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 21:24:56 -0800
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
9254d9654c663ec834e6f32e6700d1d8dd21e708
9254d965
2 parents
7e634e66
84165542
Merge branch 'master' of
ssh://gerrit.onlab.us:29418/onos-next
Hide whitespace changes
Inline
Side-by-side
Showing
62 changed files
with
980 additions
and
214 deletions
core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
core/store/dist/src/main/java/org/onlab/onos/store/service/impl/MapDBLog.java
providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilderVer13.java
tools/dev/bash_profile
tools/dev/onos.cshrc
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/ev/intent/ev_1_ui.json
web/gui/src/main/webapp/json/intent/ev_2_onos.json → web/gui/src/main/webapp/json/ev/intent/ev_2_onos.json
web/gui/src/main/webapp/json/intent/ev_3_ui.json → web/gui/src/main/webapp/json/ev/intent/ev_3_ui.json
web/gui/src/main/webapp/json/intent/ev_4_onos.json → web/gui/src/main/webapp/json/ev/intent/ev_4_onos.json
web/gui/src/main/webapp/json/intent/ev_5_onos.json → web/gui/src/main/webapp/json/ev/intent/ev_5_onos.json
web/gui/src/main/webapp/json/intent/ev_6_onos.json → web/gui/src/main/webapp/json/ev/intent/ev_6_onos.json
web/gui/src/main/webapp/json/intent/ev_7_ui.json → web/gui/src/main/webapp/json/ev/intent/ev_7_ui.json
web/gui/src/main/webapp/json/ev/intent/scenario.json
web/gui/src/main/webapp/json/ev/simple/ev_1_onos.json
web/gui/src/main/webapp/json/ev/simple/ev_2_onos.json
web/gui/src/main/webapp/json/ev/simple/ev_3_onos.json
web/gui/src/main/webapp/json/ev/simple/ev_4_onos.json
web/gui/src/main/webapp/json/ev/simple/ev_5_onos.json
web/gui/src/main/webapp/json/ev/simple/scenario.json
web/gui/src/main/webapp/json/eventTest_10.json → web/gui/src/main/webapp/json/ev/startup/ev_10_onos.json
web/gui/src/main/webapp/json/eventTest_11.json → web/gui/src/main/webapp/json/ev/startup/ev_11_onos.json
web/gui/src/main/webapp/json/eventTest_12.json → web/gui/src/main/webapp/json/ev/startup/ev_12_onos.json
web/gui/src/main/webapp/json/eventTest_13.json → web/gui/src/main/webapp/json/ev/startup/ev_13_onos.json
web/gui/src/main/webapp/json/eventTest_14.json → web/gui/src/main/webapp/json/ev/startup/ev_14_onos.json
web/gui/src/main/webapp/json/eventTest_15.json → web/gui/src/main/webapp/json/ev/startup/ev_15_onos.json
web/gui/src/main/webapp/json/eventTest_16.json → web/gui/src/main/webapp/json/ev/startup/ev_16_onos.json
web/gui/src/main/webapp/json/eventTest_17.json → web/gui/src/main/webapp/json/ev/startup/ev_17_onos.json
web/gui/src/main/webapp/json/eventTest_18.json → web/gui/src/main/webapp/json/ev/startup/ev_18_onos.json
web/gui/src/main/webapp/json/eventTest_19.json → web/gui/src/main/webapp/json/ev/startup/ev_19_onos.json
web/gui/src/main/webapp/json/eventTest_1.json → web/gui/src/main/webapp/json/ev/startup/ev_1_onos.json
web/gui/src/main/webapp/json/eventTest_20.json → web/gui/src/main/webapp/json/ev/startup/ev_20_onos.json
web/gui/src/main/webapp/json/eventTest_21.json → web/gui/src/main/webapp/json/ev/startup/ev_21_onos.json
web/gui/src/main/webapp/json/eventTest_22.json → web/gui/src/main/webapp/json/ev/startup/ev_22_onos.json
web/gui/src/main/webapp/json/eventTest_23.json → web/gui/src/main/webapp/json/ev/startup/ev_23_onos.json
web/gui/src/main/webapp/json/eventTest_24.json → web/gui/src/main/webapp/json/ev/startup/ev_24_onos.json
web/gui/src/main/webapp/json/eventTest_25.json → web/gui/src/main/webapp/json/ev/startup/ev_25_onos.json
web/gui/src/main/webapp/json/eventTest_26.json → web/gui/src/main/webapp/json/ev/startup/ev_26_onos.json
web/gui/src/main/webapp/json/eventTest_27.json → web/gui/src/main/webapp/json/ev/startup/ev_27_onos.json
web/gui/src/main/webapp/json/eventTest_28.json → web/gui/src/main/webapp/json/ev/startup/ev_28_onos.json
web/gui/src/main/webapp/json/eventTest_29.json → web/gui/src/main/webapp/json/ev/startup/ev_29_onos.json
web/gui/src/main/webapp/json/eventTest_2.json → web/gui/src/main/webapp/json/ev/startup/ev_2_onos.json
web/gui/src/main/webapp/json/eventTest_30.json → web/gui/src/main/webapp/json/ev/startup/ev_30_onos.json
web/gui/src/main/webapp/json/eventTest_31.json → web/gui/src/main/webapp/json/ev/startup/ev_31_onos.json
web/gui/src/main/webapp/json/eventTest_32.json → web/gui/src/main/webapp/json/ev/startup/ev_32_onos.json
web/gui/src/main/webapp/json/eventTest_33.json → web/gui/src/main/webapp/json/ev/startup/ev_33_onos.json
web/gui/src/main/webapp/json/eventTest_34.json → web/gui/src/main/webapp/json/ev/startup/ev_34_onos.json
web/gui/src/main/webapp/json/eventTest_35.json → web/gui/src/main/webapp/json/ev/startup/ev_35_onos.json
web/gui/src/main/webapp/json/eventTest_3.json → web/gui/src/main/webapp/json/ev/startup/ev_3_onos.json
web/gui/src/main/webapp/json/eventTest_4.json → web/gui/src/main/webapp/json/ev/startup/ev_4_onos.json
web/gui/src/main/webapp/json/eventTest_5.json → web/gui/src/main/webapp/json/ev/startup/ev_5_onos.json
web/gui/src/main/webapp/json/eventTest_6.json → web/gui/src/main/webapp/json/ev/startup/ev_6_onos.json
web/gui/src/main/webapp/json/eventTest_7.json → web/gui/src/main/webapp/json/ev/startup/ev_7_onos.json
web/gui/src/main/webapp/json/eventTest_8.json → web/gui/src/main/webapp/json/ev/startup/ev_8_onos.json
web/gui/src/main/webapp/json/eventTest_9.json → web/gui/src/main/webapp/json/ev/startup/ev_9_onos.json
web/gui/src/main/webapp/json/ev/startup/scenario.json
web/gui/src/main/webapp/onos2.js
web/gui/src/main/webapp/preamble.js
web/gui/src/main/webapp/sampleHash.js
web/gui/src/main/webapp/topo2.css
web/gui/src/main/webapp/topo2.js
core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
View file @
9254d96
...
...
@@ -296,7 +296,7 @@ public class FlowRuleManager
post
(
event
);
}
}
else
{
log
.
info
(
"Removing flow rules...."
);
log
.
debug
(
"Removing flow rules...."
);
removeFlowRules
(
flowEntry
);
}
...
...
core/store/dist/src/main/java/org/onlab/onos/store/service/impl/MapDBLog.java
View file @
9254d96
...
...
@@ -2,13 +2,16 @@ package org.onlab.onos.store.service.impl;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkArgument
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkState
;
import
static
com
.
google
.
common
.
base
.
Verify
.
verifyNotNull
;
import
static
org
.
slf4j
.
LoggerFactory
.
getLogger
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentNavigableMap
;
import
net.kuujo.copycat.log.Entry
;
...
...
@@ -25,8 +28,6 @@ import org.mapdb.TxMaker;
import
org.onlab.onos.store.serializers.StoreSerializer
;
import
org.slf4j.Logger
;
import
com.google.common.collect.Lists
;
/**
* MapDB based log implementation.
*/
...
...
@@ -84,7 +85,7 @@ public class MapDBLog implements Log {
public
List
<
Long
>
appendEntries
(
List
<
Entry
>
entries
)
{
assertIsOpen
();
checkArgument
(
entries
!=
null
,
"expecting non-null entries"
);
final
List
<
Long
>
indices
=
Lists
.
newArrayList
(
);
final
List
<
Long
>
indices
=
new
ArrayList
<>(
entries
.
size
()
);
txMaker
.
execute
(
new
TxBlock
()
{
@Override
...
...
@@ -92,13 +93,15 @@ public class MapDBLog implements Log {
BTreeMap
<
Long
,
byte
[]>
log
=
getLogMap
(
db
);
Atomic
.
Long
size
=
db
.
getAtomicLong
(
SIZE_FIELD_NAME
);
long
nextIndex
=
log
.
isEmpty
()
?
1
:
log
.
lastKey
()
+
1
;
long
addedBytes
=
0
;
for
(
Entry
entry
:
entries
)
{
byte
[]
entryBytes
=
serializer
.
encode
(
entry
);
log
.
put
(
nextIndex
,
entryBytes
);
size
.
addAndGet
(
entryBytes
.
length
)
;
addedBytes
+=
entryBytes
.
length
;
indices
.
add
(
nextIndex
);
nextIndex
++;
}
size
.
addAndGet
(
addedBytes
);
}
});
...
...
@@ -236,12 +239,15 @@ public class MapDBLog implements Log {
public
void
tx
(
DB
db
)
{
BTreeMap
<
Long
,
byte
[]>
log
=
getLogMap
(
db
);
Atomic
.
Long
size
=
db
.
getAtomicLong
(
SIZE_FIELD_NAME
);
long
startIndex
=
index
+
1
;
long
endIndex
=
log
.
lastKey
();
for
(
long
i
=
startIndex
;
i
<=
endIndex
;
++
i
)
{
byte
[]
entryBytes
=
log
.
remove
(
i
);
size
.
addAndGet
(-
1L
*
entryBytes
.
length
);
long
removedBytes
=
0
;
ConcurrentNavigableMap
<
Long
,
byte
[]>
tailMap
=
log
.
tailMap
(
index
,
false
);
Iterator
<
Map
.
Entry
<
Long
,
byte
[]>>
it
=
tailMap
.
entrySet
().
iterator
();
while
(
it
.
hasNext
())
{
Map
.
Entry
<
Long
,
byte
[]>
entry
=
it
.
next
();
removedBytes
+=
entry
.
getValue
().
length
;
it
.
remove
();
}
size
.
addAndGet
(-
removedBytes
);
}
});
}
...
...
@@ -273,9 +279,16 @@ public class MapDBLog implements Log {
BTreeMap
<
Long
,
byte
[]>
log
=
getLogMap
(
db
);
Atomic
.
Long
size
=
db
.
getAtomicLong
(
SIZE_FIELD_NAME
);
ConcurrentNavigableMap
<
Long
,
byte
[]>
headMap
=
log
.
headMap
(
index
);
long
deletedBytes
=
headMap
.
keySet
().
stream
().
mapToLong
(
i
->
log
.
remove
(
i
).
length
).
sum
();
size
.
addAndGet
(-
1
*
deletedBytes
);
byte
[]
entryBytes
=
serializer
.
encode
(
entry
);
Iterator
<
Map
.
Entry
<
Long
,
byte
[]>>
it
=
headMap
.
entrySet
().
iterator
();
long
deletedBytes
=
0
;
while
(
it
.
hasNext
())
{
Map
.
Entry
<
Long
,
byte
[]>
e
=
it
.
next
();
deletedBytes
+=
e
.
getValue
().
length
;
it
.
remove
();
}
size
.
addAndGet
(-
deletedBytes
);
byte
[]
entryBytes
=
verifyNotNull
(
serializer
.
encode
(
entry
));
byte
[]
existingEntry
=
log
.
put
(
index
,
entryBytes
);
if
(
existingEntry
!=
null
)
{
size
.
addAndGet
(
entryBytes
.
length
-
existingEntry
.
length
);
...
...
providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilderVer13.java
View file @
9254d96
...
...
@@ -139,7 +139,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
.
setXid
(
cookie
)
.
setCookie
(
U64
.
of
(
cookie
))
.
setBufferId
(
OFBufferId
.
NO_BUFFER
)
.
setActions
(
actions
)
//.setActions(actions) //FIXME do we want to send actions in flowdel?
//.setInstructions(Collections.singletonList(writeActions))
.
setMatch
(
match
)
.
setFlags
(
Collections
.
singleton
(
OFFlowModFlags
.
SEND_FLOW_REM
))
...
...
tools/dev/bash_profile
View file @
9254d96
...
...
@@ -19,13 +19,13 @@ fi
export
MAVEN
=
${
MAVEN
:-
~/Applications/apache-maven-3.2.2
}
export
KARAF_VERSION
=
${
KARAF_VERSION
:-
3
.0.2
}
export
KARAF
=
${
KARAF
:-
~/Applications/apache-karaf-
$KARAF_VERSION
}
export
KARAF_LOG
=
$KARAF
/data/log/karaf.log
export
KARAF
_HOME
=
${
KARAF
:-
~/Applications/apache-karaf-
$KARAF_VERSION
}
export
KARAF_LOG
=
$KARAF
_HOME
/data/log/karaf.log
# Setup a path
export
PATH
=
"
$PATH
:
$ONOS_ROOT
/tools/dev/bin:
$ONOS_ROOT
/tools/test/bin"
export
PATH
=
"
$PATH
:
$ONOS_ROOT
/tools/build"
export
PATH
=
"
$PATH
:
$MAVEN
/bin:
$KARAF
/bin"
export
PATH
=
"
$PATH
:
$MAVEN
/bin:
$KARAF
_HOME
/bin"
# Convenience utility to warp to various ONOS source projects
# e.g. 'o api', 'o dev', 'o'
...
...
tools/dev/onos.cshrc
View file @
9254d96
...
...
@@ -29,8 +29,8 @@ endif
if ( ! $?KARAF_VERSION ) then
setenv KARAF_VERSION 3.0.2
endif
if ( ! $?KARAF ) then
setenv KARAF $HOME/Applications/apache-karaf-$KARAF_VERSION
if ( ! $?KARAF
_HOME
) then
setenv KARAF
_HOME
$HOME/Applications/apache-karaf-$KARAF_VERSION
endif
setenv KARAF_LOG $KARAF/data/log/karaf.log
...
...
web/gui/src/main/java/org/onlab/onos/gui/TopologyWebSocket.java
View file @
9254d96
...
...
@@ -20,50 +20,95 @@ 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.core.ApplicationId
;
import
org.onlab.onos.core.CoreService
;
import
org.onlab.onos.mastership.MastershipEvent
;
import
org.onlab.onos.mastership.MastershipListener
;
import
org.onlab.onos.mastership.MastershipService
;
import
org.onlab.onos.net.Annotations
;
import
org.onlab.onos.net.ConnectPoint
;
import
org.onlab.onos.net.DefaultEdgeLink
;
import
org.onlab.onos.net.Device
;
import
org.onlab.onos.net.DeviceId
;
import
org.onlab.onos.net.ElementId
;
import
org.onlab.onos.net.Host
;
import
org.onlab.onos.net.HostId
;
import
org.onlab.onos.net.HostLocation
;
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.DeviceListener
;
import
org.onlab.onos.net.device.DeviceService
;
import
org.onlab.onos.net.flow.DefaultTrafficSelector
;
import
org.onlab.onos.net.flow.DefaultTrafficTreatment
;
import
org.onlab.onos.net.host.HostEvent
;
import
org.onlab.onos.net.host.HostListener
;
import
org.onlab.onos.net.host.HostService
;
import
org.onlab.onos.net.intent.HostToHostIntent
;
import
org.onlab.onos.net.intent.Intent
;
import
org.onlab.onos.net.intent.IntentEvent
;
import
org.onlab.onos.net.intent.IntentId
;
import
org.onlab.onos.net.intent.IntentListener
;
import
org.onlab.onos.net.intent.IntentService
;
import
org.onlab.onos.net.intent.PathIntent
;
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
;
import
org.onlab.onos.net.topology.TopologyGraph
;
import
org.onlab.onos.net.topology.TopologyListener
;
import
org.onlab.onos.net.topology.TopologyService
;
import
org.onlab.onos.net.topology.TopologyVertex
;
import
org.onlab.onos.net.link.LinkListener
;
import
org.onlab.onos.net.link.LinkService
;
import
org.onlab.onos.net.provider.ProviderId
;
import
org.onlab.onos.net.topology.PathService
;
import
org.onlab.osgi.ServiceDirectory
;
import
org.onlab.packet.IpAddress
;
import
java.io.IOException
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.ConcurrentHashMap
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkNotNull
;
import
static
org
.
onlab
.
onos
.
net
.
DeviceId
.
deviceId
;
import
static
org
.
onlab
.
onos
.
net
.
HostId
.
hostId
;
import
static
org
.
onlab
.
onos
.
net
.
PortNumber
.
portNumber
;
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
.
host
.
HostEvent
.
Type
.
HOST_ADDED
;
import
static
org
.
onlab
.
onos
.
net
.
host
.
HostEvent
.
Type
.
HOST_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.
*/
public
class
TopologyWebSocket
implements
WebSocket
.
OnTextMessage
,
TopologyListener
{
public
class
TopologyWebSocket
implements
WebSocket
.
OnTextMessage
{
private
static
final
String
APP_ID
=
"org.onlab.onos.gui"
;
private
static
final
ProviderId
PID
=
new
ProviderId
(
"core"
,
"org.onlab.onos.core"
,
true
);
private
final
ApplicationId
appId
;
private
final
ServiceDirectory
directory
;
private
final
TopologyService
topologyService
;
private
final
DeviceService
deviceService
;
private
final
ObjectMapper
mapper
=
new
ObjectMapper
();
private
Connection
connection
;
private
final
DeviceService
deviceService
;
private
final
LinkService
linkService
;
private
final
HostService
hostService
;
private
final
MastershipService
mastershipService
;
private
final
IntentService
intentService
;
private
final
DeviceListener
deviceListener
=
new
InternalDeviceListener
();
private
final
LinkListener
linkListener
=
new
InternalLinkListener
();
private
final
HostListener
hostListener
=
new
InternalHostListener
();
private
final
MastershipListener
mastershipListener
=
new
InternalMastershipListener
();
private
final
IntentListener
intentListener
=
new
InternalIntentListener
();
// TODO: extract into an external & durable state; good enough for now and demo
private
static
Map
<
String
,
ObjectNode
>
metaUi
=
new
HashMap
<>();
private
static
Map
<
String
,
ObjectNode
>
metaUi
=
new
ConcurrentHashMap
<>();
// Intents that are being monitored for the GUI
private
static
Map
<
IntentId
,
Long
>
intentsToMonitor
=
new
ConcurrentHashMap
<>();
private
static
final
String
COMPACT
=
"%s/%s-%s/%s"
;
...
...
@@ -74,81 +119,231 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe
* @param directory service directory
*/
public
TopologyWebSocket
(
ServiceDirectory
directory
)
{
this
.
directory
=
directory
;
topologyService
=
directory
.
get
(
TopologyService
.
class
);
this
.
directory
=
checkNotNull
(
directory
,
"Directory cannot be null"
);
deviceService
=
directory
.
get
(
DeviceService
.
class
);
linkService
=
directory
.
get
(
LinkService
.
class
);
hostService
=
directory
.
get
(
HostService
.
class
);
mastershipService
=
directory
.
get
(
MastershipService
.
class
);
intentService
=
directory
.
get
(
IntentService
.
class
);
appId
=
directory
.
get
(
CoreService
.
class
).
registerApplication
(
APP_ID
);
}
@Override
public
void
onOpen
(
Connection
connection
)
{
this
.
connection
=
connection
;
deviceService
.
addListener
(
deviceListener
);
linkService
.
addListener
(
linkListener
);
hostService
.
addListener
(
hostListener
);
mastershipService
.
addListener
(
mastershipListener
);
intentService
.
addListener
(
intentListener
);
sendAllDevices
();
sendAllLinks
();
sendAllHosts
();
}
// Register for topology events...
if
(
topologyService
!=
null
&&
deviceService
!=
null
)
{
topologyService
.
addListener
(
this
);
Topology
topology
=
topologyService
.
currentTopology
();
TopologyGraph
graph
=
topologyService
.
getGraph
(
topology
);
for
(
TopologyVertex
vertex
:
graph
.
getVertexes
())
{
sendMessage
(
message
(
new
DeviceEvent
(
DEVICE_ADDED
,
deviceService
.
getDevice
(
vertex
.
deviceId
()))));
}
private
void
sendAllHosts
()
{
for
(
Host
host
:
hostService
.
getHosts
())
{
sendMessage
(
hostMessage
(
new
HostEvent
(
HOST_ADDED
,
host
)));
}
}
for
(
TopologyEdge
edge
:
graph
.
getEdges
())
{
sendMessage
(
message
(
new
LinkEvent
(
LINK_ADDED
,
edge
.
link
())));
}
private
void
sendAllDevices
()
{
for
(
Device
device
:
deviceService
.
getDevices
())
{
sendMessage
(
deviceMessage
(
new
DeviceEvent
(
DEVICE_ADDED
,
device
)));
}
}
}
else
{
sendMessage
(
message
(
"error"
,
"No topology service!!!"
));
private
void
sendAllLinks
()
{
for
(
Link
link
:
linkService
.
getLinks
())
{
sendMessage
(
linkMessage
(
new
LinkEvent
(
LINK_ADDED
,
link
)));
}
}
@Override
public
void
onClose
(
int
closeCode
,
String
message
)
{
TopologyService
topologyService
=
directory
.
get
(
TopologyService
.
class
);
if
(
topologyService
!=
null
)
{
topologyService
.
removeListener
(
this
);
}
deviceService
.
removeListener
(
deviceListener
);
linkService
.
removeListener
(
linkListener
);
hostService
.
removeListener
(
hostListener
);
mastershipService
.
removeListener
(
mastershipListener
);
}
@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
;
String
type
=
string
(
event
,
"event"
,
"unknown"
);
if
(
type
.
equals
(
"showDetails"
))
{
showDetails
(
event
);
}
else
if
(
type
.
equals
(
"updateMeta"
))
{
updateMetaInformation
(
event
);
}
else
if
(
type
.
equals
(
"requestPath"
))
{
createHostIntent
(
event
);
}
else
if
(
type
.
equals
(
"requestTraffic"
))
{
sendTraffic
(
event
);
}
else
if
(
type
.
equals
(
"cancelTraffic"
))
{
cancelTraffic
(
event
);
}
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"WTF?! "
+
data
);
e
.
printStackTrace
();
}
}
// Sends the specified data to the client.
private
void
sendMessage
(
ObjectNode
data
)
{
try
{
connection
.
sendMessage
(
data
.
toString
());
}
catch
(
IOException
e
)
{
System
.
out
.
println
(
"Received: "
+
data
);
e
.
printStackTrace
(
);
}
}
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
();
// Retrieves the payload from the specified event.
private
ObjectNode
payload
(
ObjectNode
event
)
{
return
(
ObjectNode
)
event
.
path
(
"payload"
);
}
Path
path
=
paths
.
iterator
().
next
();
for
(
Link
link
:
path
.
links
())
{
links
.
add
(
compactLinkString
(
link
));
}
// Returns the specified node property as a number
private
long
number
(
ObjectNode
node
,
String
name
)
{
return
node
.
path
(
name
).
asLong
();
}
// Returns the specified node property as a string.
private
String
string
(
ObjectNode
node
,
String
name
)
{
return
node
.
path
(
name
).
asText
();
}
// Returns the specified node property as a string.
private
String
string
(
ObjectNode
node
,
String
name
,
String
defaultValue
)
{
return
node
.
path
(
name
).
asText
(
defaultValue
);
}
// Returns the specified set of IP addresses as a string.
private
String
ip
(
Set
<
IpAddress
>
ipAddresses
)
{
Iterator
<
IpAddress
>
it
=
ipAddresses
.
iterator
();
return
it
.
hasNext
()
?
it
.
next
().
toString
()
:
"unknown"
;
}
// Encodes the specified host location into a JSON object.
private
ObjectNode
location
(
ObjectMapper
mapper
,
HostLocation
location
)
{
return
mapper
.
createObjectNode
()
.
put
(
"device"
,
location
.
deviceId
().
toString
())
.
put
(
"port"
,
location
.
port
().
toLong
());
}
// Encodes the specified list of labels a JSON array.
private
ArrayNode
labels
(
ObjectMapper
mapper
,
String
...
labels
)
{
ArrayNode
json
=
mapper
.
createArrayNode
();
for
(
String
label
:
labels
)
{
json
.
add
(
label
);
}
return
json
;
}
// 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
ObjectNode
message
(
String
severity
,
long
id
,
String
message
)
{
return
envelope
(
"message"
,
id
,
mapper
.
createObjectNode
()
.
put
(
"severity"
,
severity
)
.
put
(
"message"
,
message
));
}
// Puts the payload into an envelope and returns it.
private
ObjectNode
envelope
(
String
type
,
long
sid
,
ObjectNode
payload
)
{
ObjectNode
event
=
mapper
.
createObjectNode
();
event
.
put
(
"event"
,
type
);
if
(
sid
>
0
)
{
event
.
put
(
"sid"
,
sid
);
}
event
.
set
(
"payload"
,
payload
);
return
event
;
}
// Sends back device or host details.
private
void
showDetails
(
ObjectNode
event
)
{
ObjectNode
payload
=
payload
(
event
);
String
type
=
string
(
payload
,
"type"
,
"unknown"
);
if
(
type
.
equals
(
"device"
))
{
sendMessage
(
deviceDetails
(
deviceId
(
string
(
payload
,
"id"
)),
number
(
event
,
"sid"
)));
}
else
if
(
type
.
equals
(
"host"
))
{
sendMessage
(
hostDetails
(
hostId
(
string
(
payload
,
"id"
)),
number
(
event
,
"sid"
)));
}
}
// Updates device/host meta information.
private
void
updateMetaInformation
(
ObjectNode
event
)
{
ObjectNode
payload
=
payload
(
event
);
metaUi
.
put
(
string
(
payload
,
"id"
),
payload
);
}
// Creates host-to-host intent.
private
void
createHostIntent
(
ObjectNode
event
)
{
ObjectNode
payload
=
payload
(
event
);
long
id
=
number
(
event
,
"sid"
);
// TODO: add protection against device ids and non-existent hosts.
HostId
one
=
hostId
(
string
(
payload
,
"one"
));
HostId
two
=
hostId
(
string
(
payload
,
"two"
));
HostToHostIntent
hostIntent
=
new
HostToHostIntent
(
appId
,
one
,
two
,
DefaultTrafficSelector
.
builder
().
build
(),
DefaultTrafficTreatment
.
builder
().
build
());
intentsToMonitor
.
put
(
hostIntent
.
id
(),
number
(
event
,
"sid"
));
intentService
.
submit
(
hostIntent
);
}
// Sends traffic message.
private
void
sendTraffic
(
ObjectNode
event
)
{
ObjectNode
payload
=
payload
(
event
);
long
id
=
number
(
event
,
"sid"
);
IntentId
intentId
=
IntentId
.
valueOf
(
payload
.
path
(
"intentId"
).
asLong
());
payload
.
set
(
"links"
,
links
);
sendMessage
(
envelope
(
"showPath"
,
payload
));
if
(
payload
!=
null
)
{
payload
.
put
(
"traffic"
,
true
);
sendMessage
(
envelope
(
"showPath"
,
id
,
payload
));
}
else
{
sendMessage
(
message
(
"warn"
,
id
,
"No path found"
));
}
// TODO: when no path, send a message to the client
}
// Cancels sending traffic messages.
private
void
cancelTraffic
(
ObjectNode
event
)
{
// TODO: implement this
}
// Finds the path between the specified devices.
private
ObjectNode
findPath
(
DeviceId
one
,
DeviceId
two
)
{
PathService
pathService
=
directory
.
get
(
PathService
.
class
);
Set
<
Path
>
paths
=
pathService
.
getPaths
(
one
,
two
);
if
(
paths
.
isEmpty
())
{
return
null
;
}
else
{
return
pathMessage
(
paths
.
iterator
().
next
());
}
}
// Produces a path message to the client.
private
ObjectNode
pathMessage
(
Path
path
)
{
ObjectNode
payload
=
mapper
.
createObjectNode
();
ArrayNode
links
=
mapper
.
createArrayNode
();
for
(
Link
link
:
path
.
links
())
{
links
.
add
(
compactLinkString
(
link
));
}
payload
.
set
(
"links"
,
links
);
return
payload
;
}
/**
...
...
@@ -158,21 +353,13 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe
* @return formatted link string
*/
public
static
String
compactLinkString
(
Link
link
)
{
return
String
.
format
(
COMPACT
,
link
.
src
().
device
Id
(),
link
.
src
().
port
(),
link
.
dst
().
device
Id
(),
link
.
dst
().
port
());
return
String
.
format
(
COMPACT
,
link
.
src
().
element
Id
(),
link
.
src
().
port
(),
link
.
dst
().
element
Id
(),
link
.
dst
().
port
());
}
private
void
sendMessage
(
String
data
)
{
try
{
connection
.
sendMessage
(
data
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
// Produces a link event message to the client.
private
String
m
essage
(
DeviceEvent
event
)
{
private
ObjectNode
deviceM
essage
(
DeviceEvent
event
)
{
Device
device
=
event
.
subject
();
ObjectNode
payload
=
mapper
.
createObjectNode
()
.
put
(
"id"
,
device
.
id
().
toString
())
...
...
@@ -183,27 +370,24 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe
ArrayNode
labels
=
mapper
.
createArrayNode
();
labels
.
add
(
device
.
id
().
toString
());
labels
.
add
(
device
.
chassisId
().
toString
());
labels
.
add
(
"
"
);
// compact no-label view
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
);
}
addMetaUi
(
device
.
id
(),
payload
);
String
type
=
(
event
.
type
()
==
DEVICE_ADDED
)
?
"addDevice"
:
((
event
.
type
()
==
DEVICE_REMOVED
)
?
"removeDevice"
:
"updateDevice"
);
return
envelope
(
type
,
payload
);
return
envelope
(
type
,
0
,
payload
);
}
// Produces a link event message to the client.
private
String
m
essage
(
LinkEvent
event
)
{
private
ObjectNode
linkM
essage
(
LinkEvent
event
)
{
Link
link
=
event
.
subject
();
ObjectNode
payload
=
mapper
.
createObjectNode
()
.
put
(
"id"
,
compactLinkString
(
link
))
.
put
(
"type"
,
link
.
type
().
toString
().
toLowerCase
())
.
put
(
"linkWidth"
,
2
)
.
put
(
"src"
,
link
.
src
().
deviceId
().
toString
())
...
...
@@ -211,42 +395,147 @@ public class TopologyWebSocket implements WebSocket.OnTextMessage, TopologyListe
.
put
(
"dst"
,
link
.
dst
().
deviceId
().
toString
())
.
put
(
"dstPort"
,
link
.
dst
().
port
().
toString
());
String
type
=
(
event
.
type
()
==
LINK_ADDED
)
?
"addLink"
:
((
event
.
type
()
==
LINK_REMOVED
)
?
"removeLink"
:
"
remov
eLink"
);
return
envelope
(
type
,
payload
);
((
event
.
type
()
==
LINK_REMOVED
)
?
"removeLink"
:
"
updat
eLink"
);
return
envelope
(
type
,
0
,
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
));
// Produces a host event message to the client.
private
ObjectNode
hostMessage
(
HostEvent
event
)
{
Host
host
=
event
.
subject
();
ObjectNode
payload
=
mapper
.
createObjectNode
()
.
put
(
"id"
,
host
.
id
().
toString
())
.
put
(
"ingress"
,
compactLinkString
(
edgeLink
(
host
,
true
)))
.
put
(
"egress"
,
compactLinkString
(
edgeLink
(
host
,
false
)));
payload
.
set
(
"cp"
,
location
(
mapper
,
host
.
location
()));
payload
.
set
(
"labels"
,
labels
(
mapper
,
ip
(
host
.
ipAddresses
()),
host
.
mac
().
toString
()));
payload
.
set
(
"props"
,
props
(
host
.
annotations
()));
addMetaUi
(
host
.
id
(),
payload
);
String
type
=
(
event
.
type
()
==
HOST_ADDED
)
?
"addHost"
:
((
event
.
type
()
==
HOST_REMOVED
)
?
"removeHost"
:
"updateHost"
);
return
envelope
(
type
,
0
,
payload
);
}
private
DefaultEdgeLink
edgeLink
(
Host
host
,
boolean
ingress
)
{
return
new
DefaultEdgeLink
(
PID
,
new
ConnectPoint
(
host
.
id
(),
portNumber
(
0
)),
host
.
location
(),
ingress
);
}
private
void
addMetaUi
(
ElementId
id
,
ObjectNode
payload
)
{
ObjectNode
meta
=
metaUi
.
get
(
id
.
toString
());
if
(
meta
!=
null
)
{
payload
.
set
(
"metaUi"
,
meta
);
}
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
));
// Returns device details response.
private
ObjectNode
deviceDetails
(
DeviceId
deviceId
,
long
sid
)
{
Device
device
=
deviceService
.
getDevice
(
deviceId
);
Annotations
annot
=
device
.
annotations
();
int
portCount
=
deviceService
.
getPorts
(
deviceId
).
size
();
return
envelope
(
"showDetails"
,
sid
,
json
(
deviceId
.
toString
(),
device
.
type
().
toString
().
toLowerCase
(),
new
Prop
(
"Name"
,
annot
.
value
(
"name"
)),
new
Prop
(
"Vendor"
,
device
.
manufacturer
()),
new
Prop
(
"H/W Version"
,
device
.
hwVersion
()),
new
Prop
(
"S/W Version"
,
device
.
swVersion
()),
new
Prop
(
"Serial Number"
,
device
.
serialNumber
()),
new
Separator
(),
new
Prop
(
"Latitude"
,
annot
.
value
(
"latitude"
)),
new
Prop
(
"Longitude"
,
annot
.
value
(
"longitude"
)),
new
Prop
(
"Ports"
,
Integer
.
toString
(
portCount
))));
}
// 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
();
// Returns host details response.
private
ObjectNode
hostDetails
(
HostId
hostId
,
long
sid
)
{
Host
host
=
hostService
.
getHost
(
hostId
);
Annotations
annot
=
host
.
annotations
();
return
envelope
(
"showDetails"
,
sid
,
json
(
hostId
.
toString
(),
"host"
,
new
Prop
(
"MAC"
,
host
.
mac
().
toString
()),
new
Prop
(
"IP"
,
host
.
ipAddresses
().
toString
()),
new
Separator
(),
new
Prop
(
"Latitude"
,
annot
.
value
(
"latitude"
)),
new
Prop
(
"Longitude"
,
annot
.
value
(
"longitude"
))));
}
@Override
public
void
event
(
TopologyEvent
event
)
{
for
(
Event
reason
:
event
.
reasons
())
{
if
(
reason
instanceof
DeviceEvent
)
{
sendMessage
(
message
((
DeviceEvent
)
reason
));
}
else
if
(
reason
instanceof
LinkEvent
)
{
sendMessage
(
message
((
LinkEvent
)
reason
));
// Produces JSON property details.
private
ObjectNode
json
(
String
id
,
String
type
,
Prop
...
props
)
{
ObjectMapper
mapper
=
new
ObjectMapper
();
ObjectNode
result
=
mapper
.
createObjectNode
()
.
put
(
"id"
,
id
).
put
(
"type"
,
type
);
ObjectNode
pnode
=
mapper
.
createObjectNode
();
ArrayNode
porder
=
mapper
.
createArrayNode
();
for
(
Prop
p
:
props
)
{
porder
.
add
(
p
.
key
);
pnode
.
put
(
p
.
key
,
p
.
value
);
}
result
.
set
(
"propOrder"
,
porder
);
result
.
set
(
"props"
,
pnode
);
return
result
;
}
// Auxiliary key/value carrier.
private
class
Prop
{
private
final
String
key
;
private
final
String
value
;
protected
Prop
(
String
key
,
String
value
)
{
this
.
key
=
key
;
this
.
value
=
value
;
}
}
private
class
Separator
extends
Prop
{
protected
Separator
()
{
super
(
"-"
,
""
);
}
}
private
class
InternalDeviceListener
implements
DeviceListener
{
@Override
public
void
event
(
DeviceEvent
event
)
{
sendMessage
(
deviceMessage
(
event
));
}
}
private
class
InternalLinkListener
implements
LinkListener
{
@Override
public
void
event
(
LinkEvent
event
)
{
sendMessage
(
linkMessage
(
event
));
}
}
private
class
InternalHostListener
implements
HostListener
{
@Override
public
void
event
(
HostEvent
event
)
{
sendMessage
(
hostMessage
(
event
));
}
}
private
class
InternalMastershipListener
implements
MastershipListener
{
@Override
public
void
event
(
MastershipEvent
event
)
{
}
}
private
class
InternalIntentListener
implements
IntentListener
{
@Override
public
void
event
(
IntentEvent
event
)
{
Intent
intent
=
event
.
subject
();
Long
sid
=
intentsToMonitor
.
get
(
intent
.
id
());
if
(
sid
!=
null
)
{
List
<
Intent
>
installable
=
intentService
.
getInstallableIntents
(
intent
.
id
());
if
(
installable
!=
null
&&
!
installable
.
isEmpty
())
{
PathIntent
pathIntent
=
(
PathIntent
)
installable
.
iterator
().
next
();
Path
path
=
pathIntent
.
path
();
ObjectNode
payload
=
pathMessage
(
path
).
put
(
"intentId"
,
intent
.
id
().
toString
());
sendMessage
(
envelope
(
"showPath"
,
sid
,
payload
));
}
}
}
}
...
...
web/gui/src/main/webapp/index2.html
View file @
9254d96
...
...
@@ -90,6 +90,7 @@
<script
src=
"sampleAlt2.js"
></script>
<script
src=
"sampleRadio.js"
></script>
<script
src=
"sampleKeys.js"
></script>
<script
src=
"sampleHash.js"
></script>
<!-- Contributed (application) views injected here -->
<!-- TODO: replace with template marker and inject refs server-side -->
...
...
web/gui/src/main/webapp/json/intent/ev_1_ui.json
→
web/gui/src/main/webapp/json/
ev/
intent/ev_1_ui.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/intent/ev_2_onos.json
→
web/gui/src/main/webapp/json/
ev/
intent/ev_2_onos.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/intent/ev_3_ui.json
→
web/gui/src/main/webapp/json/
ev/
intent/ev_3_ui.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/intent/ev_4_onos.json
→
web/gui/src/main/webapp/json/
ev/
intent/ev_4_onos.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/intent/ev_5_onos.json
→
web/gui/src/main/webapp/json/
ev/
intent/ev_5_onos.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/intent/ev_6_onos.json
→
web/gui/src/main/webapp/json/
ev/
intent/ev_6_onos.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/intent/ev_7_ui.json
→
web/gui/src/main/webapp/json/
ev/
intent/ev_7_ui.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev/intent/scenario.json
0 → 100644
View file @
9254d96
{
"comments"
:
[
"This scenario steps through adding a host intent."
],
"title"
:
"Host Intent Scenario"
,
"params"
:
{
"lastAuto"
:
0
}
}
\ No newline at end of file
web/gui/src/main/webapp/json/ev/simple/ev_1_onos.json
0 → 100644
View file @
9254d96
{
"event"
:
"addDevice"
,
"payload"
:
{
"id"
:
"of:0000ffffffff0008"
,
"type"
:
"switch"
,
"online"
:
false
,
"labels"
:
[
"0000ffffffff0008"
,
"FF:FF:FF:FF:00:08"
,
"sw-8"
],
"metaUi"
:
{
"x"
:
400
,
"y"
:
280
}
}
}
web/gui/src/main/webapp/json/ev/simple/ev_2_onos.json
0 → 100644
View file @
9254d96
{
"event"
:
"addDevice"
,
"payload"
:
{
"id"
:
"of:0000ffffffff0003"
,
"type"
:
"switch"
,
"online"
:
false
,
"labels"
:
[
"0000ffffffff0003"
,
"FF:FF:FF:FF:00:03"
,
"sw-3"
],
"metaUi"
:
{
"x"
:
800
,
"y"
:
280
}
}
}
web/gui/src/main/webapp/json/ev/simple/ev_3_onos.json
0 → 100644
View file @
9254d96
{
"event"
:
"addLink"
,
"payload"
:
{
"src"
:
"of:0000ffffffff0003"
,
"srcPort"
:
"21"
,
"dst"
:
"of:0000ffffffff0008"
,
"dstPort"
:
"20"
,
"type"
:
"infra"
,
"linkWidth"
:
2
,
"props"
:
{
"BW"
:
"70 G"
}
}
}
web/gui/src/main/webapp/json/ev/simple/ev_4_onos.json
0 → 100644
View file @
9254d96
{
"event"
:
"addHost"
,
"payload"
:
{
"id"
:
"00:00:00:00:00:03/-1"
,
"cp"
:
{
"device"
:
"of:0000ffffffff0003"
,
"port"
:
1
},
"labels"
:
[
"10.0.0.3"
,
"00:00:00:00:00:03"
],
"metaUi"
:
{
}
}
}
web/gui/src/main/webapp/json/ev/simple/ev_5_onos.json
0 → 100644
View file @
9254d96
{
"event"
:
"addHost"
,
"payload"
:
{
"id"
:
"00:00:00:00:00:08/-1"
,
"cp"
:
{
"device"
:
"of:0000ffffffff0008"
,
"port"
:
1
},
"labels"
:
[
"10.0.0.8"
,
"00:00:00:00:00:08"
],
"metaUi"
:
{
}
}
}
web/gui/src/main/webapp/json/ev/simple/scenario.json
0 → 100644
View file @
9254d96
{
"comments"
:
[
"Add two devices and one link (auto), and two hosts."
],
"title"
:
"Simple Startup Scenario"
,
"params"
:
{
"lastAuto"
:
0
}
}
\ No newline at end of file
web/gui/src/main/webapp/json/ev
entTest_10
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_10_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_11
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_11_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_12
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_12_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_13
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_13_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_14
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_14_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_15
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_15_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_16
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_16_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_17
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_17_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_18
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_18_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_19
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_19_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_1
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_1_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_20
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_20_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_21
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_21_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_22
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_22_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_23
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_23_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_24
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_24_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_25
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_25_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_26
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_26_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_27
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_27_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_28
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_28_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_29
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_29_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_2
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_2_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_30
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_30_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_31
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_31_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_32
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_32_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_33
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_33_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_34
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_34_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_35
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_35_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_3
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_3_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_4
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_4_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_5
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_5_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_6
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_6_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_7
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_7_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_8
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_8_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev
entTest_9
.json
→
web/gui/src/main/webapp/json/ev
/startup/ev_9_onos
.json
View file @
9254d96
File moved
web/gui/src/main/webapp/json/ev/startup/scenario.json
0 → 100644
View file @
9254d96
{
"comments"
:
[
"This scenario steps through adding devices and links."
,
"(Typical 'start-ip' of the view.)"
],
"title"
:
"Startup Scenario"
,
"params"
:
{
"lastAuto"
:
32
}
}
\ No newline at end of file
web/gui/src/main/webapp/onos2.js
View file @
9254d96
...
...
@@ -52,6 +52,7 @@
current
=
{
view
:
null
,
ctx
:
''
,
flags
:
{},
theme
:
settings
.
theme
},
built
=
false
,
...
...
@@ -110,6 +111,7 @@
function
doError
(
msg
)
{
errorCount
++
;
console
.
error
(
msg
);
doAlert
(
msg
);
}
function
trace
(
msg
)
{
...
...
@@ -140,7 +142,7 @@
t
=
parseHash
(
hash
);
if
(
!
t
||
!
t
.
vid
)
{
doError
(
'Unable to parse target hash:
'
+
hash
);
doError
(
'Unable to parse target hash:
"'
+
hash
+
'"'
);
}
view
=
views
[
t
.
vid
];
...
...
@@ -160,33 +162,72 @@
function
parseHash
(
s
)
{
// extract navigation coordinates from the supplied string
// "vid,ctx
" --> { vid:vid, ctx:ctx
}
// "vid,ctx
?flag1,flag2" --> { vid:vid, ctx:ctx, flags:{...}
}
traceFn
(
'parseHash'
,
s
);
var
m
=
/^
[
#
]{0,1}(\S
+
)
,
(\S
*
)
$/
.
exec
(
s
);
// look for use of flags, first
var
vidctx
,
vid
,
ctx
,
flags
,
flagMap
,
m
;
// RE that includes flags ('?flag1,flag2')
m
=
/^
[
#
]{0,1}(
.+
)\?(
.+
)
$/
.
exec
(
s
);
if
(
m
)
{
return
{
vid
:
m
[
1
],
ctx
:
m
[
2
]
};
vidctx
=
m
[
1
];
flags
=
m
[
2
];
flagMap
=
{};
}
else
{
// no flags
m
=
/^
[
#
]{0,1}((
.+
)(
,.+
)
*
)
$/
.
exec
(
s
);
if
(
m
)
{
vidctx
=
m
[
1
];
}
else
{
// bad hash
return
null
;
}
}
vidctx
=
vidctx
.
split
(
','
);
vid
=
vidctx
[
0
];
ctx
=
vidctx
[
1
];
if
(
flags
)
{
flags
.
split
(
','
).
forEach
(
function
(
f
)
{
flagMap
[
f
.
trim
()]
=
true
;
});
}
m
=
/^
[
#
]{0,1}(\S
+
)
$/
.
exec
(
s
);
return
m
?
{
vid
:
m
[
1
]
}
:
null
;
return
{
vid
:
vid
.
trim
(),
ctx
:
ctx
?
ctx
.
trim
()
:
''
,
flags
:
flagMap
};
}
function
makeHash
(
t
,
ctx
)
{
function
makeHash
(
t
,
ctx
,
flags
)
{
traceFn
(
'makeHash'
);
// make a hash string from the given navigation coordinates.
// make a hash string from the given navigation coordinates,
// and optional flags map.
// if t is not an object, then it is a vid
var
h
=
t
,
c
=
ctx
||
''
;
c
=
ctx
||
''
,
f
=
$
.
isPlainObject
(
flags
)
?
flags
:
null
;
if
(
$
.
isPlainObject
(
t
))
{
h
=
t
.
vid
;
c
=
t
.
ctx
||
''
;
f
=
t
.
flags
||
null
;
}
if
(
c
)
{
h
+=
','
+
c
;
}
if
(
f
)
{
h
+=
'?'
+
d3
.
map
(
f
).
keys
().
join
(
','
);
}
trace
(
'hash = "'
+
h
+
'"'
);
return
h
;
}
...
...
@@ -244,6 +285,9 @@
// set the specified view as current, while invoking the
// appropriate life-cycle callbacks
// first, we'll start by closing the alerts pane, if open
closeAlerts
();
// if there is a current view, and it is not the same as
// the incoming view, then unload it...
if
(
current
.
view
&&
(
current
.
view
.
vid
!==
view
.
vid
))
{
...
...
@@ -258,10 +302,11 @@
// cache new view and context
current
.
view
=
view
;
current
.
ctx
=
t
.
ctx
||
''
;
current
.
flags
=
t
.
flags
||
{};
// preload is called only once, after the view is in the DOM
if
(
!
view
.
preloaded
)
{
view
.
preload
(
current
.
ctx
);
view
.
preload
(
current
.
ctx
,
current
.
flags
);
view
.
preloaded
=
true
;
}
...
...
@@ -269,7 +314,7 @@
view
.
reset
();
// load the view
view
.
load
(
current
.
ctx
);
view
.
load
(
current
.
ctx
,
current
.
flags
);
}
// generate 'unique' id by prefixing view id
...
...
@@ -454,7 +499,7 @@
d3
.
selectAll
(
'.onosView'
).
call
(
setViewDimensions
);
// allow current view to react to resize event...
if
(
current
.
view
)
{
current
.
view
.
resize
(
current
.
ctx
);
current
.
view
.
resize
(
current
.
ctx
,
current
.
flags
);
}
}
...
...
@@ -521,13 +566,13 @@
}
},
preload
:
function
(
ctx
)
{
preload
:
function
(
ctx
,
flags
)
{
var
c
=
ctx
||
''
,
fn
=
isF
(
this
.
cb
.
preload
);
traceFn
(
'View.preload'
,
this
.
vid
+
', '
+
c
);
if
(
fn
)
{
trace
(
'PRELOAD cb for '
+
this
.
vid
);
fn
(
this
.
token
(),
c
);
fn
(
this
.
token
(),
c
,
flags
);
}
},
...
...
@@ -544,15 +589,14 @@
}
},
load
:
function
(
ctx
)
{
load
:
function
(
ctx
,
flags
)
{
var
c
=
ctx
||
''
,
fn
=
isF
(
this
.
cb
.
load
);
traceFn
(
'View.load'
,
this
.
vid
+
', '
+
c
);
this
.
$div
.
classed
(
'currentView'
,
true
);
// TODO: add radio button set, if needed
if
(
fn
)
{
trace
(
'LOAD cb for '
+
this
.
vid
);
fn
(
this
.
token
(),
c
);
fn
(
this
.
token
(),
c
,
flags
);
}
},
...
...
@@ -560,14 +604,13 @@
var
fn
=
isF
(
this
.
cb
.
unload
);
traceFn
(
'View.unload'
,
this
.
vid
);
this
.
$div
.
classed
(
'currentView'
,
false
);
// TODO: remove radio button set, if needed
if
(
fn
)
{
trace
(
'UNLOAD cb for '
+
this
.
vid
);
fn
(
this
.
token
());
}
},
resize
:
function
(
ctx
)
{
resize
:
function
(
ctx
,
flags
)
{
var
c
=
ctx
||
''
,
fn
=
isF
(
this
.
cb
.
resize
),
w
=
this
.
width
(),
...
...
@@ -576,7 +619,7 @@
' ['
+
w
+
'x'
+
h
+
']'
);
if
(
fn
)
{
trace
(
'RESIZE cb for '
+
this
.
vid
);
fn
(
this
.
token
(),
c
);
fn
(
this
.
token
(),
c
,
flags
);
}
},
...
...
web/gui/src/main/webapp/preamble.js
View file @
9254d96
...
...
@@ -21,12 +21,17 @@
*/
(
function
()
{
// NOTE: DON'T Want to do this.. we want to be able to
// use the parameter section, for example:
// #viewId,context?flag1,flag2,flag3
// Check if the URL in the address bar contains a parameter section
// (delineated by '?'). If this is the case, rewrite using '#' instead.
var
m
=
/
([^
?
]
*
)\?(
.*
)
/
.
exec
(
window
.
location
.
href
);
if
(
m
)
{
window
.
location
.
href
=
m
[
1
]
+
'#'
+
m
[
2
];
}
//
var m = /([^?]*)\?(.*)/.exec(window.location.href);
//
if (m) {
//
window.location.href = m[1] + '#' + m[2];
//
}
}());
...
...
web/gui/src/main/webapp/sampleHash.js
0 → 100644
View file @
9254d96
/*
* 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.
*/
/*
Sample view to illustrate hash formats.
@author Simon Hunt
*/
(
function
(
onos
)
{
'use strict'
;
var
intro
=
"Try using the following hashes in the address bar:"
,
hashPrefix
=
'#sampleHash'
,
suffixes
=
[
''
,
',one'
,
',two'
,
',context,ignored'
,
',context,ignored?a,b,c'
,
',two?foo'
,
',three?foo,bar'
],
$d
;
function
note
(
txt
)
{
$d
.
append
(
'p'
)
.
text
(
txt
)
.
style
({
'font-size'
:
'10pt'
,
color
:
'darkorange'
,
padding
:
'0 20px'
,
margin
:
0
});
}
function
para
(
txt
,
color
)
{
var
c
=
color
||
'black'
;
$d
.
append
(
'p'
)
.
text
(
txt
)
.
style
({
padding
:
'2px 8px'
,
color
:
c
});
}
function
load
(
view
,
ctx
,
flags
)
{
var
c
=
ctx
||
'(undefined)'
,
f
=
flags
?
d3
.
map
(
flags
).
keys
()
:
[];
$d
=
view
.
$div
;
para
(
intro
);
suffixes
.
forEach
(
function
(
s
)
{
note
(
hashPrefix
+
s
);
});
para
(
'View ID: '
+
view
.
vid
,
'blue'
);
para
(
'Context: '
+
c
,
'blue'
);
para
(
'Flags: { '
+
f
.
join
(
', '
)
+
' }'
,
'magenta'
);
}
// == register the view here, with links to lifecycle callbacks
onos
.
ui
.
addView
(
'sampleHash'
,
{
reset
:
true
,
// empty the div on reset
load
:
load
});
}(
ONOS
));
web/gui/src/main/webapp/topo2.css
View file @
9254d96
...
...
@@ -20,55 +20,64 @@
@author Simon Hunt
*/
svg
#topo-bg
{
#topo
svg
#topo-bg
{
opacity
:
0.5
;
}
/* NODES */
svg
.node.device
{
#topo
svg
.node.device
{
stroke
:
none
;
stroke-width
:
1.5px
;
cursor
:
pointer
;
}
svg
.node.device
rect
{
#topo
svg
.node.device
rect
{
stroke-width
:
1.5px
;
}
svg
.node.device.fixed
rect
{
#topo
svg
.node.device.fixed
rect
{
stroke-width
:
1.5
;
stroke
:
#ccc
;
}
svg
.node.device.switch
{
#topo
svg
.node.device.switch
{
fill
:
#17f
;
}
svg
.node.device.roadm
{
#topo
svg
.node.device.roadm
{
fill
:
#03c
;
}
svg
.node
text
{
#topo
svg
.node.host
{
fill
:
#846
;
}
#topo
svg
.node
text
{
stroke
:
none
;
fill
:
white
;
font
:
10pt
sans-serif
;
pointer-events
:
none
;
}
svg
.node.selected
rect
,
svg
.node.selected
circle
{
#topo
svg
.node.selected
rect
,
#topo
svg
.node.selected
circle
{
filter
:
url(#blue-glow)
;
}
/* LINKS */
svg
.link
{
#topo
svg
.link
{
opacity
:
.7
;
}
#topo
svg
.link.showPath
{
stroke
:
#f00
;
stroke-width
:
4px
;
}
/* for debugging */
svg
.node
circle
.debug
{
#topo
svg
.node
circle
.debug
{
fill
:
white
;
stroke
:
red
;
}
...
...
web/gui/src/main/webapp/topo2.js
View file @
9254d96
...
...
@@ -132,8 +132,21 @@
links
:
[],
lookup
:
{}
},
scenario
=
{
evDir
:
'json/ev/'
,
evScenario
:
'/scenario.json'
,
evPrefix
:
'/ev_'
,
evOnos
:
'_onos.json'
,
evUi
:
'_ui.json'
,
ctx
:
null
,
params
:
{},
evNumber
:
0
,
view
:
null
,
debug
:
false
},
webSock
,
labelIdx
=
0
,
deviceLabelIndex
=
0
,
hostLabelIndex
=
0
,
selectOrder
=
[],
selections
=
{},
...
...
@@ -155,10 +168,6 @@
// ==============================
// For Debugging / Development
var
eventPrefix
=
'json/eventTest_'
,
eventNumber
=
0
,
alertNumber
=
0
;
function
note
(
label
,
msg
)
{
console
.
log
(
'NOTE: '
+
label
+
': '
+
msg
);
}
...
...
@@ -175,32 +184,71 @@
view
.
alert
(
'test'
);
}
function
injectTestEvent
(
view
)
{
function
abortIfLive
(
)
{
if
(
config
.
useLiveData
)
{
view
.
alert
(
"Sorry, currently using live data.."
);
return
;
scenario
.
view
.
alert
(
"Sorry, currently using live data.."
);
return
true
;
}
return
false
;
}
eventNumber
++
;
var
eventUrl
=
eventPrefix
+
eventNumber
+
'.json'
;
function
testDebug
(
msg
)
{
if
(
scenario
.
debug
)
{
scenario
.
view
.
alert
(
msg
);
}
}
d3
.
json
(
eventUrl
,
function
(
err
,
data
)
{
function
injectTestEvent
(
view
)
{
if
(
abortIfLive
())
{
return
;
}
var
sc
=
scenario
,
evn
=
++
sc
.
evNumber
,
pfx
=
sc
.
evDir
+
sc
.
ctx
+
sc
.
evPrefix
+
evn
,
onosUrl
=
pfx
+
sc
.
evOnos
,
uiUrl
=
pfx
+
sc
.
evUi
;
tryOnosEvent
(
onosUrl
,
uiUrl
);
}
// TODO: tryOnosEvent/tryUiEvent folded into recursive function.
function
tryOnosEvent
(
onosUrl
,
uiUrl
)
{
var
v
=
scenario
.
view
;
d3
.
json
(
onosUrl
,
function
(
err
,
data
)
{
if
(
err
)
{
view
.
dataLoadError
(
err
,
eventUrl
);
if
(
err
.
status
===
404
)
{
tryUiEvent
(
uiUrl
);
}
else
{
v
.
alert
(
'non-404 error:\n\n'
+
onosUrl
+
'\n\n'
+
err
);
}
}
else
{
testDebug
(
'loaded: '
+
onosUrl
);
handleServerEvent
(
data
);
}
});
}
function
tryUiEvent
(
uiUrl
)
{
var
v
=
scenario
.
view
;
d3
.
json
(
uiUrl
,
function
(
err
,
data
)
{
if
(
err
)
{
v
.
alert
(
'Error:\n\n'
+
uiUrl
+
'\n\n'
+
err
.
status
+
': '
+
err
.
statusText
);
}
else
{
testDebug
(
'loaded: '
+
uiUrl
);
handleUiEvent
(
data
);
}
});
}
function
handleUiEvent
(
data
)
{
testDebug
(
'handleUiEvent(): '
+
data
.
event
);
// TODO:
}
function
injectStartupEvents
(
view
)
{
if
(
config
.
useLiveData
)
{
view
.
alert
(
"Sorry, currently using live data.."
);
return
;
}
var
last
=
scenario
.
params
.
lastAuto
||
0
;
if
(
abortIfLive
())
{
return
;
}
var
lastStartupEvent
=
32
;
while
(
eventNumber
<
lastStartupEvent
)
{
while
(
scenario
.
evNumber
<
last
)
{
injectTestEvent
(
view
);
}
}
...
...
@@ -211,14 +259,16 @@
}
function
cycleLabels
()
{
labelIdx
=
(
labelIdx
===
network
.
deviceLabelCount
-
1
)
?
0
:
labelId
x
+
1
;
deviceLabelIndex
=
(
deviceLabelIndex
===
network
.
deviceLabelCount
-
1
)
?
0
:
deviceLabelInde
x
+
1
;
function
niceLabel
(
label
)
{
return
(
label
&&
label
.
trim
())
?
label
:
'.'
;
}
network
.
nodes
.
forEach
(
function
(
d
)
{
var
idx
=
(
labelIdx
<
d
.
labels
.
length
)
?
labelIdx
:
0
,
if
(
d
.
class
!==
'device'
)
{
return
;
}
var
idx
=
(
deviceLabelIndex
<
d
.
labels
.
length
)
?
deviceLabelIndex
:
0
,
node
=
d3
.
select
(
'#'
+
safeId
(
d
.
id
)),
box
;
...
...
@@ -303,9 +353,14 @@
var
eventDispatch
=
{
addDevice
:
addDevice
,
updateDevice
:
updateDevice
,
removeDevice
:
removeDevice
,
updateDevice
:
stillToImplement
,
removeDevice
:
stillToImplement
,
addLink
:
addLink
,
updateLink
:
stillToImplement
,
removeLink
:
stillToImplement
,
addHost
:
addHost
,
updateHost
:
stillToImplement
,
removeHost
:
stillToImplement
,
showPath
:
showPath
};
...
...
@@ -320,18 +375,6 @@
network
.
force
.
start
();
}
function
updateDevice
(
data
)
{
var
device
=
data
.
payload
;
note
(
'updateDevice'
,
device
.
id
);
}
function
removeDevice
(
data
)
{
var
device
=
data
.
payload
;
note
(
'removeDevice'
,
device
.
id
);
}
function
addLink
(
data
)
{
var
link
=
data
.
payload
,
lnk
=
createLink
(
link
);
...
...
@@ -340,16 +383,57 @@
note
(
'addLink'
,
lnk
.
id
);
network
.
links
.
push
(
lnk
);
network
.
lookup
[
lnk
.
id
]
=
lnk
;
updateLinks
();
network
.
force
.
start
();
}
}
function
addHost
(
data
)
{
var
host
=
data
.
payload
,
node
=
createHostNode
(
host
),
lnk
;
note
(
'addHost'
,
node
.
id
);
network
.
nodes
.
push
(
node
);
network
.
lookup
[
host
.
id
]
=
node
;
updateNodes
();
lnk
=
createHostLink
(
host
);
if
(
lnk
)
{
network
.
links
.
push
(
lnk
);
network
.
lookup
[
host
.
ingress
]
=
lnk
;
network
.
lookup
[
host
.
egress
]
=
lnk
;
updateLinks
();
}
network
.
force
.
start
();
}
function
showPath
(
data
)
{
network
.
view
.
alert
(
data
.
event
+
"\n"
+
data
.
payload
.
links
.
length
);
var
links
=
data
.
payload
.
links
,
s
=
[
data
.
event
+
"\n"
+
links
.
length
];
links
.
forEach
(
function
(
d
,
i
)
{
s
.
push
(
d
);
});
network
.
view
.
alert
(
s
.
join
(
'\n'
));
links
.
forEach
(
function
(
d
,
i
)
{
var
link
=
network
.
lookup
[
d
];
if
(
link
)
{
d3
.
select
(
'#'
+
link
.
svgId
).
classed
(
'showPath'
,
true
);
}
});
// TODO: add selection-highlite lines to links
}
// ....
// ...............................
function
stillToImplement
(
data
)
{
var
p
=
data
.
payload
;
note
(
data
.
event
,
p
.
id
);
//network.view.alert('Not yet implemented: "' + data.event + '"');
}
function
unknownEvent
(
data
)
{
network
.
view
.
alert
(
'Unknown event type: "'
+
data
.
event
+
'"'
);
...
...
@@ -367,10 +451,42 @@
return
'translate('
+
x
+
','
+
y
+
')'
;
}
function
createHostLink
(
host
)
{
var
src
=
host
.
id
,
dst
=
host
.
cp
.
device
,
id
=
host
.
id
,
srcNode
=
network
.
lookup
[
src
],
dstNode
=
network
.
lookup
[
dst
],
lnk
;
if
(
!
dstNode
)
{
// TODO: send warning message back to server on websocket
network
.
view
.
alert
(
'switch not on map for link\n\n'
+
'src = '
+
src
+
'\ndst = '
+
dst
);
return
null
;
}
lnk
=
{
svgId
:
safeId
(
src
)
+
'-'
+
safeId
(
dst
),
id
:
id
,
source
:
srcNode
,
target
:
dstNode
,
class
:
'link'
,
svgClass
:
'link hostLink'
,
x1
:
srcNode
.
x
,
y1
:
srcNode
.
y
,
x2
:
dstNode
.
x
,
y2
:
dstNode
.
y
,
width
:
1
};
return
lnk
;
}
function
createLink
(
link
)
{
var
type
=
link
.
type
,
src
=
link
.
src
,
dst
=
link
.
dst
,
id
=
link
.
id
,
w
=
link
.
linkWidth
,
srcNode
=
network
.
lookup
[
src
],
dstNode
=
network
.
lookup
[
dst
],
...
...
@@ -384,7 +500,8 @@
}
lnk
=
{
id
:
safeId
(
src
)
+
'~'
+
safeId
(
dst
),
svgId
:
safeId
(
src
)
+
'-'
+
safeId
(
dst
),
id
:
id
,
source
:
srcNode
,
target
:
dstNode
,
class
:
'link'
,
...
...
@@ -415,7 +532,7 @@
var
entering
=
link
.
enter
()
.
append
(
'line'
)
.
attr
({
id
:
function
(
d
)
{
return
d
.
i
d
;
},
id
:
function
(
d
)
{
return
d
.
svgI
d
;
},
class
:
function
(
d
)
{
return
d
.
svgClass
;
},
x1
:
function
(
d
)
{
return
d
.
x1
;
},
y1
:
function
(
d
)
{
return
d
.
y1
;
},
...
...
@@ -433,6 +550,19 @@
// augment links
// TODO: add src/dst port labels etc.
// operate on both existing and new links, if necessary
//link .foo() .bar() ...
// operate on exiting links:
// TODO: figure out how to remove the node 'g' AND its children
link
.
exit
()
.
transition
()
.
duration
(
750
)
.
attr
({
opacity
:
0
})
.
remove
();
}
function
createDeviceNode
(
device
)
{
...
...
@@ -451,6 +581,22 @@
return
node
;
}
function
createHostNode
(
host
)
{
// start with the object as is
var
node
=
host
;
// Augment as needed...
node
.
class
=
'host'
;
node
.
svgClass
=
'node host'
;
// TODO: consider placing near its switch, if [x,y] not defined
positionNode
(
node
);
// cache label array length
network
.
hostLabelCount
=
host
.
labels
.
length
;
return
node
;
}
function
positionNode
(
node
)
{
var
meta
=
node
.
metaUi
,
x
=
0
,
...
...
@@ -525,7 +671,7 @@
entering
.
filter
(
'.device'
).
each
(
function
(
d
)
{
var
node
=
d3
.
select
(
this
),
icon
=
iconUrl
(
d
),
idx
=
(
labelIdx
<
d
.
labels
.
length
)
?
labelId
x
:
0
,
idx
=
(
deviceLabelIndex
<
d
.
labels
.
length
)
?
deviceLabelInde
x
:
0
,
box
;
node
.
append
(
'rect'
)
...
...
@@ -568,6 +714,32 @@
}
});
// augment host nodes...
entering
.
filter
(
'.host'
).
each
(
function
(
d
)
{
var
node
=
d3
.
select
(
this
),
idx
=
(
hostLabelIndex
<
d
.
labels
.
length
)
?
hostLabelIndex
:
0
,
box
;
node
.
append
(
'circle'
)
.
attr
(
'r'
,
8
);
// TODO: define host circle radius
// TODO: are we attaching labels to hosts?
node
.
append
(
'text'
)
.
text
(
d
.
labels
[
idx
])
.
attr
(
'dy'
,
'1.1em'
);
// debug function to show the modelled x,y coordinates of nodes...
if
(
debug
(
'showNodeXY'
))
{
node
.
select
(
'circle'
).
attr
(
'fill-opacity'
,
0.5
);
node
.
append
(
'circle'
)
.
attr
({
class
:
'debug'
,
cx
:
0
,
cy
:
0
,
r
:
'3px'
});
}
});
// operate on both existing and new nodes, if necessary
//node .foo() .bar() ...
...
...
@@ -618,7 +790,6 @@
webSock
.
ws
=
new
WebSocket
(
webSockUrl
());
webSock
.
ws
.
onopen
=
function
()
{
webSock
.
_send
(
"Hi there!"
);
};
webSock
.
ws
.
onmessage
=
function
(
m
)
{
...
...
@@ -643,7 +814,7 @@
if
(
webSock
.
ws
)
{
webSock
.
ws
.
send
(
message
);
}
else
{
network
.
view
.
alert
(
'no web socket open
'
);
network
.
view
.
alert
(
'no web socket open
\n\n'
+
message
);
}
}
...
...
@@ -714,7 +885,7 @@
//flyinPane(null);
}
// TODO: this click handler does not get unloaded when the view does
$
(
'#view'
).
on
(
'click'
,
function
(
e
)
{
if
(
!
$
(
e
.
target
).
closest
(
'.node'
).
length
)
{
if
(
!
e
.
metaKey
)
{
...
...
@@ -723,6 +894,33 @@
}
});
function
prepareScenario
(
view
,
ctx
,
dbg
)
{
var
sc
=
scenario
,
urlSc
=
sc
.
evDir
+
ctx
+
sc
.
evScenario
;
if
(
!
ctx
)
{
view
.
alert
(
"No scenario specified (null ctx)"
);
return
;
}
sc
.
view
=
view
;
sc
.
ctx
=
ctx
;
sc
.
debug
=
dbg
;
sc
.
evNumber
=
0
;
d3
.
json
(
urlSc
,
function
(
err
,
data
)
{
var
p
=
data
&&
data
.
params
||
{};
if
(
err
)
{
view
.
alert
(
'No scenario found:\n\n'
+
urlSc
+
'\n\n'
+
err
);
}
else
{
sc
.
params
=
p
;
view
.
alert
(
"Scenario loaded: "
+
ctx
+
'\n\n'
+
data
.
title
);
}
});
}
// ==============================
// View life-cycle callbacks
...
...
@@ -767,10 +965,12 @@
node
=
nodeG
.
selectAll
(
'.node'
);
function
ldist
(
d
)
{
return
fcfg
.
linkDistance
[
d
.
class
]
||
150
;
return
2
*
30
;
//return fcfg.linkDistance[d.class] || 150;
}
function
lstrg
(
d
)
{
return
fcfg
.
linkStrength
[
d
.
class
]
||
1
;
return
2
*
0.6
;
//return fcfg.linkStrength[d.class] || 1;
}
function
lchrg
(
d
)
{
return
fcfg
.
charge
[
d
.
class
]
||
-
200
;
...
...
@@ -781,14 +981,11 @@
}
function
atDragEnd
(
d
,
self
)
{
// once we've finished moving, pin the node in position,
// if it is a device (not a host)
if
(
d
.
class
===
'device'
)
{
d
.
fixed
=
true
;
d3
.
select
(
self
).
classed
(
'fixed'
,
true
);
if
(
config
.
useLiveData
)
{
tellServerCoords
(
d
);
}
// once we've finished moving, pin the node in position
d
.
fixed
=
true
;
d3
.
select
(
self
).
classed
(
'fixed'
,
true
);
if
(
config
.
useLiveData
)
{
tellServerCoords
(
d
);
}
}
...
...
@@ -806,17 +1003,34 @@
.
size
(
forceDim
)
.
nodes
(
network
.
nodes
)
.
links
(
network
.
links
)
.
charge
(
lchrg
)
.
gravity
(
0.3
)
.
charge
(
-
15000
)
.
friction
(
0.1
)
//.charge(lchrg)
.
linkDistance
(
ldist
)
.
linkStrength
(
lstrg
)
.
on
(
'tick'
,
tick
);
// TVUE
//.gravity(0.3)
//.charge(-15000)
//.friction(0.1)
//.linkDistance(function(d) { return d.value * 30; })
//.linkStrength(function(d) { return d.value * 0.6; })
//.size([w, h])
//.start();
network
.
drag
=
d3u
.
createDragBehavior
(
network
.
force
,
selectCb
,
atDragEnd
);
}
function
load
(
view
,
ctx
)
{
function
load
(
view
,
ctx
,
flags
)
{
// cache the view token, so network topo functions can access it
network
.
view
=
view
;
config
.
useLiveData
=
!
flags
.
local
;
if
(
!
config
.
useLiveData
)
{
prepareScenario
(
view
,
ctx
,
flags
.
debug
);
}
// set our radio buttons and key bindings
view
.
setRadio
(
btnSet
);
...
...
Please
register
or
login
to post a comment