Toggle navigation
Toggle navigation
This project
Loading...
Sign in
홍길동
/
onos
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
Madan Jampani
2014-11-09 01:38:46 -0800
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
8c35207b3f71722ada23c25cacacd113c87d40de
8c35207b
2 parents
348a9fea
5f36d34b
Merge branch 'master' of
ssh://gerrit.onlab.us:29418/onos-next
Show whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
760 additions
and
142 deletions
apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java
apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIpService.java
apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/BgpNeighborsListCommand.java
apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml
core/net/src/main/java/org/onlab/onos/net/topology/impl/DefaultTopologyProvider.java
core/store/dist/src/main/java/org/onlab/onos/store/cluster/messaging/impl/ClusterCommunicationManager.java
core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStore.java
core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
core/store/dist/src/main/java/org/onlab/onos/store/host/impl/GossipHostStore.java
core/store/dist/src/main/java/org/onlab/onos/store/link/impl/GossipLinkStore.java
core/store/dist/src/main/java/org/onlab/onos/store/resource/impl/DistributedLinkResourceStore.java
core/store/dist/src/main/java/org/onlab/onos/store/serializers/ClusterMessageSerializer.java → core/store/dist/src/main/java/org/onlab/onos/store/serializers/impl/ClusterMessageSerializer.java
core/store/dist/src/main/java/org/onlab/onos/store/serializers/DistributedStoreSerializers.java → core/store/dist/src/main/java/org/onlab/onos/store/serializers/impl/DistributedStoreSerializers.java
core/store/dist/src/main/java/org/onlab/onos/store/serializers/MastershipBasedTimestampSerializer.java → core/store/dist/src/main/java/org/onlab/onos/store/serializers/impl/MastershipBasedTimestampSerializer.java
core/store/dist/src/main/java/org/onlab/onos/store/serializers/MessageSubjectSerializer.java → core/store/dist/src/main/java/org/onlab/onos/store/serializers/impl/MessageSubjectSerializer.java
core/store/dist/src/main/java/org/onlab/onos/store/service/impl/ClusterMessagingProtocolClient.java
core/store/dist/src/main/java/org/onlab/onos/store/service/impl/ClusterMessagingProtocolServer.java
core/store/dist/src/test/java/org/onlab/onos/store/impl/MastershipBasedTimestampTest.java
core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleLinkResourceStore.java
utils/netty/src/main/java/org/onlab/netty/NettyMessagingService.java
web/gui/src/main/java/org/onlab/onos/gui/TopologyWebSocket.java
web/gui/src/main/webapp/index2.html
web/gui/src/main/webapp/json/intent/ev_1_ui.json
web/gui/src/main/webapp/json/intent/ev_2_onos.json
web/gui/src/main/webapp/json/intent/ev_3_ui.json
web/gui/src/main/webapp/json/intent/ev_4_onos.json
web/gui/src/main/webapp/json/intent/ev_5_onos.json
web/gui/src/main/webapp/json/intent/ev_6_onos.json
web/gui/src/main/webapp/json/intent/ev_7_ui.json
web/gui/src/main/webapp/mast2.css
web/gui/src/main/webapp/onos2.css
web/gui/src/main/webapp/onos2.js
web/gui/src/main/webapp/topo2.js
apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIp.java
View file @
8c35207
...
...
@@ -30,6 +30,7 @@ import org.onlab.onos.core.CoreService;
import
org.onlab.onos.net.host.HostService
;
import
org.onlab.onos.net.intent.IntentService
;
import
org.onlab.onos.sdnip.bgp.BgpRouteEntry
;
import
org.onlab.onos.sdnip.bgp.BgpSession
;
import
org.onlab.onos.sdnip.bgp.BgpSessionManager
;
import
org.onlab.onos.sdnip.config.SdnIpConfigReader
;
import
org.slf4j.Logger
;
...
...
@@ -97,6 +98,11 @@ public class SdnIp implements SdnIpService {
}
@Override
public
Collection
<
BgpSession
>
getBgpSessions
()
{
return
bgpSessionManager
.
getBgpSessions
();
}
@Override
public
Collection
<
BgpRouteEntry
>
getBgpRoutes
()
{
return
bgpSessionManager
.
getBgpRoutes
();
}
...
...
apps/sdnip/src/main/java/org/onlab/onos/sdnip/SdnIpService.java
View file @
8c35207
...
...
@@ -18,12 +18,20 @@ package org.onlab.onos.sdnip;
import
java.util.Collection
;
import
org.onlab.onos.sdnip.bgp.BgpRouteEntry
;
import
org.onlab.onos.sdnip.bgp.BgpSession
;
/**
* Service interface exported by SDN-IP.
*/
public
interface
SdnIpService
{
/**
* Gets the BGP sessions.
*
* @return the BGP sessions
*/
public
Collection
<
BgpSession
>
getBgpSessions
();
/**
* Gets the BGP routes.
*
* @return the BGP routes
...
...
apps/sdnip/src/main/java/org/onlab/onos/sdnip/cli/BgpNeighborsListCommand.java
0 → 100644
View file @
8c35207
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
onlab
.
onos
.
sdnip
.
cli
;
import
java.util.Collection
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.node.ArrayNode
;
import
com.fasterxml.jackson.databind.node.ObjectNode
;
import
org.apache.karaf.shell.commands.Command
;
import
org.apache.karaf.shell.commands.Option
;
import
org.onlab.onos.cli.AbstractShellCommand
;
import
org.onlab.onos.sdnip.SdnIpService
;
import
org.onlab.onos.sdnip.bgp.BgpSession
;
/**
* Command to show the BGP neighbors.
*/
@Command
(
scope
=
"onos"
,
name
=
"bgp-neighbors"
,
description
=
"Lists the BGP neighbors"
)
public
class
BgpNeighborsListCommand
extends
AbstractShellCommand
{
@Option
(
name
=
"-n"
,
aliases
=
"--neighbor"
,
description
=
"BGP neighbor to display information about"
,
required
=
false
,
multiValued
=
false
)
private
String
bgpNeighbor
;
private
static
final
String
FORMAT_NEIGHBOR_LINE1
=
"BGP neighbor is %s, remote AS %d, local AS %d"
;
private
static
final
String
FORMAT_NEIGHBOR_LINE2
=
" Remote router ID %s, IP %s, BGP version %d, Hold time %d"
;
private
static
final
String
FORMAT_NEIGHBOR_LINE3
=
" Local router ID %s, IP %s, BGP version %d, Hold time %d"
;
@Override
protected
void
execute
()
{
SdnIpService
service
=
get
(
SdnIpService
.
class
);
Collection
<
BgpSession
>
bgpSessions
=
service
.
getBgpSessions
();
if
(
bgpNeighbor
!=
null
)
{
// Print a single neighbor (if found)
BgpSession
foundBgpSession
=
null
;
for
(
BgpSession
bgpSession
:
bgpSessions
)
{
if
(
bgpSession
.
getRemoteBgpId
().
toString
().
equals
(
bgpNeighbor
))
{
foundBgpSession
=
bgpSession
;
break
;
}
}
if
(
foundBgpSession
!=
null
)
{
printNeighbor
(
foundBgpSession
);
}
else
{
print
(
"BGP neighbor %s not found"
,
bgpNeighbor
);
}
return
;
}
// Print all neighbors
printNeighbors
(
bgpSessions
);
}
/**
* Prints all BGP neighbors.
*
* @param bgpSessions the BGP sessions for the neighbors to print
*/
private
void
printNeighbors
(
Collection
<
BgpSession
>
bgpSessions
)
{
if
(
outputJson
())
{
print
(
"%s"
,
json
(
bgpSessions
));
}
else
{
for
(
BgpSession
bgpSession
:
bgpSessions
)
{
printNeighbor
(
bgpSession
);
}
}
}
/**
* Prints a BGP neighbor.
*
* @param bgpSession the BGP session for the neighbor to print
*/
private
void
printNeighbor
(
BgpSession
bgpSession
)
{
print
(
FORMAT_NEIGHBOR_LINE1
,
bgpSession
.
getRemoteBgpId
().
toString
(),
bgpSession
.
getRemoteAs
(),
bgpSession
.
getLocalAs
());
print
(
FORMAT_NEIGHBOR_LINE2
,
bgpSession
.
getRemoteBgpId
().
toString
(),
bgpSession
.
getRemoteAddress
().
toString
(),
bgpSession
.
getRemoteBgpVersion
(),
bgpSession
.
getRemoteHoldtime
());
print
(
FORMAT_NEIGHBOR_LINE3
,
bgpSession
.
getLocalBgpId
().
toString
(),
bgpSession
.
getLocalAddress
().
toString
(),
bgpSession
.
getLocalBgpVersion
(),
bgpSession
.
getLocalHoldtime
());
}
/**
* Produces a JSON array of BGP neighbors.
*
* @param bgpSessions the BGP sessions with the data
* @return JSON array with the neighbors
*/
private
JsonNode
json
(
Collection
<
BgpSession
>
bgpSessions
)
{
ObjectMapper
mapper
=
new
ObjectMapper
();
ArrayNode
result
=
mapper
.
createArrayNode
();
for
(
BgpSession
bgpSession
:
bgpSessions
)
{
result
.
add
(
json
(
mapper
,
bgpSession
));
}
return
result
;
}
/**
* Produces JSON object for a BGP neighbor.
*
* @param mapper the JSON object mapper to use
* @param bgpSession the BGP session with the data
* @return JSON object for the route
*/
private
ObjectNode
json
(
ObjectMapper
mapper
,
BgpSession
bgpSession
)
{
ObjectNode
result
=
mapper
.
createObjectNode
();
result
.
put
(
"remoteAddress"
,
bgpSession
.
getRemoteAddress
().
toString
());
result
.
put
(
"remoteBgpVersion"
,
bgpSession
.
getRemoteBgpVersion
());
result
.
put
(
"remoteAs"
,
bgpSession
.
getRemoteAs
());
result
.
put
(
"remoteHoldtime"
,
bgpSession
.
getRemoteHoldtime
());
result
.
put
(
"remoteBgpId"
,
bgpSession
.
getRemoteBgpId
().
toString
());
//
result
.
put
(
"localAddress"
,
bgpSession
.
getLocalAddress
().
toString
());
result
.
put
(
"localBgpVersion"
,
bgpSession
.
getLocalBgpVersion
());
result
.
put
(
"localAs"
,
bgpSession
.
getLocalAs
());
result
.
put
(
"localHoldtime"
,
bgpSession
.
getLocalHoldtime
());
result
.
put
(
"localBgpId"
,
bgpSession
.
getLocalBgpId
().
toString
());
return
result
;
}
}
apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml
View file @
8c35207
...
...
@@ -17,6 +17,9 @@
<command-bundle
xmlns=
"http://karaf.apache.org/xmlns/shell/v1.1.0"
>
<command>
<action
class=
"org.onlab.onos.sdnip.cli.BgpNeighborsListCommand"
/>
</command>
<command>
<action
class=
"org.onlab.onos.sdnip.cli.BgpRoutesListCommand"
/>
</command>
<command>
...
...
core/net/src/main/java/org/onlab/onos/net/topology/impl/DefaultTopologyProvider.java
View file @
8c35207
...
...
@@ -61,8 +61,8 @@ public class DefaultTopologyProvider extends AbstractProvider
// TODO: make these configurable
private
static
final
int
MAX_EVENTS
=
100
;
private
static
final
int
MAX_IDLE_MS
=
5
0
;
private
static
final
int
MAX_BATCH_MS
=
20
0
;
private
static
final
int
MAX_IDLE_MS
=
5
;
private
static
final
int
MAX_BATCH_MS
=
5
0
;
private
static
final
int
MAX_THREADS
=
8
;
// FIXME: Replace with a system-wide timer instance;
...
...
core/store/dist/src/main/java/org/onlab/onos/store/cluster/messaging/impl/ClusterCommunicationManager.java
View file @
8c35207
...
...
@@ -34,10 +34,10 @@ import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService;
import
org.onlab.onos.store.cluster.messaging.ClusterMessage
;
import
org.onlab.onos.store.cluster.messaging.ClusterMessageHandler
;
import
org.onlab.onos.store.cluster.messaging.MessageSubject
;
import
org.onlab.onos.store.serializers.ClusterMessageSerializer
;
import
org.onlab.onos.store.serializers.KryoNamespaces
;
import
org.onlab.onos.store.serializers.KryoSerializer
;
import
org.onlab.onos.store.serializers.MessageSubjectSerializer
;
import
org.onlab.onos.store.serializers.impl.ClusterMessageSerializer
;
import
org.onlab.onos.store.serializers.impl.MessageSubjectSerializer
;
import
org.onlab.util.KryoNamespace
;
import
org.onlab.netty.Endpoint
;
import
org.onlab.netty.Message
;
...
...
core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStore.java
View file @
8c35207
...
...
@@ -59,7 +59,7 @@ import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler;
import
org.onlab.onos.store.cluster.messaging.MessageSubject
;
import
org.onlab.onos.store.impl.Timestamped
;
import
org.onlab.onos.store.serializers.KryoSerializer
;
import
org.onlab.onos.store.serializers.DistributedStoreSerializers
;
import
org.onlab.onos.store.serializers.
impl.
DistributedStoreSerializers
;
import
org.onlab.packet.ChassisId
;
import
org.onlab.util.KryoNamespace
;
import
org.onlab.util.NewConcurrentHashMap
;
...
...
@@ -230,9 +230,10 @@ public class GossipDeviceStore
final
Timestamped
<
DeviceDescription
>
deltaDesc
=
new
Timestamped
<>(
deviceDescription
,
newTimestamp
);
final
DeviceEvent
event
;
final
Timestamped
<
DeviceDescription
>
mergedDesc
;
synchronized
(
getOrCreateDeviceDescriptionsMap
(
deviceId
))
{
final
Map
<
ProviderId
,
DeviceDescriptions
>
device
=
getOrCreateDeviceDescriptionsMap
(
deviceId
);
synchronized
(
device
)
{
event
=
createOrUpdateDeviceInternal
(
providerId
,
deviceId
,
deltaDesc
);
mergedDesc
=
getOrCreateDeviceDescriptionsMap
(
deviceId
)
.
get
(
providerId
).
getDeviceDesc
();
mergedDesc
=
device
.
get
(
providerId
).
getDeviceDesc
();
}
if
(
event
!=
null
)
{
log
.
info
(
"Notifying peers of a device update topology event for providerId: {} and deviceId: {}"
,
...
...
@@ -252,10 +253,10 @@ public class GossipDeviceStore
Timestamped
<
DeviceDescription
>
deltaDesc
)
{
// Collection of DeviceDescriptions for a Device
Map
<
ProviderId
,
DeviceDescriptions
>
providerDescs
Map
<
ProviderId
,
DeviceDescriptions
>
device
=
getOrCreateDeviceDescriptionsMap
(
deviceId
);
synchronized
(
providerDescs
)
{
synchronized
(
device
)
{
// locking per device
if
(
isDeviceRemoved
(
deviceId
,
deltaDesc
.
timestamp
()))
{
...
...
@@ -263,7 +264,7 @@ public class GossipDeviceStore
return
null
;
}
DeviceDescriptions
descs
=
getOrCreateProviderDeviceDescriptions
(
providerDescs
,
providerId
,
deltaDesc
);
DeviceDescriptions
descs
=
getOrCreateProviderDeviceDescriptions
(
device
,
providerId
,
deltaDesc
);
final
Device
oldDevice
=
devices
.
get
(
deviceId
);
final
Device
newDevice
;
...
...
@@ -272,7 +273,7 @@ public class GossipDeviceStore
deltaDesc
.
isNewer
(
descs
.
getDeviceDesc
()))
{
// on new device or valid update
descs
.
putDeviceDesc
(
deltaDesc
);
newDevice
=
composeDevice
(
deviceId
,
providerDescs
);
newDevice
=
composeDevice
(
deviceId
,
device
);
}
else
{
// outdated event, ignored.
return
null
;
...
...
@@ -444,9 +445,10 @@ public class GossipDeviceStore
final
List
<
DeviceEvent
>
events
;
final
Timestamped
<
List
<
PortDescription
>>
merged
;
synchronized
(
getOrCreateDeviceDescriptionsMap
(
deviceId
))
{
final
Map
<
ProviderId
,
DeviceDescriptions
>
device
=
getOrCreateDeviceDescriptionsMap
(
deviceId
);
synchronized
(
device
)
{
events
=
updatePortsInternal
(
providerId
,
deviceId
,
timestampedInput
);
final
DeviceDescriptions
descs
=
getOrCreateDeviceDescriptionsMap
(
deviceId
)
.
get
(
providerId
);
final
DeviceDescriptions
descs
=
device
.
get
(
providerId
);
List
<
PortDescription
>
mergedList
=
FluentIterable
.
from
(
portDescriptions
)
.
transform
(
new
Function
<
PortDescription
,
PortDescription
>()
{
...
...
@@ -632,9 +634,10 @@ public class GossipDeviceStore
=
new
Timestamped
<>(
portDescription
,
newTimestamp
);
final
DeviceEvent
event
;
final
Timestamped
<
PortDescription
>
mergedDesc
;
synchronized
(
getOrCreateDeviceDescriptionsMap
(
deviceId
))
{
final
Map
<
ProviderId
,
DeviceDescriptions
>
device
=
getOrCreateDeviceDescriptionsMap
(
deviceId
);
synchronized
(
device
)
{
event
=
updatePortStatusInternal
(
providerId
,
deviceId
,
deltaDesc
);
mergedDesc
=
getOrCreateDeviceDescriptionsMap
(
deviceId
)
.
get
(
providerId
)
mergedDesc
=
device
.
get
(
providerId
)
.
getPortDesc
(
portDescription
.
portNumber
());
}
if
(
event
!=
null
)
{
...
...
core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
View file @
8c35207
...
...
@@ -75,9 +75,9 @@ import org.onlab.onos.store.flow.ReplicaInfoService;
import
org.onlab.onos.store.hz.AbstractHazelcastStore
;
import
org.onlab.onos.store.hz.SMap
;
import
org.onlab.onos.store.serializers.DecodeTo
;
import
org.onlab.onos.store.serializers.DistributedStoreSerializers
;
import
org.onlab.onos.store.serializers.KryoSerializer
;
import
org.onlab.onos.store.serializers.StoreSerializer
;
import
org.onlab.onos.store.serializers.impl.DistributedStoreSerializers
;
import
org.onlab.util.KryoNamespace
;
import
org.slf4j.Logger
;
...
...
core/store/dist/src/main/java/org/onlab/onos/store/host/impl/GossipHostStore.java
View file @
8c35207
...
...
@@ -67,8 +67,8 @@ import org.onlab.onos.store.cluster.messaging.ClusterMessage;
import
org.onlab.onos.store.cluster.messaging.ClusterMessageHandler
;
import
org.onlab.onos.store.cluster.messaging.MessageSubject
;
import
org.onlab.onos.store.impl.Timestamped
;
import
org.onlab.onos.store.serializers.DistributedStoreSerializers
;
import
org.onlab.onos.store.serializers.KryoSerializer
;
import
org.onlab.onos.store.serializers.impl.DistributedStoreSerializers
;
import
org.onlab.packet.IpAddress
;
import
org.onlab.packet.MacAddress
;
import
org.onlab.packet.VlanId
;
...
...
core/store/dist/src/main/java/org/onlab/onos/store/link/impl/GossipLinkStore.java
View file @
8c35207
...
...
@@ -55,8 +55,8 @@ import org.onlab.onos.store.cluster.messaging.ClusterMessage;
import
org.onlab.onos.store.cluster.messaging.ClusterMessageHandler
;
import
org.onlab.onos.store.cluster.messaging.MessageSubject
;
import
org.onlab.onos.store.impl.Timestamped
;
import
org.onlab.onos.store.serializers.DistributedStoreSerializers
;
import
org.onlab.onos.store.serializers.KryoSerializer
;
import
org.onlab.onos.store.serializers.impl.DistributedStoreSerializers
;
import
org.onlab.util.KryoNamespace
;
import
org.slf4j.Logger
;
...
...
core/store/dist/src/main/java/org/onlab/onos/store/resource/impl/DistributedLinkResourceStore.java
View file @
8c35207
...
...
@@ -73,7 +73,7 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
* @param link the target link
* @return free resources
*/
private
Set
<
ResourceAllocation
>
readOriginalFreeResources
(
Link
link
)
{
private
synchronized
Set
<
ResourceAllocation
>
readOriginalFreeResources
(
Link
link
)
{
// TODO read capacity and lambda resources from topology
Set
<
ResourceAllocation
>
allocations
=
new
HashSet
<>();
for
(
int
i
=
1
;
i
<=
100
;
i
++)
{
...
...
@@ -92,7 +92,7 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
* {@link org.onlab.onos.net.resource.BandwidthResourceAllocation} object with 0 bandwidth
*
*/
private
BandwidthResourceAllocation
getBandwidth
(
Set
<
ResourceAllocation
>
freeRes
)
{
private
synchronized
BandwidthResourceAllocation
getBandwidth
(
Set
<
ResourceAllocation
>
freeRes
)
{
for
(
ResourceAllocation
res
:
freeRes
)
{
if
(
res
.
type
()
==
ResourceType
.
BANDWIDTH
)
{
return
(
BandwidthResourceAllocation
)
res
;
...
...
@@ -107,7 +107,7 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
* @param link the target link
* @param allocations the resources to be subtracted
*/
private
void
subtractFreeResources
(
Link
link
,
LinkResourceAllocations
allocations
)
{
private
synchronized
void
subtractFreeResources
(
Link
link
,
LinkResourceAllocations
allocations
)
{
// TODO Use lock or version for updating freeResources.
checkNotNull
(
link
);
Set
<
ResourceAllocation
>
freeRes
=
new
HashSet
<>(
getFreeResources
(
link
));
...
...
@@ -141,7 +141,7 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
* @param link the target link
* @param allocations the resources to be added
*/
private
void
addFreeResources
(
Link
link
,
LinkResourceAllocations
allocations
)
{
private
synchronized
void
addFreeResources
(
Link
link
,
LinkResourceAllocations
allocations
)
{
// TODO Use lock or version for updating freeResources.
Set
<
ResourceAllocation
>
freeRes
=
new
HashSet
<>(
getFreeResources
(
link
));
Set
<
ResourceAllocation
>
addRes
=
allocations
.
getResourceAllocation
(
link
);
...
...
@@ -167,7 +167,7 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
}
@Override
public
Set
<
ResourceAllocation
>
getFreeResources
(
Link
link
)
{
public
synchronized
Set
<
ResourceAllocation
>
getFreeResources
(
Link
link
)
{
checkNotNull
(
link
);
Set
<
ResourceAllocation
>
freeRes
=
freeResources
.
get
(
link
);
if
(
freeRes
==
null
)
{
...
...
@@ -178,7 +178,7 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
}
@Override
public
void
allocateResources
(
LinkResourceAllocations
allocations
)
{
public
synchronized
void
allocateResources
(
LinkResourceAllocations
allocations
)
{
checkNotNull
(
allocations
);
linkResourceAllocationsMap
.
put
(
allocations
.
intendId
(),
allocations
);
for
(
Link
link
:
allocations
.
links
())
{
...
...
@@ -193,7 +193,7 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
}
@Override
public
void
releaseResources
(
LinkResourceAllocations
allocations
)
{
public
synchronized
void
releaseResources
(
LinkResourceAllocations
allocations
)
{
checkNotNull
(
allocations
);
linkResourceAllocationsMap
.
remove
(
allocations
.
intendId
());
for
(
Link
link
:
allocations
.
links
())
{
...
...
@@ -209,13 +209,13 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
}
@Override
public
LinkResourceAllocations
getAllocations
(
IntentId
intentId
)
{
public
synchronized
LinkResourceAllocations
getAllocations
(
IntentId
intentId
)
{
checkNotNull
(
intentId
);
return
linkResourceAllocationsMap
.
get
(
intentId
);
}
@Override
public
Iterable
<
LinkResourceAllocations
>
getAllocations
(
Link
link
)
{
public
synchronized
Iterable
<
LinkResourceAllocations
>
getAllocations
(
Link
link
)
{
checkNotNull
(
link
);
Set
<
LinkResourceAllocations
>
result
=
allocatedResources
.
get
(
link
);
if
(
result
==
null
)
{
...
...
@@ -225,7 +225,7 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
}
@Override
public
Iterable
<
LinkResourceAllocations
>
getAllocations
()
{
public
synchronized
Iterable
<
LinkResourceAllocations
>
getAllocations
()
{
return
Collections
.
unmodifiableCollection
(
linkResourceAllocationsMap
.
values
());
}
...
...
core/store/dist/src/main/java/org/onlab/onos/store/serializers/ClusterMessageSerializer.java
→
core/store/dist/src/main/java/org/onlab/onos/store/serializers/
impl/
ClusterMessageSerializer.java
View file @
8c35207
...
...
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
onlab
.
onos
.
store
.
serializers
;
package
org
.
onlab
.
onos
.
store
.
serializers
.
impl
;
import
org.onlab.onos.cluster.NodeId
;
import
org.onlab.onos.store.cluster.messaging.ClusterMessage
;
...
...
core/store/dist/src/main/java/org/onlab/onos/store/serializers/DistributedStoreSerializers.java
→
core/store/dist/src/main/java/org/onlab/onos/store/serializers/
impl/
DistributedStoreSerializers.java
View file @
8c35207
...
...
@@ -13,11 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
onlab
.
onos
.
store
.
serializers
;
package
org
.
onlab
.
onos
.
store
.
serializers
.
impl
;
import
org.onlab.onos.store.impl.MastershipBasedTimestamp
;
import
org.onlab.onos.store.impl.Timestamped
;
import
org.onlab.onos.store.impl.WallClockTimestamp
;
import
org.onlab.onos.store.serializers.KryoNamespaces
;
import
org.onlab.util.KryoNamespace
;
public
final
class
DistributedStoreSerializers
{
...
...
core/store/dist/src/main/java/org/onlab/onos/store/serializers/MastershipBasedTimestampSerializer.java
→
core/store/dist/src/main/java/org/onlab/onos/store/serializers/
impl/
MastershipBasedTimestampSerializer.java
View file @
8c35207
...
...
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
onlab
.
onos
.
store
.
serializers
;
package
org
.
onlab
.
onos
.
store
.
serializers
.
impl
;
import
org.onlab.onos.store.impl.MastershipBasedTimestamp
;
...
...
core/store/dist/src/main/java/org/onlab/onos/store/serializers/MessageSubjectSerializer.java
→
core/store/dist/src/main/java/org/onlab/onos/store/serializers/
impl/
MessageSubjectSerializer.java
View file @
8c35207
...
...
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
onlab
.
onos
.
store
.
serializers
;
package
org
.
onlab
.
onos
.
store
.
serializers
.
impl
;
import
org.onlab.onos.store.cluster.messaging.MessageSubject
;
...
...
core/store/dist/src/main/java/org/onlab/onos/store/service/impl/ClusterMessagingProtocolClient.java
View file @
8c35207
...
...
@@ -85,7 +85,7 @@ public class ClusterMessagingProtocolClient implements ProtocolClient {
return
CompletableFuture
.
completedFuture
(
null
);
}
p
ublic
<
I
>
MessageSubject
messageType
(
I
input
)
{
p
rivate
<
I
>
MessageSubject
messageType
(
I
input
)
{
Class
<?>
clazz
=
input
.
getClass
();
if
(
clazz
.
equals
(
PollRequest
.
class
))
{
return
ClusterMessagingProtocol
.
COPYCAT_POLL
;
...
...
@@ -117,7 +117,7 @@ public class ClusterMessagingProtocolClient implements ProtocolClient {
this
.
request
=
request
;
this
.
message
=
new
ClusterMessage
(
null
,
null
,
// FIXME fill in proper sender
messageType
(
request
),
ClusterMessagingProtocol
.
SERIALIZER
.
encode
(
request
));
this
.
future
=
future
;
...
...
@@ -132,19 +132,20 @@ public class ClusterMessagingProtocolClient implements ProtocolClient {
future
.
complete
(
ClusterMessagingProtocol
.
SERIALIZER
.
decode
(
response
));
}
catch
(
IOException
|
InterruptedException
|
ExecutionException
|
TimeoutException
e
)
{
if
(
message
.
subject
().
equals
(
ClusterMessagingProtocol
.
COPYCAT_SYNC
)
||
message
.
subject
().
equals
(
ClusterMessagingProtocol
.
COPYCAT_PING
))
{
log
.
warn
(
"{} Request to {} failed. Will retry in {} ms"
,
message
.
subject
(),
remoteNode
,
RETRY_INTERVAL_MILLIS
);
THREAD_POOL
.
schedule
(
this
,
RETRY_INTERVAL_MILLIS
,
TimeUnit
.
MILLISECONDS
);
}
else
{
//
if (message.subject().equals(ClusterMessagingProtocol.COPYCAT_SYNC) ||
//
message.subject().equals(ClusterMessagingProtocol.COPYCAT_PING)) {
//
log.warn("{} Request to {} failed. Will retry in {} ms",
//
message.subject(), remoteNode, RETRY_INTERVAL_MILLIS);
//
THREAD_POOL.schedule(
//
this,
//
RETRY_INTERVAL_MILLIS,
//
TimeUnit.MILLISECONDS);
//
} else {
log
.
warn
(
"RPCTask for {} failed."
,
request
,
e
);
future
.
completeExceptionally
(
e
);
}
//
}
}
catch
(
Exception
e
)
{
log
.
warn
(
"RPCTask for {} terribly failed."
,
request
,
e
);
future
.
completeExceptionally
(
e
);
}
}
...
...
core/store/dist/src/main/java/org/onlab/onos/store/service/impl/ClusterMessagingProtocolServer.java
View file @
8c35207
...
...
@@ -67,14 +67,36 @@ public class ClusterMessagingProtocolServer implements ProtocolServer {
@Override
public
void
handle
(
ClusterMessage
message
)
{
T
request
=
ClusterMessagingProtocol
.
SERIALIZER
.
decode
(
message
.
payload
());
if
(
handler
==
null
)
{
// there is a slight window of time during state transition,
// where handler becomes null
for
(
int
i
=
0
;
i
<
10
;
++
i
)
{
if
(
handler
!=
null
)
{
break
;
}
try
{
Thread
.
sleep
(
1
);
}
catch
(
InterruptedException
e
)
{
log
.
trace
(
"Exception"
,
e
);
}
}
if
(
handler
==
null
)
{
log
.
error
(
"There was no handler for registered!"
);
return
;
}
}
if
(
request
.
getClass
().
equals
(
PingRequest
.
class
))
{
handler
.
ping
((
PingRequest
)
request
).
whenComplete
(
new
PostExecutionTask
<
PingResponse
>(
message
));
handler
.
ping
((
PingRequest
)
request
)
.
whenComplete
(
new
PostExecutionTask
<
PingResponse
>(
message
));
}
else
if
(
request
.
getClass
().
equals
(
PollRequest
.
class
))
{
handler
.
poll
((
PollRequest
)
request
).
whenComplete
(
new
PostExecutionTask
<
PollResponse
>(
message
));
handler
.
poll
((
PollRequest
)
request
)
.
whenComplete
(
new
PostExecutionTask
<
PollResponse
>(
message
));
}
else
if
(
request
.
getClass
().
equals
(
SyncRequest
.
class
))
{
handler
.
sync
((
SyncRequest
)
request
).
whenComplete
(
new
PostExecutionTask
<
SyncResponse
>(
message
));
handler
.
sync
((
SyncRequest
)
request
)
.
whenComplete
(
new
PostExecutionTask
<
SyncResponse
>(
message
));
}
else
if
(
request
.
getClass
().
equals
(
SubmitRequest
.
class
))
{
handler
.
submit
((
SubmitRequest
)
request
).
whenComplete
(
new
PostExecutionTask
<
SubmitResponse
>(
message
));
handler
.
submit
((
SubmitRequest
)
request
)
.
whenComplete
(
new
PostExecutionTask
<
SubmitResponse
>(
message
));
}
else
{
throw
new
IllegalStateException
(
"Unknown request type: "
+
request
.
getClass
().
getName
());
}
...
...
@@ -94,6 +116,7 @@ public class ClusterMessagingProtocolServer implements ProtocolServer {
log
.
error
(
"Processing for "
+
message
.
subject
()
+
" failed."
,
t
);
}
else
{
try
{
log
.
trace
(
"responding to {}"
,
message
.
subject
());
message
.
respond
(
ClusterMessagingProtocol
.
SERIALIZER
.
encode
(
response
));
}
catch
(
Exception
e
)
{
log
.
error
(
"Failed to respond to "
+
response
.
getClass
().
getName
(),
e
);
...
...
core/store/dist/src/test/java/org/onlab/onos/store/impl/MastershipBasedTimestampTest.java
View file @
8c35207
...
...
@@ -21,7 +21,7 @@ import java.nio.ByteBuffer;
import
org.junit.Test
;
import
org.onlab.onos.store.Timestamp
;
import
org.onlab.onos.store.serializers.MastershipBasedTimestampSerializer
;
import
org.onlab.onos.store.serializers.
impl.
MastershipBasedTimestampSerializer
;
import
org.onlab.util.KryoNamespace
;
import
com.google.common.testing.EqualsTester
;
...
...
core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleLinkResourceStore.java
View file @
8c35207
...
...
@@ -73,7 +73,7 @@ public class SimpleLinkResourceStore implements LinkResourceStore {
* @param link the target link
* @return free resources
*/
private
Set
<
ResourceAllocation
>
readOriginalFreeResources
(
Link
link
)
{
private
synchronized
Set
<
ResourceAllocation
>
readOriginalFreeResources
(
Link
link
)
{
// TODO read capacity and lambda resources from topology
Set
<
ResourceAllocation
>
allocations
=
new
HashSet
<>();
for
(
int
i
=
1
;
i
<=
100
;
i
++)
{
...
...
@@ -92,7 +92,7 @@ public class SimpleLinkResourceStore implements LinkResourceStore {
* {@link BandwidthResourceAllocation} object with 0 bandwidth
*
*/
private
BandwidthResourceAllocation
getBandwidth
(
Set
<
ResourceAllocation
>
freeRes
)
{
private
synchronized
BandwidthResourceAllocation
getBandwidth
(
Set
<
ResourceAllocation
>
freeRes
)
{
for
(
ResourceAllocation
res
:
freeRes
)
{
if
(
res
.
type
()
==
ResourceType
.
BANDWIDTH
)
{
return
(
BandwidthResourceAllocation
)
res
;
...
...
@@ -107,7 +107,7 @@ public class SimpleLinkResourceStore implements LinkResourceStore {
* @param link the target link
* @param allocations the resources to be subtracted
*/
private
void
subtractFreeResources
(
Link
link
,
LinkResourceAllocations
allocations
)
{
private
synchronized
void
subtractFreeResources
(
Link
link
,
LinkResourceAllocations
allocations
)
{
// TODO Use lock or version for updating freeResources.
checkNotNull
(
link
);
Set
<
ResourceAllocation
>
freeRes
=
new
HashSet
<>(
getFreeResources
(
link
));
...
...
@@ -141,7 +141,7 @@ public class SimpleLinkResourceStore implements LinkResourceStore {
* @param link the target link
* @param allocations the resources to be added
*/
private
void
addFreeResources
(
Link
link
,
LinkResourceAllocations
allocations
)
{
private
synchronized
void
addFreeResources
(
Link
link
,
LinkResourceAllocations
allocations
)
{
// TODO Use lock or version for updating freeResources.
Set
<
ResourceAllocation
>
freeRes
=
new
HashSet
<>(
getFreeResources
(
link
));
Set
<
ResourceAllocation
>
addRes
=
allocations
.
getResourceAllocation
(
link
);
...
...
@@ -167,7 +167,7 @@ public class SimpleLinkResourceStore implements LinkResourceStore {
}
@Override
public
Set
<
ResourceAllocation
>
getFreeResources
(
Link
link
)
{
public
synchronized
Set
<
ResourceAllocation
>
getFreeResources
(
Link
link
)
{
checkNotNull
(
link
);
Set
<
ResourceAllocation
>
freeRes
=
freeResources
.
get
(
link
);
if
(
freeRes
==
null
)
{
...
...
@@ -178,7 +178,7 @@ public class SimpleLinkResourceStore implements LinkResourceStore {
}
@Override
public
void
allocateResources
(
LinkResourceAllocations
allocations
)
{
public
synchronized
void
allocateResources
(
LinkResourceAllocations
allocations
)
{
checkNotNull
(
allocations
);
linkResourceAllocationsMap
.
put
(
allocations
.
intendId
(),
allocations
);
for
(
Link
link
:
allocations
.
links
())
{
...
...
@@ -193,7 +193,7 @@ public class SimpleLinkResourceStore implements LinkResourceStore {
}
@Override
public
void
releaseResources
(
LinkResourceAllocations
allocations
)
{
public
synchronized
void
releaseResources
(
LinkResourceAllocations
allocations
)
{
checkNotNull
(
allocations
);
linkResourceAllocationsMap
.
remove
(
allocations
.
intendId
());
for
(
Link
link
:
allocations
.
links
())
{
...
...
@@ -209,13 +209,13 @@ public class SimpleLinkResourceStore implements LinkResourceStore {
}
@Override
public
LinkResourceAllocations
getAllocations
(
IntentId
intentId
)
{
public
synchronized
LinkResourceAllocations
getAllocations
(
IntentId
intentId
)
{
checkNotNull
(
intentId
);
return
linkResourceAllocationsMap
.
get
(
intentId
);
}
@Override
public
Iterable
<
LinkResourceAllocations
>
getAllocations
(
Link
link
)
{
public
synchronized
Iterable
<
LinkResourceAllocations
>
getAllocations
(
Link
link
)
{
checkNotNull
(
link
);
Set
<
LinkResourceAllocations
>
result
=
allocatedResources
.
get
(
link
);
if
(
result
==
null
)
{
...
...
@@ -225,7 +225,7 @@ public class SimpleLinkResourceStore implements LinkResourceStore {
}
@Override
public
Iterable
<
LinkResourceAllocations
>
getAllocations
()
{
public
synchronized
Iterable
<
LinkResourceAllocations
>
getAllocations
()
{
return
Collections
.
unmodifiableCollection
(
linkResourceAllocationsMap
.
values
());
}
...
...
utils/netty/src/main/java/org/onlab/netty/NettyMessagingService.java
View file @
8c35207
...
...
@@ -316,7 +316,11 @@ public class NettyMessagingService implements MessagingService {
return
;
}
MessageHandler
handler
=
NettyMessagingService
.
this
.
getMessageHandler
(
type
);
if
(
handler
!=
null
)
{
handler
.
handle
(
message
);
}
else
{
log
.
debug
(
"No handler registered for {}"
,
type
);
}
}
@Override
...
...
web/gui/src/main/java/org/onlab/onos/gui/TopologyWebSocket.java
View file @
8c35207
...
...
@@ -15,8 +15,20 @@
*/
package
org
.
onlab
.
onos
.
gui
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.node.ArrayNode
;
import
com.fasterxml.jackson.databind.node.ObjectNode
;
import
org.eclipse.jetty.websocket.WebSocket
;
import
org.onlab.onos.event.Event
;
import
org.onlab.onos.net.Annotations
;
import
org.onlab.onos.net.Device
;
import
org.onlab.onos.net.DeviceId
;
import
org.onlab.onos.net.Link
;
import
org.onlab.onos.net.Path
;
import
org.onlab.onos.net.device.DeviceEvent
;
import
org.onlab.onos.net.device.DeviceService
;
import
org.onlab.onos.net.link.LinkEvent
;
import
org.onlab.onos.net.topology.Topology
;
import
org.onlab.onos.net.topology.TopologyEdge
;
import
org.onlab.onos.net.topology.TopologyEvent
;
...
...
@@ -27,6 +39,15 @@ import org.onlab.onos.net.topology.TopologyVertex;
import
org.onlab.osgi.ServiceDirectory
;
import
java.io.IOException
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Set
;
import
static
org
.
onlab
.
onos
.
net
.
DeviceId
.
deviceId
;
import
static
org
.
onlab
.
onos
.
net
.
device
.
DeviceEvent
.
Type
.
DEVICE_ADDED
;
import
static
org
.
onlab
.
onos
.
net
.
device
.
DeviceEvent
.
Type
.
DEVICE_REMOVED
;
import
static
org
.
onlab
.
onos
.
net
.
link
.
LinkEvent
.
Type
.
LINK_ADDED
;
import
static
org
.
onlab
.
onos
.
net
.
link
.
LinkEvent
.
Type
.
LINK_REMOVED
;
/**
* Web socket capable of interacting with the GUI topology view.
...
...
@@ -37,8 +58,16 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe
private
final
TopologyService
topologyService
;
private
final
DeviceService
deviceService
;
private
final
ObjectMapper
mapper
=
new
ObjectMapper
();
private
Connection
connection
;
// TODO: extract into an external & durable state; good enough for now and demo
private
static
Map
<
String
,
ObjectNode
>
metaUi
=
new
HashMap
<>();
private
static
final
String
COMPACT
=
"%s/%s-%s/%s"
;
/**
* Creates a new web-socket for serving data to GUI topology view.
*
...
...
@@ -58,22 +87,19 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe
if
(
topologyService
!=
null
&&
deviceService
!=
null
)
{
topologyService
.
addListener
(
this
);
sendMessage
(
"Yo!!!"
);
Topology
topology
=
topologyService
.
currentTopology
();
TopologyGraph
graph
=
topologyService
.
getGraph
(
topology
);
for
(
TopologyVertex
vertex
:
graph
.
getVertexes
())
{
sendMessage
(
deviceService
.
getDevice
(
vertex
.
deviceId
()).
toString
());
sendMessage
(
message
(
new
DeviceEvent
(
DEVICE_ADDED
,
deviceService
.
getDevice
(
vertex
.
deviceId
()))));
}
for
(
TopologyEdge
edge
:
graph
.
getEdges
())
{
sendMessage
(
edge
.
link
().
toString
(
));
sendMessage
(
message
(
new
LinkEvent
(
LINK_ADDED
,
edge
.
link
())
));
}
sendMessage
(
"That's what we're starting with..."
);
}
else
{
sendMessage
(
"No topology service!!!"
);
sendMessage
(
message
(
"error"
,
"No topology service!!!"
)
);
}
}
...
...
@@ -87,10 +113,57 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe
@Override
public
void
onMessage
(
String
data
)
{
try
{
ObjectNode
event
=
(
ObjectNode
)
mapper
.
reader
().
readTree
(
data
);
String
type
=
event
.
path
(
"event"
).
asText
(
"unknown"
);
ObjectNode
payload
=
(
ObjectNode
)
event
.
path
(
"payload"
);
switch
(
type
)
{
case
"updateMeta"
:
metaUi
.
put
(
payload
.
path
(
"id"
).
asText
(),
payload
);
break
;
case
"requestPath"
:
findPath
(
deviceId
(
payload
.
path
(
"one"
).
asText
()),
deviceId
(
payload
.
path
(
"two"
).
asText
()));
default
:
break
;
}
}
catch
(
IOException
e
)
{
System
.
out
.
println
(
"Received: "
+
data
);
}
}
private
void
findPath
(
DeviceId
one
,
DeviceId
two
)
{
Set
<
Path
>
paths
=
topologyService
.
getPaths
(
topologyService
.
currentTopology
(),
one
,
two
);
if
(!
paths
.
isEmpty
())
{
ObjectNode
payload
=
mapper
.
createObjectNode
();
ArrayNode
links
=
mapper
.
createArrayNode
();
Path
path
=
paths
.
iterator
().
next
();
for
(
Link
link
:
path
.
links
())
{
links
.
add
(
compactLinkString
(
link
));
}
payload
.
set
(
"links"
,
links
);
sendMessage
(
envelope
(
"showPath"
,
payload
));
}
// TODO: when no path, send a message to the client
}
/**
* Returns a compact string representing the given link.
*
* @param link infrastructure link
* @return formatted link string
*/
public
static
String
compactLinkString
(
Link
link
)
{
return
String
.
format
(
COMPACT
,
link
.
src
().
deviceId
(),
link
.
src
().
port
(),
link
.
dst
().
deviceId
(),
link
.
dst
().
port
());
}
public
void
sendMessage
(
String
data
)
{
private
void
sendMessage
(
String
data
)
{
try
{
connection
.
sendMessage
(
data
);
}
catch
(
IOException
e
)
{
...
...
@@ -98,9 +171,84 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe
}
}
// Produces a link event message to the client.
private
String
message
(
DeviceEvent
event
)
{
Device
device
=
event
.
subject
();
ObjectNode
payload
=
mapper
.
createObjectNode
()
.
put
(
"id"
,
device
.
id
().
toString
())
.
put
(
"type"
,
device
.
type
().
toString
().
toLowerCase
())
.
put
(
"online"
,
deviceService
.
isAvailable
(
device
.
id
()));
// Generate labels: id, chassis id, no-label, optional-name
ArrayNode
labels
=
mapper
.
createArrayNode
();
labels
.
add
(
device
.
id
().
toString
());
labels
.
add
(
device
.
chassisId
().
toString
());
labels
.
add
(
" "
);
// compact no-label view
labels
.
add
(
device
.
annotations
().
value
(
"name"
));
// Add labels, props and stuff the payload into envelope.
payload
.
set
(
"labels"
,
labels
);
payload
.
set
(
"props"
,
props
(
device
.
annotations
()));
ObjectNode
meta
=
metaUi
.
get
(
device
.
id
().
toString
());
if
(
meta
!=
null
)
{
payload
.
set
(
"metaUi"
,
meta
);
}
String
type
=
(
event
.
type
()
==
DEVICE_ADDED
)
?
"addDevice"
:
((
event
.
type
()
==
DEVICE_REMOVED
)
?
"removeDevice"
:
"updateDevice"
);
return
envelope
(
type
,
payload
);
}
// Produces a link event message to the client.
private
String
message
(
LinkEvent
event
)
{
Link
link
=
event
.
subject
();
ObjectNode
payload
=
mapper
.
createObjectNode
()
.
put
(
"type"
,
link
.
type
().
toString
().
toLowerCase
())
.
put
(
"linkWidth"
,
2
)
.
put
(
"src"
,
link
.
src
().
deviceId
().
toString
())
.
put
(
"srcPort"
,
link
.
src
().
port
().
toString
())
.
put
(
"dst"
,
link
.
dst
().
deviceId
().
toString
())
.
put
(
"dstPort"
,
link
.
dst
().
port
().
toString
());
String
type
=
(
event
.
type
()
==
LINK_ADDED
)
?
"addLink"
:
((
event
.
type
()
==
LINK_REMOVED
)
?
"removeLink"
:
"removeLink"
);
return
envelope
(
type
,
payload
);
}
// Produces JSON structure from annotations.
private
JsonNode
props
(
Annotations
annotations
)
{
ObjectNode
props
=
mapper
.
createObjectNode
();
for
(
String
key
:
annotations
.
keys
())
{
props
.
put
(
key
,
annotations
.
value
(
key
));
}
return
props
;
}
// Produces a log message event bound to the client.
private
String
message
(
String
severity
,
String
message
)
{
return
envelope
(
"message"
,
mapper
.
createObjectNode
()
.
put
(
"severity"
,
severity
)
.
put
(
"message"
,
message
));
}
// Puts the payload into an envelope and returns it.
private
String
envelope
(
String
type
,
ObjectNode
payload
)
{
ObjectNode
event
=
mapper
.
createObjectNode
();
event
.
put
(
"event"
,
type
);
event
.
set
(
"payload"
,
payload
);
return
event
.
toString
();
}
@Override
public
void
event
(
TopologyEvent
event
)
{
sendMessage
(
event
.
toString
());
for
(
Event
reason
:
event
.
reasons
())
{
if
(
reason
instanceof
DeviceEvent
)
{
sendMessage
(
message
((
DeviceEvent
)
reason
));
}
else
if
(
reason
instanceof
LinkEvent
)
{
sendMessage
(
message
((
LinkEvent
)
reason
));
}
}
}
}
...
...
web/gui/src/main/webapp/index2.html
View file @
8c35207
...
...
@@ -72,9 +72,9 @@
<!-- Initialize the UI...-->
<script
type=
"text/javascript"
>
var
ONOS
=
$
.
onos
({
comment
:
"configuration options"
,
comment
:
'configuration options'
,
theme
:
'light'
,
startVid
:
'topo'
,
// startVid: 'sampleKeys',
trace
:
false
});
</script>
...
...
web/gui/src/main/webapp/json/intent/ev_1_ui.json
0 → 100644
View file @
8c35207
{
"event"
:
"addHostIntent"
,
"sid"
:
1
,
"payload"
:
{
"one"
:
"hostOne"
,
"two"
:
"hostTwo"
}
}
web/gui/src/main/webapp/json/intent/ev_2_onos.json
0 → 100644
View file @
8c35207
{
"event"
:
"showPath"
,
"sid"
:
1
,
"payload"
:
{
"intentId"
:
"0x1234"
,
"path"
:
{
"links"
:
[
"1-2"
,
"2-3"
],
"traffic"
:
false
}
}
}
web/gui/src/main/webapp/json/intent/ev_3_ui.json
0 → 100644
View file @
8c35207
{
"event"
:
"monitorIntent"
,
"sid"
:
2
,
"payload"
:
{
"intentId"
:
"0x1234"
}
}
web/gui/src/main/webapp/json/intent/ev_4_onos.json
0 → 100644
View file @
8c35207
{
"event"
:
"showPath"
,
"sid"
:
2
,
"payload"
:
{
"intentId"
:
"0x1234"
,
"path"
:
{
"links"
:
[
"1-2"
,
"2-3"
],
"traffic"
:
true
,
"srcLabel"
:
"567 Mb"
,
"dstLabel"
:
"6 Mb"
}
}
}
web/gui/src/main/webapp/json/intent/ev_5_onos.json
0 → 100644
View file @
8c35207
{
"event"
:
"showPath"
,
"sid"
:
2
,
"payload"
:
{
"intentId"
:
"0x1234"
,
"path"
:
{
"links"
:
[
"1-2"
,
"2-3"
],
"traffic"
:
true
,
"srcLabel"
:
"967 Mb"
,
"dstLabel"
:
"65 Mb"
}
}
}
web/gui/src/main/webapp/json/intent/ev_6_onos.json
0 → 100644
View file @
8c35207
{
"event"
:
"showPath"
,
"sid"
:
2
,
"payload"
:
{
"intentId"
:
"0x1234"
,
"path"
:
{
"links"
:
[
"1-2"
,
"2-3"
],
"traffic"
:
false
}
}
}
web/gui/src/main/webapp/json/intent/ev_7_ui.json
0 → 100644
View file @
8c35207
{
"event"
:
"cancelMonitorIntent"
,
"sid"
:
3
,
"payload"
:
{
"intentId"
:
"0x1234"
}
}
web/gui/src/main/webapp/mast2.css
View file @
8c35207
...
...
@@ -23,8 +23,15 @@
#mast
{
height
:
36px
;
padding
:
4px
;
background-color
:
#bbb
;
vertical-align
:
baseline
;
}
.light
#mast
{
background-color
:
#bbb
;
box-shadow
:
0px
2px
8px
#777
;
}
.dark
#mast
{
background-color
:
#444
;
box-shadow
:
0px
2px
8px
#777
;
}
...
...
@@ -35,12 +42,18 @@
}
#mast
span
.title
{
color
:
#369
;
font-size
:
14pt
;
font-style
:
italic
;
vertical-align
:
12px
;
}
.light
#mast
span
.title
{
color
:
#369
;
}
.dark
#mast
span
.title
{
color
:
#78a
;
}
#mast
span
.right
{
padding-top
:
8px
;
padding-right
:
16px
;
...
...
@@ -50,16 +63,31 @@
#mast
span
.radio
{
font-size
:
10pt
;
margin
:
4px
2px
;
border
:
1px
dotted
#222
;
padding
:
1px
6px
;
color
:
#eee
;
cursor
:
pointer
;
}
.light
#mast
span
.radio
{
border
:
1px
dotted
#222
;
color
:
#eee
;
}
.dark
#mast
span
.radio
{
border
:
1px
dotted
#bbb
;
color
:
#888
;
}
#mast
span
.radio.active
{
padding
:
1px
6px
;
font-weight
:
bold
;
}
.light
#mast
span
.radio.active
{
background-color
:
#bbb
;
border
:
1px
solid
#eee
;
padding
:
1px
6px
;
color
:
#666
;
font-weight
:
bold
;
}
.dark
#mast
span
.radio.active
{
background-color
:
#222
;
border
:
1px
solid
#eee
;
color
:
#aaf
;
}
...
...
web/gui/src/main/webapp/onos2.css
View file @
8c35207
...
...
@@ -32,7 +32,7 @@ div.onosView.currentView {
display
:
block
;
}
div
#alerts
{
#alerts
{
display
:
none
;
position
:
absolute
;
z-index
:
2000
;
...
...
@@ -45,21 +45,28 @@ div#alerts {
box-shadow
:
4px
6px
12px
#777
;
}
div
#alerts
pre
{
#alerts
pre
{
margin
:
0.2em
6px
;
}
div
#alerts
span
.close
{
#alerts
span
.close
{
color
:
#6af
;
float
:
right
;
right
:
2px
;
cursor
:
pointer
;
}
div
#alerts
span
.close
:hover
{
#alerts
span
.close
:hover
{
color
:
#fff
;
}
#alerts
p
.footnote
{
text-align
:
right
;
font-size
:
8pt
;
margin
:
8px
0
0
0
;
color
:
#66d
;
}
/*
* ==============================================================
* END OF NEW ONOS.JS file
...
...
web/gui/src/main/webapp/onos2.js
View file @
8c35207
...
...
@@ -37,23 +37,34 @@
var
defaultOptions
=
{
trace
:
false
,
theme
:
'light'
,
startVid
:
defaultVid
};
// compute runtime settings
var
settings
=
$
.
extend
({},
defaultOptions
,
options
);
// set the selected theme
d3
.
select
(
'body'
).
classed
(
settings
.
theme
,
true
);
// internal state
var
views
=
{},
current
=
{
view
:
null
,
ctx
:
''
ctx
:
''
,
theme
:
settings
.
theme
},
built
=
false
,
errorCount
=
0
,
keyHandler
=
{
fn
:
null
,
map
:
{}
globalKeys
:
{},
maskedKeys
:
{},
viewKeys
:
{},
viewFn
:
null
},
alerts
=
{
open
:
false
,
count
:
0
};
// DOM elements etc.
...
...
@@ -240,8 +251,8 @@
// detach radio buttons, key handlers, etc.
$
(
'#mastRadio'
).
children
().
detach
();
keyHandler
.
fn
=
null
;
keyHandler
.
map
=
{}
;
keyHandler
.
viewKeys
=
{}
;
keyHandler
.
viewFn
=
null
;
}
// cache new view and context
...
...
@@ -322,20 +333,74 @@
$mastRadio
.
node
().
appendChild
(
btnG
.
node
());
}
function
setupGlobalKeys
()
{
keyHandler
.
globalKeys
=
{
esc
:
escapeKey
,
T
:
toggleTheme
};
// Masked keys are global key handlers that always return true.
// That is, the view will never see the event for that key.
keyHandler
.
maskedKeys
=
{
T
:
true
};
}
function
escapeKey
(
view
,
key
,
code
,
ev
)
{
if
(
alerts
.
open
)
{
closeAlerts
();
return
true
;
}
return
false
;
}
function
toggleTheme
(
view
,
key
,
code
,
ev
)
{
var
body
=
d3
.
select
(
'body'
);
current
.
theme
=
(
current
.
theme
===
'light'
)
?
'dark'
:
'light'
;
body
.
classed
(
'light dark'
,
false
);
body
.
classed
(
current
.
theme
,
true
);
return
true
;
}
function
setKeyBindings
(
keyArg
)
{
var
viewKeys
,
masked
=
[];
if
(
$
.
isFunction
(
keyArg
))
{
// set general key handler callback
keyHandler
.
f
n
=
keyArg
;
keyHandler
.
viewF
n
=
keyArg
;
}
else
{
// set specific key filter map
keyHandler
.
map
=
keyArg
;
viewKeys
=
d3
.
map
(
keyArg
).
keys
();
viewKeys
.
forEach
(
function
(
key
)
{
if
(
keyHandler
.
maskedKeys
[
key
])
{
masked
.
push
(
' Key "'
+
key
+
'" is reserved'
);
}
});
if
(
masked
.
length
)
{
doAlert
(
'WARNING...\n\nsetKeys():\n'
+
masked
.
join
(
'\n'
));
}
keyHandler
.
viewKeys
=
keyArg
;
}
}
var
alerts
=
{
open
:
false
,
count
:
0
};
function
keyIn
()
{
var
event
=
d3
.
event
,
keyCode
=
event
.
keyCode
,
key
=
whatKey
(
keyCode
),
gcb
=
isF
(
keyHandler
.
globalKeys
[
key
]),
vcb
=
isF
(
keyHandler
.
viewKeys
[
key
])
||
isF
(
keyHandler
.
viewFn
);
// global callback?
if
(
gcb
&&
gcb
(
current
.
view
.
token
(),
key
,
keyCode
,
event
))
{
// if the event was 'handled', we are done
return
;
}
// otherwise, let the view callback have a shot
if
(
vcb
)
{
vcb
(
current
.
view
.
token
(),
key
,
keyCode
,
event
);
}
}
function
createAlerts
()
{
var
al
=
d3
.
select
(
'#alerts'
)
...
...
@@ -345,15 +410,16 @@
.
text
(
'X'
)
.
on
(
'click'
,
closeAlerts
);
al
.
append
(
'pre'
);
al
.
append
(
'p'
).
attr
(
'class'
,
'footnote'
)
.
text
(
'Press ESCAPE to close'
);
alerts
.
open
=
true
;
alerts
.
count
=
0
;
}
function
closeAlerts
()
{
d3
.
select
(
'#alerts'
)
.
style
(
'display'
,
'none'
);
d3
.
select
(
'#alerts span'
).
remove
();
d3
.
select
(
'#alerts pre'
).
remove
();
.
style
(
'display'
,
'none'
)
.
html
(
''
);
alerts
.
open
=
false
;
}
...
...
@@ -384,17 +450,6 @@
addAlert
(
msg
);
}
function
keyIn
()
{
var
event
=
d3
.
event
,
keyCode
=
event
.
keyCode
,
key
=
whatKey
(
keyCode
),
cb
=
isF
(
keyHandler
.
map
[
key
])
||
isF
(
keyHandler
.
fn
);
if
(
cb
)
{
cb
(
current
.
view
.
token
(),
key
,
keyCode
,
event
);
}
}
function
resize
(
e
)
{
d3
.
selectAll
(
'.onosView'
).
call
(
setViewDimensions
);
// allow current view to react to resize event...
...
...
@@ -683,6 +738,7 @@
$
(
window
).
on
(
'resize'
,
resize
);
d3
.
select
(
'body'
).
on
(
'keydown'
,
keyIn
);
setupGlobalKeys
();
// Invoke hashchange callback to navigate to content
// indicated by the window location hash.
...
...
web/gui/src/main/webapp/topo2.js
View file @
8c35207
...
...
@@ -28,7 +28,7 @@
// configuration data
var
config
=
{
useLiveData
:
fals
e
,
useLiveData
:
tru
e
,
debugOn
:
false
,
debug
:
{
showNodeXY
:
true
,
...
...
@@ -113,27 +113,31 @@
// key bindings
var
keyDispatch
=
{
space
:
injectTestEvent
,
// TODO: remove (testing only)
S
:
injectStartupEvents
,
// TODO: remove (testing only)
A
:
testAlert
,
// TODO: remove (testing only)
M
:
testMe
,
// TODO: remove (testing only)
S
:
injectStartupEvents
,
// TODO: remove (testing only)
space
:
injectTestEvent
,
// TODO: remove (testing only)
B
:
toggleBg
,
G
:
toggleLayout
,
B
:
toggleBg
,
// TODO: do we really need this?
L
:
cycleLabels
,
P
:
togglePorts
,
U
:
unpin
U
:
unpin
,
X
:
requestPath
};
// state variables
var
network
=
{
view
:
null
,
// view token reference
nodes
:
[],
links
:
[],
lookup
:
{}
},
webSock
,
labelIdx
=
0
,
selected
=
{},
selectOrder
=
[],
selections
=
{},
highlighted
=
null
,
hovered
=
null
,
viewMode
=
'showAll'
,
...
...
@@ -167,19 +171,19 @@
// ==============================
// Key Callbacks
function
testAlert
(
view
)
{
alertNumber
++
;
view
.
alert
(
"Test me! -- "
+
alertNumber
);
}
function
testMe
(
view
)
{
view
.
alert
(
'test'
);
}
function
injectTestEvent
(
view
)
{
if
(
config
.
useLiveData
)
{
view
.
alert
(
"Sorry, currently using live data.."
);
return
;
}
eventNumber
++
;
var
eventUrl
=
eventPrefix
+
eventNumber
+
'.json'
;
console
.
log
(
'Fetching JSON: '
+
eventUrl
);
d3
.
json
(
eventUrl
,
function
(
err
,
data
)
{
if
(
err
)
{
view
.
dataLoadError
(
err
,
eventUrl
);
...
...
@@ -190,6 +194,11 @@
}
function
injectStartupEvents
(
view
)
{
if
(
config
.
useLiveData
)
{
view
.
alert
(
"Sorry, currently using live data.."
);
return
;
}
var
lastStartupEvent
=
32
;
while
(
eventNumber
<
lastStartupEvent
)
{
injectTestEvent
(
view
);
...
...
@@ -201,19 +210,20 @@
bgImg
.
style
(
'visibility'
,
(
vis
===
'hidden'
)
?
'visible'
:
'hidden'
);
}
function
toggleLayout
(
view
)
{
function
cycleLabels
()
{
labelIdx
=
(
labelIdx
===
network
.
deviceLabelCount
-
1
)
?
0
:
labelIdx
+
1
;
function
niceLabel
(
label
)
{
return
(
label
&&
label
.
trim
())
?
label
:
'.'
;
}
function
cycleLabels
()
{
labelIdx
=
(
labelIdx
===
network
.
deviceLabelCount
-
1
)
?
0
:
labelIdx
+
1
;
network
.
nodes
.
forEach
(
function
(
d
)
{
var
idx
=
(
labelIdx
<
d
.
labels
.
length
)
?
labelIdx
:
0
,
node
=
d3
.
select
(
'#'
+
safeId
(
d
.
id
)),
box
;
node
.
select
(
'text'
)
.
text
(
d
.
labels
[
idx
]
)
.
text
(
niceLabel
(
d
.
labels
[
idx
])
)
.
style
(
'opacity'
,
0
)
.
transition
()
.
style
(
'opacity'
,
1
);
...
...
@@ -232,11 +242,19 @@
}
function
togglePorts
(
view
)
{
view
.
alert
(
'togglePorts() callback'
)
}
function
unpin
(
view
)
{
view
.
alert
(
'unpin() callback'
)
}
function
requestPath
(
view
)
{
var
payload
=
{
one
:
selections
[
selectOrder
[
0
]].
obj
.
id
,
two
:
selections
[
selectOrder
[
1
]].
obj
.
id
}
sendMessage
(
'requestPath'
,
payload
);
}
// ==============================
...
...
@@ -248,19 +266,19 @@
// d3.selectAll('svg .port').classed('inactive', false);
// d3.selectAll('svg .portText').classed('inactive', false);
// TODO ...
console
.
log
(
'showAllLayers()
'
);
network
.
view
.
alert
(
'showAllLayers() callback
'
);
}
function
showPacketLayer
()
{
showAllLayers
();
// TODO ...
console
.
log
(
'showPacketLayer()
'
);
network
.
view
.
alert
(
'showPacketLayer() callback
'
);
}
function
showOpticalLayer
()
{
showAllLayers
();
// TODO ...
console
.
log
(
'showOpticalLayer()
'
);
network
.
view
.
alert
(
'showOpticalLayer() callback
'
);
}
// ==============================
...
...
@@ -279,11 +297,6 @@
});
}
function
establishWebSocket
()
{
// TODO: establish a real web-socket
// NOTE, for now, we are using the 'Q' key to artificially inject
// "events" from the server.
}
// ==============================
// Event handlers for server-pushed events
...
...
@@ -292,7 +305,8 @@
addDevice
:
addDevice
,
updateDevice
:
updateDevice
,
removeDevice
:
removeDevice
,
addLink
:
addLink
addLink
:
addLink
,
showPath
:
showPath
};
function
addDevice
(
data
)
{
...
...
@@ -331,11 +345,14 @@
}
}
function
showPath
(
data
)
{
network
.
view
.
alert
(
data
.
event
+
"\n"
+
data
.
payload
.
links
.
length
);
}
// ....
function
unknownEvent
(
data
)
{
// TODO: use dialog, not alert
alert
(
'Unknown event type: "'
+
data
.
event
+
'"'
);
network
.
view
.
alert
(
'Unknown event type: "'
+
data
.
event
+
'"'
);
}
function
handleServerEvent
(
data
)
{
...
...
@@ -360,7 +377,9 @@
lnk
;
if
(
!
(
srcNode
&&
dstNode
))
{
alert
(
'nodes not on map'
);
// TODO: send warning message back to server on websocket
network
.
view
.
alert
(
'nodes not on map for link\n\n'
+
'src = '
+
src
+
'\ndst = '
+
dst
);
return
null
;
}
...
...
@@ -381,6 +400,7 @@
function
linkWidth
(
w
)
{
// w is number of links between nodes. Scale appropriately.
// TODO: use a d3.scale (linear, log, ... ?)
return
w
*
1.2
;
}
...
...
@@ -604,6 +624,7 @@
webSock
.
ws
.
onmessage
=
function
(
m
)
{
if
(
m
.
data
)
{
console
.
log
(
m
.
data
);
handleServerEvent
(
JSON
.
parse
(
m
.
data
));
}
};
...
...
@@ -613,7 +634,7 @@
},
send
:
function
(
text
)
{
if
(
text
!=
null
&&
text
.
length
>
0
)
{
if
(
text
!=
null
)
{
webSock
.
_send
(
text
);
}
},
...
...
@@ -621,11 +642,87 @@
_send
:
function
(
message
)
{
if
(
webSock
.
ws
)
{
webSock
.
ws
.
send
(
message
);
}
else
{
network
.
view
.
alert
(
'no web socket open'
);
}
}
};
var
sid
=
0
;
function
sendMessage
(
evType
,
payload
)
{
var
toSend
=
{
event
:
evType
,
sid
:
++
sid
,
payload
:
payload
};
webSock
.
send
(
JSON
.
stringify
(
toSend
));
}
// ==============================
// Selection stuff
function
selectObject
(
obj
,
el
)
{
var
n
,
meta
=
d3
.
event
.
sourceEvent
.
metaKey
;
if
(
el
)
{
n
=
d3
.
select
(
el
);
}
else
{
node
.
each
(
function
(
d
)
{
if
(
d
==
obj
)
{
n
=
d3
.
select
(
el
=
this
);
}
});
}
if
(
!
n
)
return
;
if
(
meta
&&
n
.
classed
(
'selected'
))
{
deselectObject
(
obj
.
id
);
//flyinPane(null);
return
;
}
if
(
!
meta
)
{
deselectAll
();
}
selections
[
obj
.
id
]
=
{
obj
:
obj
,
el
:
el
};
selectOrder
.
push
(
obj
.
id
);
n
.
classed
(
'selected'
,
true
);
//flyinPane(obj);
}
function
deselectObject
(
id
)
{
var
obj
=
selections
[
id
];
if
(
obj
)
{
d3
.
select
(
obj
.
el
).
classed
(
'selected'
,
false
);
selections
[
id
]
=
null
;
// TODO: use splice to remove element
}
//flyinPane(null);
}
function
deselectAll
()
{
// deselect all nodes in the network...
node
.
classed
(
'selected'
,
false
);
selections
=
{};
selectOrder
=
[];
//flyinPane(null);
}
$
(
'#view'
).
on
(
'click'
,
function
(
e
)
{
if
(
!
$
(
e
.
target
).
closest
(
'.node'
).
length
)
{
if
(
!
e
.
metaKey
)
{
deselectAll
();
}
}
});
// ==============================
// View life-cycle callbacks
...
...
@@ -680,7 +777,7 @@
}
function
selectCb
(
d
,
self
)
{
// TODO:
selectObject(d, self);
selectObject
(
d
,
self
);
}
function
atDragEnd
(
d
,
self
)
{
...
...
@@ -688,10 +785,21 @@
// if it is a device (not a host)
if
(
d
.
class
===
'device'
)
{
d
.
fixed
=
true
;
d3
.
select
(
self
).
classed
(
'fixed'
,
true
)
// TODO: send new [x,y] back to server, via websocket.
d3
.
select
(
self
).
classed
(
'fixed'
,
true
);
if
(
config
.
useLiveData
)
{
tellServerCoords
(
d
);
}
}
}
function
tellServerCoords
(
d
)
{
sendMessage
(
'updateMeta'
,
{
id
:
d
.
id
,
'class'
:
d
.
class
,
x
:
Math
.
floor
(
d
.
x
),
y
:
Math
.
floor
(
d
.
y
)
});
}
// set up the force layout
network
.
force
=
d3
.
layout
.
force
()
...
...
@@ -704,7 +812,6 @@
.
on
(
'tick'
,
tick
);
network
.
drag
=
d3u
.
createDragBehavior
(
network
.
force
,
selectCb
,
atDragEnd
);
webSock
.
connect
();
}
function
load
(
view
,
ctx
)
{
...
...
@@ -715,7 +822,9 @@
view
.
setRadio
(
btnSet
);
view
.
setKeys
(
keyDispatch
);
establishWebSocket
();
if
(
config
.
useLiveData
)
{
webSock
.
connect
();
}
}
function
resize
(
view
,
ctx
)
{
...
...
Please
register
or
login
to post a comment