Improvement In 'show router port', added 'show router adjacency', renamed some diplay name in CLI
diff --git a/cli/cli/c_actions.py b/cli/cli/c_actions.py
index 4346af9..fd741e0 100755
--- a/cli/cli/c_actions.py
+++ b/cli/cli/c_actions.py
@@ -172,6 +172,20 @@
if data != "deleted":
result = json.loads(data)
return result
+
+
+
+ if not detail:
+ detail = data.get('detail', 'default')
+ url = "http://%s/rest/v1/" % sdnsh.controller + (select_url % data)
+
+ result = sdnsh.store.rest_simple_request(url)
+ check_rest_result(result)
+ if sdnsh.description: # description debugging
+ print "command_display_rest: result ", result
+ entries = json.loads(result)
+
+
def write_fields(obj_type, obj_id, data):
"""
@@ -2092,6 +2106,8 @@
# It certainly seems possible to map from url's to the type associated,
# with the result, but it also makes sense to encode that type information
# into the description
+ if 'routerrealtimestats' in data and data['routerrealtimestats'] == 'adjacency':
+ rest_type =False
if rest_type:
entries = command_display_rest_type_converter(table_format,
rest_type,
@@ -2128,13 +2144,29 @@
name = portData.get("stringAttributes").get('name')
portNo = portData.get("portNumber")
subnetIp = port.get("subnetIp")
+ adjacency = str(port.get('adjacency'))
combResult.append({
'name' :name,
'portNo' : portNo,
'subnetIp' : subnetIp,
+ 'adjacency' : adjacency,
+ })
+ entries = combResult
+ if 'routerrealtimestats' in data and data['routerrealtimestats'] == 'adjacency':
+ #raise error.ArgumentValidationError('\n\n\n %s' % (entries))
+ #raise error.ArgumentValidationError('\n\n\n %s' % (entries))
+ combResult = []
+ adjacencyPairList = entries
+ for adjacencyPair in adjacencyPairList:
+ adjacencySid = adjacencyPair.get("adjacencySid")
+ ports = adjacencyPair.get("ports")
+ combResult.append({
+ 'adjacencySid' : adjacencySid,
+ 'ports' : ports,
})
entries = combResult
#raise error.ArgumentValidationError('\n\n\n %s' % (data))
+
if 'showtunnel' in data and (data['showtunnel'] == 'tunnel' or data['detail'] == 'details'):
#eraise error.ArgumentValidationError('\n\n\n %s' % (entries))
combResult = []
diff --git a/cli/cli/desc/version200/core.py b/cli/cli/desc/version200/core.py
index 6a9f3e9..26c6fdb 100755
--- a/cli/cli/desc/version200/core.py
+++ b/cli/cli/desc/version200/core.py
@@ -2422,11 +2422,13 @@
},
'dpidGroup' : { 'verbose-name' : 'dpid/Group',
},
+ 'labelStack' : { 'verbose-name' : 'Label Stack',
+ },
}
},
}
-SHOW_POLICYL_FORMAT = {
+SHOW_POLICY_FORMAT = {
'show_policy' : {
'field-orderings' : {
'default' : [ 'Idx', 'policyId', 'policyType','priority','dstMacAddress','srcMacAddress',
@@ -2434,6 +2436,12 @@
'etherType', 'ipProtocolNumber',
]
},
+ 'fields': {
+ 'policyId' : { 'verbose-name' : 'Policy Id',
+ },
+ 'policyType' : { 'verbose-name': 'Policy Type',
+ },
+ }
},
}
@@ -2532,40 +2540,59 @@
],
},
'fields': {
- 'dpid' : { 'verbose-name' : 'RouterDPID',
+ 'dpid' : { 'verbose-name' : 'Router DPID',
#'formatter' : fmtcnv.replace_switch_with_alias
},
- 'name' : { 'verbose-name' : 'RouterName',
+ 'name' : { 'verbose-name' : 'Router Name',
#'formatter' : fmtcnv.decode_port_counter
},
- 'routerIP' : { 'verbose-name' : 'RouterIP',
+ 'routerIP' : { 'verbose-name' : 'Router IP',
},
- 'routerMac' : { 'verbose-name' : 'RouterMac',
+ 'routerMac' : { 'verbose-name' : 'Router Mac',
#'formatter' : fmtcnv.decode_port_counter
},
- 'isEdgeRouter' : { 'verbose-name' : 'isEdgeRouter',
+ 'isEdgeRouter' : { 'verbose-name' : 'Edge Router',
#'formatter' : fmtcnv.decode_port_counter
},
- 'nodeSId' : { 'verbose-name' : 'nodeSId',
+ 'nodeSId' : { 'verbose-name' : 'Node SId',
#'formatter' : fmtcnv.decode_port_counter
},
}
},
}
+#adjacency
+ROUTER_ADJACENCY_FORMAT= {
+ 'router_adjacency' : {
+ 'field-orderings' : {
+ 'default' : [ 'Idx', 'adjacencySid', 'ports'],
+ 'scoped' : [ 'Idx', 'adjacencySid', 'ports'],
+ },
+ 'fields': {
+ 'adjacencySid' : { 'verbose-name' : 'Adjacency Sid(s)',
+ },
+
+ },
+
+ },
+}
ROUTER_PORT_FORMAT = {
'router_port' : {
'field-orderings' : {
- 'default' : [ 'Idx', 'name', 'portNo', 'subnetIp','adjacencySid'],
- 'scoped' : [ 'Idx', 'name', 'portNo', 'subnetIp','adjacencySid'],
+ 'default' : [ 'Idx', 'name', 'portNo', 'subnetIp','adjacency'],
+ 'scoped' : [ 'Idx', 'name', 'portNo', 'subnetIp','adjacency'],
},
- #'fields': {
- # 'switch' : { 'verbose-name' : 'Switch',
- # 'formatter' : fmtcnv.replace_switch_with_alias
- # },
+ 'fields': {
+ 'adjacency' : { 'verbose-name' : 'Adjacency Sid(s)',
+ },
+ 'portNo' : { 'verbose-name' : 'Port #',
+ },
+ 'subnetIp' : { 'verbose-name' : 'Subnet',
+ },
},
+ }
}
"""
diff --git a/cli/cli/desc/version200/router.py b/cli/cli/desc/version200/router.py
index f8e14bb..57bc3bc 100644
--- a/cli/cli/desc/version200/router.py
+++ b/cli/cli/desc/version200/router.py
@@ -77,12 +77,12 @@
'field' : 'routerrealtimestats',
'type' : 'enum',
'values' : (
- 'port',
+ 'port', 'adjacency'
),
'action' : 'display-rest',
'url' : 'router/%(dpid)s/%(routerrealtimestats)s',
'rest-type' : 'dict-of-list-of-switch',
- 'format' : 'router_port',
+ 'format' : 'router_%(routerrealtimestats)s',
'short-help' : 'Show requested item by querying router/switch',
'doc' : 'switch|realtime-+',
},
diff --git a/conf/onos.properties b/conf/onos.properties
index a3e1d19..89b4c80 100644
--- a/conf/onos.properties
+++ b/conf/onos.properties
@@ -23,4 +23,4 @@
# Uncomment and list all the ZooKeeper instances after localhost on multi-instance deployment.
#net.onrc.onos.core.registry.ZookeeperRegistry.connectionString = localhost:2181,otherhost:2181
# Specify a network configuration file to be used by the NetworkConfigManager
-net.onrc.onos.core.configmanager.NetworkConfigManager.networkConfigFile = conf/sr-ecmp.conf
+net.onrc.onos.core.configmanager.NetworkConfigManager.networkConfigFile = conf/sr-ecmp10.conf
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/ISegmentRoutingService.java b/src/main/java/net/onrc/onos/apps/segmentrouting/ISegmentRoutingService.java
index 44411cd..61ec630 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/ISegmentRoutingService.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/ISegmentRoutingService.java
@@ -1,6 +1,7 @@
package net.onrc.onos.apps.segmentrouting;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
import net.floodlightcontroller.core.module.IFloodlightService;
@@ -83,4 +84,18 @@
* @return Collection<PolicyInfo>
*/
public Collection<PolicyInfo> getPoclicyTable();
+ /**
+ * Returns the Adjacency Info for the node
+ *
+ * @param nodeSid Node SID
+ * @return HashMap of <AdjacencyID, list of ports>
+ */
+ public HashMap<Integer, List<Integer>> getAdjacencyInfo(int nodeSid);
+ /**
+ * Returns the Adjacency IDs for the node
+ *
+ * @param nodeSid Node SID
+ * @return Collection of Adjacency ID
+ */
+ public Collection<Integer> getAdjacencyIds(int nodeSid);
}
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/web/RouterStatisticsResource.java b/src/main/java/net/onrc/onos/apps/segmentrouting/web/RouterStatisticsResource.java
deleted file mode 100644
index 00c2f15..0000000
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/web/RouterStatisticsResource.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package net.onrc.onos.apps.segmentrouting.web;
-
-
-
-import static net.onrc.onos.core.topology.web.TopologyResource.eval;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import net.onrc.onos.core.topology.ITopologyService;
-import net.onrc.onos.core.topology.MutableTopology;
-import net.onrc.onos.core.topology.Port;
-import net.onrc.onos.core.topology.Switch;
-import net.onrc.onos.core.util.Dpid;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONObject;
-
-import org.projectfloodlight.openflow.util.HexString;
-import org.restlet.representation.Representation;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-/**
- * Base class for return router statistics
- *
- */
-public class RouterStatisticsResource extends ServerResource {
- /**
- * Gets the switches/routers and ports information from the network topology.
- *
- * @return a Representation of a Collection of switches/routers from the network
- * topology. Each switch contains the switch ports.
- */
- @Get("json")
- public Representation retrieve() {
- String routerId = (String) getRequestAttributes().get("routerId");
- String statsType = (String) getRequestAttributes().get("statsType");
- ITopologyService topologyService =
- (ITopologyService) getContext().getAttributes()
- .get(ITopologyService.class.getCanonicalName());
-
- MutableTopology mutableTopology = topologyService.getTopology();
- mutableTopology.acquireReadLock();
- try {
- if (routerId == null && statsType == null){
- return eval(toRepresentation(mutableTopology.getSwitches(), null));
- }
- else if(routerId != null && statsType.equals("port")){
- Switch sw = mutableTopology
- .getSwitch(new Dpid(HexString.toLong(routerId)));
- if(sw ==null){
- //TODO: Add exception
- return null;
- }
- Map <String, List<SegmentRouterPortInfo>> result = new HashMap <String, List<SegmentRouterPortInfo>>();
- List<SegmentRouterPortInfo> listPortInfo = new ArrayList<SegmentRouterPortInfo>();
- Collection<Port> portList =sw.getPorts();
- String subnets = null;
- if (sw.getAllStringAttributes().containsKey("subnets")){
- subnets = sw.getAllStringAttributes().get("subnets");
- JSONArray subnetArray = JSONArray.fromObject(subnets);
- Iterator<Port> pI = portList.iterator();
- while(pI.hasNext()){
- Port p = pI.next();
- Iterator<?> sI = subnetArray.iterator();
- String subnet = null;
- while(sI.hasNext()){
- JSONObject portSubnetIp = (JSONObject) sI.next();
- subnet = null;
- if(portSubnetIp.getString("portNo").equals(p.getNumber().toString())){
- subnet = portSubnetIp.getString("subnetIp");
- break;
- }
- }
- listPortInfo.add( new SegmentRouterPortInfo(subnet,p));
- }
- result.put(routerId, listPortInfo);
- return eval(toRepresentation(result,null));
- }
- else{
- Iterator<Port> pI = portList.iterator();
- while(pI.hasNext()){
- Port p = pI.next();
- String subnet = null;
- listPortInfo.add( new SegmentRouterPortInfo(subnet,p));
- }
- result.put(routerId, listPortInfo);
- return eval(toRepresentation(result,null));
- }
- }
- } finally {
- mutableTopology.releaseReadLock();
- }
- //Should Never get to this point.
- return null;
- }
-}
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRouterAdjacencyInfo.java b/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRouterAdjacencyInfo.java
new file mode 100644
index 0000000..1c47e74
--- /dev/null
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRouterAdjacencyInfo.java
@@ -0,0 +1,26 @@
+package net.onrc.onos.apps.segmentrouting.web;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Contain the adjacency port info, which is exposed to REST
+ *
+ */
+
+public class SegmentRouterAdjacencyInfo {
+ private Integer adjacencySid =null;
+ private List<Integer> ports = null;
+
+ public SegmentRouterAdjacencyInfo(Integer adj, List<Integer> pList){
+ this.adjacencySid = adj;
+ this.ports = pList;
+ }
+
+ public Integer getAdjacencySid(){
+ return this.adjacencySid;
+ }
+ public List<Integer> getPorts(){
+ return this.ports;
+ }
+}
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRouterPortInfo.java b/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRouterPortInfo.java
index 73c1334..104ad13 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRouterPortInfo.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRouterPortInfo.java
@@ -1,7 +1,6 @@
package net.onrc.onos.apps.segmentrouting.web;
-import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.List;
import net.onrc.onos.core.topology.Port;
@@ -12,18 +11,23 @@
public class SegmentRouterPortInfo {
//TODO set attributes to private and provide setter and getter.
- public String subnetIp= null;
- public Port port = null;
+ private String subnetIp= null;
+ private Port port = null;
+ private List<Integer> adjacency = null;
- public SegmentRouterPortInfo(String ssubnets, Port pport){
+ public SegmentRouterPortInfo(String ssubnets, Port pport, List<Integer> adj){
this.port = pport;
this.subnetIp = ssubnets;
+ this.adjacency = adj;
}
-
- public void setInfo(String subnetIp, Port p) {
- this.port = p;
- this.subnetIp = subnetIp;
-
+ public String getSubnetIp(){
+ return this.subnetIp;
+ }
+ public Port getPort(){
+ return this.port;
+ }
+ public List<Integer> getAdjacency(){
+ return this.adjacency;
}
}
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRouterResource.java b/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRouterResource.java
new file mode 100644
index 0000000..a34f47a
--- /dev/null
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRouterResource.java
@@ -0,0 +1,154 @@
+package net.onrc.onos.apps.segmentrouting.web;
+
+
+
+import static net.onrc.onos.core.topology.web.TopologyResource.eval;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.onrc.onos.apps.segmentrouting.ISegmentRoutingService;
+import net.onrc.onos.core.topology.ITopologyService;
+import net.onrc.onos.core.topology.MutableTopology;
+import net.onrc.onos.core.topology.Port;
+import net.onrc.onos.core.topology.Switch;
+import net.onrc.onos.core.util.Dpid;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
+import org.projectfloodlight.openflow.util.HexString;
+import org.restlet.representation.Representation;
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+/**
+ * Base class for return router statistics
+ *
+ */
+public class SegmentRouterResource extends ServerResource {
+ /**
+ * Gets the switches/routers and ports information from the network topology.
+ *
+ * @return a Representation of a Collection of switches/routers from the network
+ * topology. Each switch contains the switch ports.
+ */
+ @Get("json")
+ public Object retrieve() {
+ String routerId = (String) getRequestAttributes().get("routerId");
+ String statsType = (String) getRequestAttributes().get("statsType");
+ ITopologyService topologyService =
+ (ITopologyService) getContext().getAttributes()
+ .get(ITopologyService.class.getCanonicalName());
+
+ MutableTopology mutableTopology = topologyService.getTopology();
+ mutableTopology.acquireReadLock();
+ try {
+ if (routerId == null && statsType == null){
+ return eval(toRepresentation(mutableTopology.getSwitches(), null));
+ }
+ else if(routerId != null && statsType.equals("port")){
+ Switch sw = mutableTopology
+ .getSwitch(new Dpid(HexString.toLong(routerId)));
+ if(sw ==null){
+ //TODO: Add exception
+ return null;
+ }
+ ISegmentRoutingService segmentRoutingService =
+ (ISegmentRoutingService) getContext().getAttributes().
+ get(ISegmentRoutingService.class.getCanonicalName());
+ Map <String, List<SegmentRouterPortInfo>> result = new HashMap <String, List<SegmentRouterPortInfo>>();
+ List<SegmentRouterPortInfo> listPortInfo = new ArrayList<SegmentRouterPortInfo>();
+ Collection<Port> portList =sw.getPorts();
+ String subnets = null;
+ if (sw.getAllStringAttributes().containsKey("subnets")){
+ subnets = sw.getAllStringAttributes().get("subnets");
+ JSONArray subnetArray = JSONArray.fromObject(subnets);
+ Iterator<Port> pI = portList.iterator();
+ int nodeSid = Integer.parseInt(sw.getStringAttribute("nodeSid"));
+ HashMap<Integer, List<Integer>> adjPortInfo = segmentRoutingService.getAdjacencyInfo(nodeSid);
+ while(pI.hasNext()){
+ Port p = pI.next();
+ Iterator<Integer> keyIt = adjPortInfo.keySet().iterator();
+ Iterator<?> sI = subnetArray.iterator();
+ List<Integer> adjacency = new ArrayList<Integer>();
+ while(keyIt.hasNext()){
+ Integer adj = keyIt.next();
+ List<Integer> adjPortList = adjPortInfo.get(adj);
+ if(adjPortList.contains(Integer.valueOf(p.getNumber().shortValue()))){
+ adjacency.add(adj);
+ }
+ }
+ String subnet = null;
+ while(sI.hasNext()){
+ JSONObject portSubnetIp = (JSONObject) sI.next();
+ subnet = null;
+ if(portSubnetIp.getString("portNo").equals(p.getNumber().toString())){
+ subnet = portSubnetIp.getString("subnetIp");
+ break;
+ }
+ }
+ listPortInfo.add( new SegmentRouterPortInfo(subnet,p, adjacency));
+ }
+ result.put(routerId, listPortInfo);
+ return eval(toRepresentation(result,null));
+ }
+ else{
+ Iterator<Port> pI = portList.iterator();
+ int nodeSid = Integer.parseInt(sw.getStringAttribute("nodeSid"));
+ HashMap<Integer, List<Integer>> adjPortInfo = segmentRoutingService.getAdjacencyInfo(nodeSid);
+ while(pI.hasNext()){
+ Port p = pI.next();
+ String subnet = null;
+ Iterator<Integer> keyIt = adjPortInfo.keySet().iterator();
+ List<Integer> adjacency = new ArrayList<Integer>();
+ while(keyIt.hasNext()){
+ Integer adj = keyIt.next();
+ List<Integer> adjPortList = adjPortInfo.get(adj);
+ if(adjPortList.contains(Integer.valueOf(p.getNumber().shortValue()))){
+ adjacency.add(adj);
+ }
+ }
+ listPortInfo.add( new SegmentRouterPortInfo(subnet,p, adjacency));
+ }
+ result.put(routerId, listPortInfo);
+ return eval(toRepresentation(result,null));
+ }
+ }
+ else if(routerId != null && statsType.equals("adjacency")){
+ ISegmentRoutingService segmentRoutingService =
+ (ISegmentRoutingService) getContext().getAttributes().
+ get(ISegmentRoutingService.class.getCanonicalName());
+ Switch sw = mutableTopology
+ .getSwitch(new Dpid(HexString.toLong(routerId)));
+ if(sw ==null){
+ //TODO: Add exception
+ return null;
+ }
+ int nodeSid = Integer.parseInt(sw.getStringAttribute("nodeSid"));
+ HashMap<Integer, List<Integer>> adjPortInfo = segmentRoutingService.getAdjacencyInfo(nodeSid);
+ Iterator<Integer> aPIt = adjPortInfo.keySet().iterator();
+ List<SegmentRouterAdjacencyInfo> result= new ArrayList<SegmentRouterAdjacencyInfo>();
+ while(aPIt.hasNext()){
+ Integer adj = aPIt.next();
+ result.add( new SegmentRouterAdjacencyInfo(adj,
+ adjPortInfo.get(adj)));
+ }
+ /*HashMap<String,HashMap<Integer, List<Integer>>> dpidAdjPortMap =
+ new HashMap<String,HashMap<Integer, List<Integer>>>();
+ dpidAdjPortMap.put(routerId, adjPortInfo);
+ List<HashMap<String,HashMap<Integer, List<Integer>>>> result =
+ new ArrayList<HashMap<String,HashMap<Integer, List<Integer>>>>();
+ result.add(dpidAdjPortMap);*/
+
+ return result;
+ }
+ } finally {
+ mutableTopology.releaseReadLock();
+ }
+ //Should Never get to this point.
+ return null;
+ }
+}
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRoutingWebRoutable.java b/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRoutingWebRoutable.java
index e19df8d..f06473c 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRoutingWebRoutable.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/web/SegmentRoutingWebRoutable.java
@@ -19,8 +19,8 @@
public Restlet getRestlet(Context context) {
Router router = new Router(context);
//TODO: rewrite Router/SwitchesResource for router specific info.
- router.attach("/routers", RouterStatisticsResource.class);
- router.attach("/router/{routerId}/{statsType}", RouterStatisticsResource.class);
+ router.attach("/routers", SegmentRouterResource.class);
+ router.attach("/router/{routerId}/{statsType}", SegmentRouterResource.class);
router.attach("/tunnel", SegmentRouterTunnelResource.class);
router.attach("/policy", SegmentRouterPolicyResource.class);
// SegmentRouterTunnelResource.class);