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
tom
2014-09-12 15:53:42 -0700
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
4009d2c55b9b73d5611c71fed39fa1863415ada6
4009d2c5
1 parent
0b11b746
Adding a sample GUI page to visualize topology.
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
368 additions
and
8 deletions
apps/tvue/pom.xml
apps/tvue/src/main/java/org/onlab/onos/tvue/TopologyResource.java
apps/tvue/src/main/webapp/WEB-INF/web.xml
apps/tvue/src/main/webapp/index.html
features/features.xml
apps/tvue/pom.xml
View file @
4009d2c
...
...
@@ -11,7 +11,7 @@
<relativePath>
../pom.xml
</relativePath>
</parent>
<artifactId>
onos-tvue
</artifactId>
<artifactId>
onos-
app-
tvue
</artifactId>
<packaging>
bundle
</packaging>
<description>
ONOS simple topology viewer
</description>
...
...
apps/tvue/src/main/java/org/onlab/onos/tvue/TopologyResource.java
View file @
4009d2c
...
...
@@ -100,7 +100,7 @@ public class TopologyResource extends BaseResource {
private
ObjectNode
json
(
ObjectMapper
mapper
,
ElementId
id
,
int
group
,
boolean
isOnline
)
{
return
mapper
.
createObjectNode
()
.
put
(
"name"
,
id
.
uri
().
toString
())
.
put
(
"name"
,
id
.
uri
().
getSchemeSpecificPart
())
.
put
(
"group"
,
group
)
.
put
(
"online"
,
isOnline
);
}
...
...
@@ -147,7 +147,7 @@ public class TopologyResource extends BaseResource {
// Returns a formatted string for the element associated with the given
// connection point.
private
static
String
id
(
ConnectPoint
cp
)
{
return
cp
.
elementId
().
uri
().
toString
();
return
cp
.
elementId
().
uri
().
getSchemeSpecificPart
();
}
}
...
...
apps/tvue/src/main/webapp/WEB-INF/web.xml
View file @
4009d2c
...
...
@@ -14,7 +14,7 @@
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>
com.sun.jersey.config.property.packages
</param-name>
<param-value>
org.onlab.onos.
gui
</param-value>
<param-value>
org.onlab.onos.
tvue
</param-value>
</init-param>
<load-on-startup>
1
</load-on-startup>
</servlet>
...
...
apps/tvue/src/main/webapp/index.html
View file @
4009d2c
<!DOCTYPE html>
<html>
<head>
<title>
ONOS GUI
</title>
<title>
Topology Viewer
</title>
<script
src=
"libs/d3.v3.min.js"
></script>
<script
src=
"libs/jquery-1.11.1.min.js"
></script>
<style>
.link
{
}
.node
{
stroke-width
:
3px
;
}
.textClass
{
stroke
:
#323232
;
font-family
:
"Lucida Grande"
,
"Droid Sans"
,
Arial
,
Helvetica
,
sans-serif
;
font-weight
:
normal
;
stroke-width
:
.5
;
font-size
:
14px
;
}
</style>
</head>
<body>
<h1>
ONOS GUI
</h1>
Sort of...
<script>
// Adapted from sample code @ ericcoopey’s block #6c602d7cb14b25c179a4
// by Thomas Vachuska
var
graph
,
topo
=
{
vertexes
:{},
edges
:{}},
paths
=
[],
currentPath
=
0
;
// Set up the canvas
var
w
=
2048
,
h
=
2048
;
// Allocate colors predictably
var
color
=
d3
.
scale
.
category10
(),
deviceColor
=
color
(
2
),
sourceColor
=
color
(
0
),
targetColor
=
color
(
1
),
dummy1Color
=
color
(
9
),
dummy2Color
=
color
(
8
),
dummy3Color
=
color
(
7
),
dummy4Color
=
color
(
6
),
offlineColor
=
color
(
5
),
dummy5Color
=
color
(
4
),
hostColor
=
color
(
3
);
var
selectedNode
,
sourceNode
,
targetNode
,
pathRequested
;
function
fillColor
(
d
)
{
return
((
targetNode
&&
targetNode
.
id
==
d
.
id
)
?
targetColor
:
((
sourceNode
&&
sourceNode
.
id
==
d
.
id
)
?
sourceColor
:
d
.
online
?
color
(
d
.
group
)
:
offlineColor
));
}
function
strokeColor
(
d
)
{
return
selectedNode
&&
d
.
id
==
selectedNode
.
id
?
"#f00"
:
"#aaa"
;
}
function
linkColor
(
d
)
{
if
(
!
paths
||
paths
.
length
==
0
)
{
return
"#666"
;
}
var
path
=
paths
[
currentPath
];
if
(
path
)
{
for
(
var
i
=
0
,
n
=
path
.
length
;
i
<
n
;
i
++
)
{
var
link
=
path
[
i
];
if
((
link
.
src
==
d
.
source
.
id
||
link
.
dst
==
d
.
source
.
id
)
&&
(
link
.
dst
==
d
.
target
.
id
||
link
.
src
==
d
.
target
.
id
))
{
return
"#f00"
;
}
}
}
return
"#666"
;
}
function
linkKey
(
link
)
{
return
link
.
source
.
id
+
"-"
+
link
.
target
.
id
;
};
function
toggleNode
(
node
)
{
pathRequested
=
false
;
return
selectedNode
&&
selectedNode
!=
node
?
selectedNode
:
null
;
};
function
refreshPaths
()
{
d3
.
selectAll
(
"line"
).
attr
(
"stroke"
,
linkColor
);
}
function
fetchPaths
()
{
if
(
!
pathRequested
&&
sourceNode
&&
targetNode
)
{
pathRequested
=
true
;
d3
.
json
(
"rs/topology/paths/"
+
sourceNode
.
id
+
"/"
+
targetNode
.
id
,
function
(
error
,
data
)
{
currentPath
=
0
;
paths
=
data
.
paths
;
refreshPaths
();
});
}
}
function
resetSelections
()
{
selectedNode
=
null
;
sourceNode
=
null
;
targetNode
=
null
;
paths
=
[];
currentPath
=
0
;
refreshPaths
();
d3
.
selectAll
(
".nodeStrokeClass"
).
attr
(
"stroke"
,
strokeColor
);
}
function
nextPath
()
{
currentPath
=
paths
&&
currentPath
<
paths
.
length
-
1
?
currentPath
+
1
:
0
console
.
log
(
"Showing path: "
+
currentPath
);
refreshPaths
();
}
function
dblclick
(
d
)
{
d3
.
select
(
this
).
classed
(
"fixed"
,
d
.
fixed
=
false
);
}
function
dragstart
(
d
)
{
d3
.
select
(
this
).
classed
(
"fixed"
,
d
.
fixed
=
true
);
}
function
topoGraph
()
{
// Add and remove elements on the graph object
this
.
addNode
=
function
(
vertex
,
stamp
)
{
var
node
=
topo
.
vertexes
[
vertex
.
name
];
if
(
node
)
{
var
oldState
=
node
.
online
;
node
.
online
=
vertex
.
online
;
node
.
stamp
=
stamp
;
if
(
oldState
!=
node
.
online
)
{
update
();
return
true
;
}
return
false
;
}
node
=
{
"id"
:
vertex
.
name
,
"group"
:
vertex
.
group
,
"online"
:
vertex
.
online
,
"stamp"
:
stamp
};
nodes
.
push
(
node
);
topo
.
vertexes
[
vertex
.
name
]
=
node
;
update
();
return
true
;
};
this
.
addLink
=
function
(
edge
,
stamp
)
{
var
key
=
edge
.
source
+
"-"
+
edge
.
target
;
var
link
=
topo
.
edges
[
key
];
if
(
link
)
{
var
oldValue
=
link
.
value
;
link
.
value
=
edge
.
value
;
link
.
stamp
=
stamp
;
if
(
oldValue
!=
link
.
value
)
{
update
();
return
true
;
}
return
false
;
}
link
=
{
"source"
:
findNode
(
edge
.
source
),
"target"
:
findNode
(
edge
.
target
),
"value"
:
edge
.
value
,
"stamp"
:
stamp
};
links
.
push
(
link
);
topo
.
edges
[
key
]
=
link
;
update
();
return
true
;
};
this
.
prune
=
function
(
stamp
)
{
var
linksChanged
=
pruneArray
(
links
,
stamp
,
topo
.
edges
,
linkKey
);
var
nodesChanged
=
pruneArray
(
nodes
,
stamp
,
topo
.
vertexes
,
function
(
node
)
{
return
node
.
id
;
});
if
(
linksChanged
||
nodesChanged
)
{
update
();
return
true
;
}
return
false
;
};
var
pruneArray
=
function
(
array
,
stamp
,
map
,
key
)
{
var
changed
=
false
;
for
(
var
i
=
0
;
i
<
array
.
length
;
i
++
)
{
if
(
array
[
i
].
stamp
<
stamp
)
{
changed
=
true
;
map
[
key
(
array
[
i
])]
=
null
;
array
.
splice
(
i
,
1
);
i
--
;
}
}
return
changed
;
};
var
findNode
=
function
(
id
)
{
for
(
var
i
in
nodes
)
{
if
(
nodes
[
i
][
"id"
]
===
id
)
return
nodes
[
i
];
}
};
var
force
=
d3
.
layout
.
force
();
var
drag
=
force
.
drag
()
.
on
(
"dragstart"
,
dragstart
);
var
nodes
=
force
.
nodes
(),
links
=
force
.
links
();
var
vis
=
d3
.
select
(
"body"
)
.
append
(
"svg:svg"
)
.
attr
(
"width"
,
w
)
.
attr
(
"height"
,
h
)
.
attr
(
"id"
,
"svg"
)
.
attr
(
"pointer-events"
,
"all"
)
.
attr
(
"viewBox"
,
"0 0 "
+
w
+
" "
+
h
)
.
attr
(
"perserveAspectRatio"
,
"xMinYMid"
)
.
append
(
'svg:g'
);
d3
.
select
(
"body"
)
.
on
(
"keydown"
,
function
(
d
)
{
console
.
log
(
d3
.
event
.
keyCode
);
if
(
d3
.
event
.
keyCode
==
27
)
{
resetSelections
();
}
else
if
(
d3
.
event
.
keyCode
==
83
)
{
sourceNode
=
toggleNode
(
sourceNode
);
}
else
if
(
d3
.
event
.
keyCode
==
68
)
{
targetNode
=
toggleNode
(
targetNode
);
}
else
if
(
d3
.
event
.
keyCode
==
65
)
{
var
aux
=
sourceNode
;
sourceNode
=
targetNode
;
targetNode
=
aux
;
}
else
if
(
d3
.
event
.
keyCode
==
70
)
{
nextPath
();
}
d3
.
selectAll
(
".nodeStrokeClass"
).
attr
(
"fill"
,
fillColor
);
fetchPaths
();
});
var
update
=
function
()
{
var
link
=
vis
.
selectAll
(
"line"
)
.
data
(
links
,
linkKey
);
link
.
enter
().
append
(
"line"
)
.
attr
(
"id"
,
linkKey
)
.
attr
(
"class"
,
"link"
)
.
attr
(
"stroke-width"
,
function
(
d
)
{
return
d
.
value
;
})
.
attr
(
"stroke"
,
linkColor
);
link
.
append
(
"title"
).
text
(
function
(
d
)
{
return
d
.
id
;
});
link
.
exit
().
remove
();
var
node
=
vis
.
selectAll
(
"g.node"
)
.
data
(
nodes
,
function
(
d
)
{
return
d
.
id
;
})
.
on
(
"click"
,
function
(
d
)
{
selectedNode
=
d
;
d3
.
selectAll
(
".nodeStrokeClass"
).
attr
(
"stroke"
,
strokeColor
);
});
var
nodeEnter
=
node
.
enter
().
append
(
"g"
)
.
attr
(
"class"
,
"node"
)
.
on
(
"dblclick"
,
dblclick
)
.
call
(
force
.
drag
);
nodeEnter
.
append
(
"svg:circle"
)
.
attr
(
"r"
,
function
(
d
)
{
return
28
/
2
;
})
.
attr
(
"id"
,
function
(
d
)
{
return
"n-"
+
d
.
id
.
replace
(
/
[
.:
]
/g
,
""
);
})
.
attr
(
"class"
,
"nodeStrokeClass"
)
.
attr
(
"fill"
,
fillColor
)
.
attr
(
"stroke"
,
strokeColor
);
nodeEnter
.
append
(
"image"
)
.
attr
(
"xlink:href"
,
function
(
d
)
{
return
d
.
group
==
2
?
"images/switch.png"
:
"images/server.png"
;
})
.
attr
(
"x"
,
-
12
)
.
attr
(
"y"
,
-
12
)
.
attr
(
"width"
,
24
)
.
attr
(
"height"
,
24
);
nodeEnter
.
append
(
"svg:text"
)
.
attr
(
"class"
,
"textClass"
)
.
attr
(
"x"
,
20
)
.
attr
(
"y"
,
".31em"
)
.
text
(
function
(
d
)
{
return
d
.
id
;
});
node
.
exit
().
remove
();
d3
.
selectAll
(
"nodeStrokeClass"
).
attr
(
"stroke"
,
strokeColor
);
force
.
on
(
"tick"
,
function
()
{
node
.
attr
(
"transform"
,
function
(
d
)
{
return
"translate("
+
d
.
x
+
","
+
d
.
y
+
")"
;
});
link
.
attr
(
"x1"
,
function
(
d
)
{
return
d
.
source
.
x
;
})
.
attr
(
"y1"
,
function
(
d
)
{
return
d
.
source
.
y
;
})
.
attr
(
"x2"
,
function
(
d
)
{
return
d
.
target
.
x
;
})
.
attr
(
"y2"
,
function
(
d
)
{
return
d
.
target
.
y
;
});
});
// Restart the force layout.
force
.
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
();
};
// Make it all go
update
();
}
function
drawGraph
()
{
graph
=
new
topoGraph
(
"#svgdiv"
);
bringNodesToFront
();
}
function
bringNodesToFront
()
{
$
(
".nodeStrokeClass"
).
each
(
function
(
index
)
{
var
gnode
=
this
.
parentNode
;
gnode
.
parentNode
.
appendChild
(
gnode
);
});
}
function
addNodes
()
{
d3
.
select
(
"svg"
)
.
remove
();
drawGraph
();
}
function
fetchData
()
{
var
stamp
=
new
Date
().
getTime
();
d3
.
json
(
"rs/topology/graph"
,
function
(
error
,
data
)
{
var
changed
=
false
;
data
.
vertexes
.
forEach
(
function
(
vertex
)
{
changed
=
graph
.
addNode
(
vertex
,
stamp
)
||
changed
;
});
data
.
edges
.
forEach
(
function
(
edge
)
{
changed
=
graph
.
addLink
(
edge
,
stamp
)
||
changed
;
});
changed
=
graph
.
prune
(
stamp
)
||
changed
;
if
(
changed
)
{
bringNodesToFront
();
// Update node and links styles
d3
.
selectAll
(
".nodeStrokeClass"
).
attr
(
"fill"
,
fillColor
);
d3
.
selectAll
(
".line"
).
attr
(
"stroke-width"
,
function
(
d
)
{
return
d
.
value
;
})
}
setTimeout
(
fetchData
,
1000
);
});
};
drawGraph
();
setTimeout
(
fetchData
,
500
);
</script>
</body>
</html>
\ No newline at end of file
...
...
features/features.xml
View file @
4009d2c
...
...
@@ -62,7 +62,6 @@
<feature>
onos-core
</feature>
<bundle>
mvn:io.netty/netty/3.9.2.Final
</bundle>
<!--bundle>mvn:org.projectfloodlight/openflowj/0.3.8-SNAPSHOT</bundle-->
<bundle>
mvn:org.onlab.onos/onos-of-api/1.0.0-SNAPSHOT
</bundle>
<bundle>
mvn:org.onlab.onos/onos-of-ctl/1.0.0-SNAPSHOT
</bundle>
...
...
@@ -71,4 +70,10 @@
<bundle>
mvn:org.onlab.onos/onos-of-provider-host/1.0.0-SNAPSHOT
</bundle>
</feature>
<feature
name=
"onos-app-tvue"
version=
"1.0.0"
description=
"ONOS sample topology viewer application"
>
<feature>
onos-core
</feature>
<bundle>
mvn:org.onlab.onos/onos-app-tvue/1.0.0-SNAPSHOT
</bundle>
</feature>
</features>
...
...
Please
register
or
login
to post a comment