Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
Conflicts: providers/openflow/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java
Showing
253 changed files
with
3555 additions
and
181 deletions
apps/calendar/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
5 | + <modelVersion>4.0.0</modelVersion> | ||
6 | + | ||
7 | + <parent> | ||
8 | + <groupId>org.onlab.onos</groupId> | ||
9 | + <artifactId>onos-apps</artifactId> | ||
10 | + <version>1.0.0-SNAPSHOT</version> | ||
11 | + <relativePath>../pom.xml</relativePath> | ||
12 | + </parent> | ||
13 | + | ||
14 | + <artifactId>onos-app-calendar</artifactId> | ||
15 | + <packaging>bundle</packaging> | ||
16 | + | ||
17 | + <description>ONOS simple calendaring REST interface for intents</description> | ||
18 | + | ||
19 | + <properties> | ||
20 | + <web.context>/onos/calendar</web.context> | ||
21 | + </properties> | ||
22 | + | ||
23 | + <dependencies> | ||
24 | + <dependency> | ||
25 | + <groupId>org.onlab.onos</groupId> | ||
26 | + <artifactId>onlab-rest</artifactId> | ||
27 | + <version>${project.version}</version> | ||
28 | + </dependency> | ||
29 | + | ||
30 | + <dependency> | ||
31 | + <groupId>com.sun.jersey</groupId> | ||
32 | + <artifactId>jersey-servlet</artifactId> | ||
33 | + </dependency> | ||
34 | + <dependency> | ||
35 | + <groupId>com.sun.jersey.jersey-test-framework</groupId> | ||
36 | + <artifactId>jersey-test-framework-core</artifactId> | ||
37 | + <version>1.18.1</version> | ||
38 | + <scope>test</scope> | ||
39 | + </dependency> | ||
40 | + <dependency> | ||
41 | + <groupId>com.sun.jersey.jersey-test-framework</groupId> | ||
42 | + <artifactId>jersey-test-framework-grizzly2</artifactId> | ||
43 | + <version>1.18.1</version> | ||
44 | + <scope>test</scope> | ||
45 | + </dependency> | ||
46 | + <dependency> | ||
47 | + <groupId>org.osgi</groupId> | ||
48 | + <artifactId>org.osgi.core</artifactId> | ||
49 | + </dependency> | ||
50 | + </dependencies> | ||
51 | + | ||
52 | + <build> | ||
53 | + <plugins> | ||
54 | + <plugin> | ||
55 | + <groupId>org.apache.felix</groupId> | ||
56 | + <artifactId>maven-bundle-plugin</artifactId> | ||
57 | + <extensions>true</extensions> | ||
58 | + <configuration> | ||
59 | + <instructions> | ||
60 | + <_wab>src/main/webapp/</_wab> | ||
61 | + <Bundle-SymbolicName> | ||
62 | + ${project.groupId}.${project.artifactId} | ||
63 | + </Bundle-SymbolicName> | ||
64 | + <Import-Package> | ||
65 | + org.osgi.framework, | ||
66 | + javax.ws.rs,javax.ws.rs.core, | ||
67 | + com.sun.jersey.api.core, | ||
68 | + com.sun.jersey.spi.container.servlet, | ||
69 | + com.sun.jersey.server.impl.container.servlet, | ||
70 | + org.onlab.packet.*, | ||
71 | + org.onlab.rest.*, | ||
72 | + org.onlab.onos.* | ||
73 | + </Import-Package> | ||
74 | + <Web-ContextPath>${web.context}</Web-ContextPath> | ||
75 | + </instructions> | ||
76 | + </configuration> | ||
77 | + </plugin> | ||
78 | + </plugins> | ||
79 | + </build> | ||
80 | + | ||
81 | +</project> |
1 | +package org.onlab.onos.calendar; | ||
2 | + | ||
3 | +import org.onlab.onos.net.ConnectPoint; | ||
4 | +import org.onlab.onos.net.DeviceId; | ||
5 | +import org.onlab.onos.net.intent.IntentService; | ||
6 | +import org.onlab.rest.BaseResource; | ||
7 | + | ||
8 | +import javax.ws.rs.POST; | ||
9 | +import javax.ws.rs.Path; | ||
10 | +import javax.ws.rs.PathParam; | ||
11 | +import javax.ws.rs.core.Response; | ||
12 | +import java.net.URI; | ||
13 | + | ||
14 | +import static org.onlab.onos.net.PortNumber.portNumber; | ||
15 | + | ||
16 | +/** | ||
17 | + * Web resource for triggering calendared intents. | ||
18 | + */ | ||
19 | +@Path("intent") | ||
20 | +public class BandwidthCalendarResource extends BaseResource { | ||
21 | + | ||
22 | + @POST | ||
23 | + @Path("{src}/{dst}/{srcPort}/{dstPort}/{bandwidth}") | ||
24 | + public Response createIntent(@PathParam("src") String src, | ||
25 | + @PathParam("dst") String dst, | ||
26 | + @PathParam("srcPort") String srcPort, | ||
27 | + @PathParam("dstPort") String dstPort, | ||
28 | + @PathParam("bandwidth") String bandwidth) { | ||
29 | + // TODO: implement calls to intent framework | ||
30 | + IntentService service = get(IntentService.class); | ||
31 | + | ||
32 | + ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort)); | ||
33 | + ConnectPoint dstPoint = new ConnectPoint(deviceId(dst), portNumber(dstPort)); | ||
34 | + | ||
35 | + return Response.ok("Yo! We got src=" + srcPoint + "; dst=" + dstPoint + | ||
36 | + "; bw=" + bandwidth + "; intent service " + service).build(); | ||
37 | + } | ||
38 | + | ||
39 | + private DeviceId deviceId(String dpid) { | ||
40 | + return DeviceId.deviceId(URI.create("of:" + dpid)); | ||
41 | + } | ||
42 | + | ||
43 | +} |
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" | ||
3 | + xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" | ||
4 | + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" | ||
5 | + id="ONOS" version="2.5"> | ||
6 | + <display-name>ONOS GUI</display-name> | ||
7 | + | ||
8 | + <servlet> | ||
9 | + <servlet-name>JAX-RS Service</servlet-name> | ||
10 | + <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> | ||
11 | + <init-param> | ||
12 | + <param-name>com.sun.jersey.config.property.packages</param-name> | ||
13 | + <param-value>org.onlab.onos.calendar</param-value> | ||
14 | + </init-param> | ||
15 | + <load-on-startup>10</load-on-startup> | ||
16 | + </servlet> | ||
17 | + | ||
18 | + <servlet-mapping> | ||
19 | + <servlet-name>JAX-RS Service</servlet-name> | ||
20 | + <url-pattern>/rs/*</url-pattern> | ||
21 | + </servlet-mapping> | ||
22 | + | ||
23 | +</web-app> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -16,4 +16,11 @@ | ... | @@ -16,4 +16,11 @@ |
16 | 16 | ||
17 | <description>ONOS simple reactive forwarding app</description> | 17 | <description>ONOS simple reactive forwarding app</description> |
18 | 18 | ||
19 | + <dependencies> | ||
20 | + <dependency> | ||
21 | + <groupId>org.osgi</groupId> | ||
22 | + <artifactId>org.osgi.compendium</artifactId> | ||
23 | + </dependency> | ||
24 | + </dependencies> | ||
25 | + | ||
19 | </project> | 26 | </project> | ... | ... |
1 | package org.onlab.onos.fwd; | 1 | package org.onlab.onos.fwd; |
2 | 2 | ||
3 | -import static org.slf4j.LoggerFactory.getLogger; | ||
4 | - | ||
5 | -import java.util.Set; | ||
6 | - | ||
7 | import org.apache.felix.scr.annotations.Activate; | 3 | import org.apache.felix.scr.annotations.Activate; |
8 | import org.apache.felix.scr.annotations.Component; | 4 | import org.apache.felix.scr.annotations.Component; |
9 | import org.apache.felix.scr.annotations.Deactivate; | 5 | import org.apache.felix.scr.annotations.Deactivate; |
6 | +import org.apache.felix.scr.annotations.Modified; | ||
7 | +import org.apache.felix.scr.annotations.Property; | ||
10 | import org.apache.felix.scr.annotations.Reference; | 8 | import org.apache.felix.scr.annotations.Reference; |
11 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 9 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
12 | import org.onlab.onos.ApplicationId; | 10 | import org.onlab.onos.ApplicationId; |
... | @@ -29,8 +27,14 @@ import org.onlab.onos.net.packet.PacketProcessor; | ... | @@ -29,8 +27,14 @@ import org.onlab.onos.net.packet.PacketProcessor; |
29 | import org.onlab.onos.net.packet.PacketService; | 27 | import org.onlab.onos.net.packet.PacketService; |
30 | import org.onlab.onos.net.topology.TopologyService; | 28 | import org.onlab.onos.net.topology.TopologyService; |
31 | import org.onlab.packet.Ethernet; | 29 | import org.onlab.packet.Ethernet; |
30 | +import org.osgi.service.component.ComponentContext; | ||
32 | import org.slf4j.Logger; | 31 | import org.slf4j.Logger; |
33 | 32 | ||
33 | +import java.util.Dictionary; | ||
34 | +import java.util.Set; | ||
35 | + | ||
36 | +import static org.slf4j.LoggerFactory.getLogger; | ||
37 | + | ||
34 | /** | 38 | /** |
35 | * Sample reactive forwarding application. | 39 | * Sample reactive forwarding application. |
36 | */ | 40 | */ |
... | @@ -61,6 +65,10 @@ public class ReactiveForwarding { | ... | @@ -61,6 +65,10 @@ public class ReactiveForwarding { |
61 | 65 | ||
62 | private ApplicationId appId; | 66 | private ApplicationId appId; |
63 | 67 | ||
68 | + @Property(name = "enabled", boolValue = true, | ||
69 | + label = "Enable forwarding; default is true") | ||
70 | + private boolean isEnabled = true; | ||
71 | + | ||
64 | @Activate | 72 | @Activate |
65 | public void activate() { | 73 | public void activate() { |
66 | appId = coreService.registerApplication("org.onlab.onos.fwd"); | 74 | appId = coreService.registerApplication("org.onlab.onos.fwd"); |
... | @@ -76,6 +84,22 @@ public class ReactiveForwarding { | ... | @@ -76,6 +84,22 @@ public class ReactiveForwarding { |
76 | log.info("Stopped"); | 84 | log.info("Stopped"); |
77 | } | 85 | } |
78 | 86 | ||
87 | + @Modified | ||
88 | + public void modified(ComponentContext context) { | ||
89 | + Dictionary properties = context.getProperties(); | ||
90 | + String flag = (String) properties.get("enabled"); | ||
91 | + if (flag != null) { | ||
92 | + boolean enabled = flag.equals("true"); | ||
93 | + if (isEnabled != enabled) { | ||
94 | + isEnabled = enabled; | ||
95 | + if (!isEnabled) { | ||
96 | + flowRuleService.removeFlowRulesById(appId); | ||
97 | + } | ||
98 | + log.info("Reconfigured. Forwarding is {}", | ||
99 | + isEnabled ? "enabled" : "disabled"); | ||
100 | + } | ||
101 | + } | ||
102 | + } | ||
79 | 103 | ||
80 | /** | 104 | /** |
81 | * Packet processor responsible for forwarding packets along their paths. | 105 | * Packet processor responsible for forwarding packets along their paths. |
... | @@ -86,7 +110,7 @@ public class ReactiveForwarding { | ... | @@ -86,7 +110,7 @@ public class ReactiveForwarding { |
86 | public void process(PacketContext context) { | 110 | public void process(PacketContext context) { |
87 | // Stop processing if the packet has been handled, since we | 111 | // Stop processing if the packet has been handled, since we |
88 | // can't do any more to it. | 112 | // can't do any more to it. |
89 | - if (context.isHandled()) { | 113 | + if (!isEnabled || context.isHandled()) { |
90 | return; | 114 | return; |
91 | } | 115 | } |
92 | 116 | ||
... | @@ -114,8 +138,8 @@ public class ReactiveForwarding { | ... | @@ -114,8 +138,8 @@ public class ReactiveForwarding { |
114 | // Otherwise, get a set of paths that lead from here to the | 138 | // Otherwise, get a set of paths that lead from here to the |
115 | // destination edge switch. | 139 | // destination edge switch. |
116 | Set<Path> paths = topologyService.getPaths(topologyService.currentTopology(), | 140 | Set<Path> paths = topologyService.getPaths(topologyService.currentTopology(), |
117 | - pkt.receivedFrom().deviceId(), | 141 | + pkt.receivedFrom().deviceId(), |
118 | - dst.location().deviceId()); | 142 | + dst.location().deviceId()); |
119 | if (paths.isEmpty()) { | 143 | if (paths.isEmpty()) { |
120 | // If there are no paths, flood and bail. | 144 | // If there are no paths, flood and bail. |
121 | flood(context); | 145 | flood(context); |
... | @@ -127,8 +151,8 @@ public class ReactiveForwarding { | ... | @@ -127,8 +151,8 @@ public class ReactiveForwarding { |
127 | Path path = pickForwardPath(paths, pkt.receivedFrom().port()); | 151 | Path path = pickForwardPath(paths, pkt.receivedFrom().port()); |
128 | if (path == null) { | 152 | if (path == null) { |
129 | log.warn("Doh... don't know where to go... {} -> {} received on {}", | 153 | log.warn("Doh... don't know where to go... {} -> {} received on {}", |
130 | - ethPkt.getSourceMAC(), ethPkt.getDestinationMAC(), | 154 | + ethPkt.getSourceMAC(), ethPkt.getDestinationMAC(), |
131 | - pkt.receivedFrom()); | 155 | + pkt.receivedFrom()); |
132 | flood(context); | 156 | flood(context); |
133 | return; | 157 | return; |
134 | } | 158 | } |
... | @@ -152,7 +176,7 @@ public class ReactiveForwarding { | ... | @@ -152,7 +176,7 @@ public class ReactiveForwarding { |
152 | // Floods the specified packet if permissible. | 176 | // Floods the specified packet if permissible. |
153 | private void flood(PacketContext context) { | 177 | private void flood(PacketContext context) { |
154 | if (topologyService.isBroadcastPoint(topologyService.currentTopology(), | 178 | if (topologyService.isBroadcastPoint(topologyService.currentTopology(), |
155 | - context.inPacket().receivedFrom())) { | 179 | + context.inPacket().receivedFrom())) { |
156 | packetOut(context, PortNumber.FLOOD); | 180 | packetOut(context, PortNumber.FLOOD); |
157 | } else { | 181 | } else { |
158 | context.block(); | 182 | context.block(); |
... | @@ -174,18 +198,17 @@ public class ReactiveForwarding { | ... | @@ -174,18 +198,17 @@ public class ReactiveForwarding { |
174 | Ethernet inPkt = context.inPacket().parsed(); | 198 | Ethernet inPkt = context.inPacket().parsed(); |
175 | TrafficSelector.Builder builder = DefaultTrafficSelector.builder(); | 199 | TrafficSelector.Builder builder = DefaultTrafficSelector.builder(); |
176 | builder.matchEthType(inPkt.getEtherType()) | 200 | builder.matchEthType(inPkt.getEtherType()) |
177 | - .matchEthSrc(inPkt.getSourceMAC()) | 201 | + .matchEthSrc(inPkt.getSourceMAC()) |
178 | - .matchEthDst(inPkt.getDestinationMAC()) | 202 | + .matchEthDst(inPkt.getDestinationMAC()) |
179 | - .matchInport(context.inPacket().receivedFrom().port()); | 203 | + .matchInport(context.inPacket().receivedFrom().port()); |
180 | 204 | ||
181 | TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(); | 205 | TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(); |
182 | treat.setOutput(portNumber); | 206 | treat.setOutput(portNumber); |
183 | 207 | ||
184 | FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(), | 208 | FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(), |
185 | - builder.build(), treat.build(), PRIORITY, appId, TIMEOUT); | 209 | + builder.build(), treat.build(), PRIORITY, appId, TIMEOUT); |
186 | 210 | ||
187 | flowRuleService.applyFlowRules(f); | 211 | flowRuleService.applyFlowRules(f); |
188 | - | ||
189 | } | 212 | } |
190 | 213 | ||
191 | } | 214 | } | ... | ... |
apps/optical/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
5 | + <modelVersion>4.0.0</modelVersion> | ||
6 | + | ||
7 | + <parent> | ||
8 | + <groupId>org.onlab.onos</groupId> | ||
9 | + <artifactId>onos-apps</artifactId> | ||
10 | + <version>1.0.0-SNAPSHOT</version> | ||
11 | + <relativePath>../pom.xml</relativePath> | ||
12 | + </parent> | ||
13 | + | ||
14 | + <artifactId>onos-app-optical</artifactId> | ||
15 | + <packaging>bundle</packaging> | ||
16 | + | ||
17 | + <description>ONOS application for packet/optical deployments</description> | ||
18 | + | ||
19 | + <dependencies> | ||
20 | + | ||
21 | + <dependency> | ||
22 | + <groupId>org.onlab.onos</groupId> | ||
23 | + <artifactId>onos-cli</artifactId> | ||
24 | + <version>${project.version}</version> | ||
25 | + </dependency> | ||
26 | + <dependency> | ||
27 | + <groupId>org.apache.karaf.shell</groupId> | ||
28 | + <artifactId>org.apache.karaf.shell.console</artifactId> | ||
29 | + </dependency> | ||
30 | + | ||
31 | + <dependency> | ||
32 | + <groupId>org.codehaus.jackson</groupId> | ||
33 | + <artifactId>jackson-core-asl</artifactId> | ||
34 | + </dependency> | ||
35 | + <dependency> | ||
36 | + <groupId>org.codehaus.jackson</groupId> | ||
37 | + <artifactId>jackson-mapper-asl</artifactId> | ||
38 | + </dependency> | ||
39 | + <dependency> | ||
40 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
41 | + <artifactId>jackson-annotations</artifactId> | ||
42 | + <scope>provided</scope> | ||
43 | + </dependency> | ||
44 | + | ||
45 | + </dependencies> | ||
46 | + | ||
47 | +</project> |
This diff is collapsed. Click to expand it.
1 | +package org.onlab.onos.optical.cfg; | ||
2 | + | ||
3 | +import java.util.Map; | ||
4 | +import org.codehaus.jackson.JsonNode; | ||
5 | +import org.onlab.util.HexString; | ||
6 | + | ||
7 | +/** | ||
8 | + * Public class corresponding to JSON described data model. | ||
9 | + */ | ||
10 | +public class OpticalLinkDescription { | ||
11 | + protected String type; | ||
12 | + protected Boolean allowed; | ||
13 | + protected long dpid1; | ||
14 | + protected long dpid2; | ||
15 | + protected String nodeDpid1; | ||
16 | + protected String nodeDpid2; | ||
17 | + protected Map<String, JsonNode> params; | ||
18 | + protected Map<String, String> publishAttributes; | ||
19 | + | ||
20 | + public String getType() { | ||
21 | + return type; | ||
22 | + } | ||
23 | + | ||
24 | + public void setType(String type) { | ||
25 | + this.type = type; | ||
26 | + } | ||
27 | + | ||
28 | + public Boolean isAllowed() { | ||
29 | + return allowed; | ||
30 | + } | ||
31 | + | ||
32 | + public void setAllowed(Boolean allowed) { | ||
33 | + this.allowed = allowed; | ||
34 | + } | ||
35 | + | ||
36 | + public String getNodeDpid1() { | ||
37 | + return nodeDpid1; | ||
38 | + } | ||
39 | + | ||
40 | + public void setNodeDpid1(String nodeDpid1) { | ||
41 | + this.nodeDpid1 = nodeDpid1; | ||
42 | + this.dpid1 = HexString.toLong(nodeDpid1); | ||
43 | + } | ||
44 | + | ||
45 | + public String getNodeDpid2() { | ||
46 | + return nodeDpid2; | ||
47 | + } | ||
48 | + | ||
49 | + public void setNodeDpid2(String nodeDpid2) { | ||
50 | + this.nodeDpid2 = nodeDpid2; | ||
51 | + this.dpid2 = HexString.toLong(nodeDpid2); | ||
52 | + } | ||
53 | + | ||
54 | + public long getDpid1() { | ||
55 | + return dpid1; | ||
56 | + } | ||
57 | + | ||
58 | + public void setDpid1(long dpid1) { | ||
59 | + this.dpid1 = dpid1; | ||
60 | + this.nodeDpid1 = HexString.toHexString(dpid1); | ||
61 | + } | ||
62 | + | ||
63 | + public long getDpid2() { | ||
64 | + return dpid2; | ||
65 | + } | ||
66 | + | ||
67 | + public void setDpid2(long dpid2) { | ||
68 | + this.dpid2 = dpid2; | ||
69 | + this.nodeDpid2 = HexString.toHexString(dpid2); | ||
70 | + } | ||
71 | + | ||
72 | + public Map<String, JsonNode> getParams() { | ||
73 | + return params; | ||
74 | + } | ||
75 | + | ||
76 | + public void setParams(Map<String, JsonNode> params) { | ||
77 | + this.params = params; | ||
78 | + } | ||
79 | + | ||
80 | + public Map<String, String> getPublishAttributes() { | ||
81 | + return publishAttributes; | ||
82 | + } | ||
83 | + | ||
84 | + public void setPublishAttributes(Map<String, String> publishAttributes) { | ||
85 | + this.publishAttributes = publishAttributes; | ||
86 | + } | ||
87 | + | ||
88 | +} | ||
89 | + |
1 | +package org.onlab.onos.optical.cfg; | ||
2 | + | ||
3 | +import java.util.ArrayList; | ||
4 | +import java.util.List; | ||
5 | + | ||
6 | +import org.slf4j.Logger; | ||
7 | +import org.slf4j.LoggerFactory; | ||
8 | + | ||
9 | +/** | ||
10 | + * Public class corresponding to JSON described data model. | ||
11 | + */ | ||
12 | +public class OpticalNetworkConfig { | ||
13 | + protected static final Logger log = LoggerFactory.getLogger(OpticalNetworkConfig.class); | ||
14 | + | ||
15 | + private List<OpticalSwitchDescription> opticalSwitches; | ||
16 | + private List<OpticalLinkDescription> opticalLinks; | ||
17 | + | ||
18 | + public OpticalNetworkConfig() { | ||
19 | + opticalSwitches = new ArrayList<OpticalSwitchDescription>(); | ||
20 | + opticalLinks = new ArrayList<OpticalLinkDescription>(); | ||
21 | + } | ||
22 | + | ||
23 | + public List<OpticalSwitchDescription> getOpticalSwitches() { | ||
24 | + return opticalSwitches; | ||
25 | + } | ||
26 | + | ||
27 | + public void setOpticalSwitches(List<OpticalSwitchDescription> switches) { | ||
28 | + this.opticalSwitches = switches; | ||
29 | + } | ||
30 | + | ||
31 | + public List<OpticalLinkDescription> getOpticalLinks() { | ||
32 | + return opticalLinks; | ||
33 | + } | ||
34 | + | ||
35 | + public void setOpticalLinks(List<OpticalLinkDescription> links) { | ||
36 | + this.opticalLinks = links; | ||
37 | + } | ||
38 | + | ||
39 | +} | ||
40 | + |
1 | +package org.onlab.onos.optical.cfg; | ||
2 | + | ||
3 | +import java.util.Map; | ||
4 | +import org.codehaus.jackson.JsonNode; | ||
5 | +import org.codehaus.jackson.annotate.JsonProperty; | ||
6 | +import org.onlab.util.HexString; | ||
7 | + | ||
8 | +/** | ||
9 | + * Public class corresponding to JSON described data model. | ||
10 | + */ | ||
11 | +public class OpticalSwitchDescription { | ||
12 | + protected String name; | ||
13 | + protected long dpid; | ||
14 | + protected String nodeDpid; | ||
15 | + protected String type; | ||
16 | + protected double latitude; | ||
17 | + protected double longitude; | ||
18 | + protected boolean allowed; | ||
19 | + protected Map<String, JsonNode> params; | ||
20 | + protected Map<String, String> publishAttributes; | ||
21 | + | ||
22 | + public String getName() { | ||
23 | + return name; | ||
24 | + } | ||
25 | + @JsonProperty("name") | ||
26 | + public void setName(String name) { | ||
27 | + this.name = name; | ||
28 | + } | ||
29 | + | ||
30 | + public long getDpid() { | ||
31 | + return dpid; | ||
32 | + } | ||
33 | + @JsonProperty("dpid") | ||
34 | + public void setDpid(long dpid) { | ||
35 | + this.dpid = dpid; | ||
36 | + this.nodeDpid = HexString.toHexString(dpid); | ||
37 | + } | ||
38 | + | ||
39 | + public String getNodeDpid() { | ||
40 | + return nodeDpid; | ||
41 | + } | ||
42 | + | ||
43 | + public String getHexDpid() { | ||
44 | + return nodeDpid; | ||
45 | + } | ||
46 | + | ||
47 | + public void setNodeDpid(String nodeDpid) { | ||
48 | + this.nodeDpid = nodeDpid; | ||
49 | + this.dpid = HexString.toLong(nodeDpid); | ||
50 | + } | ||
51 | + | ||
52 | + public String getType() { | ||
53 | + return type; | ||
54 | + } | ||
55 | + | ||
56 | + public void setType(String type) { | ||
57 | + this.type = type; | ||
58 | + } | ||
59 | + | ||
60 | + public double getLatitude() { | ||
61 | + return latitude; | ||
62 | + } | ||
63 | + | ||
64 | + public void setLatitude(double latitude) { | ||
65 | + this.latitude = latitude; | ||
66 | + } | ||
67 | + | ||
68 | + public double getLongitude() { | ||
69 | + return longitude; | ||
70 | + } | ||
71 | + | ||
72 | + public void setLongitude(double longitude) { | ||
73 | + this.longitude = longitude; | ||
74 | + } | ||
75 | + | ||
76 | + public boolean isAllowed() { | ||
77 | + return allowed; | ||
78 | + } | ||
79 | + | ||
80 | + public void setAllowed(boolean allowed) { | ||
81 | + this.allowed = allowed; | ||
82 | + } | ||
83 | + | ||
84 | + public Map<String, JsonNode> getParams() { | ||
85 | + return params; | ||
86 | + } | ||
87 | + | ||
88 | + public void setParams(Map<String, JsonNode> params) { | ||
89 | + this.params = params; | ||
90 | + } | ||
91 | + | ||
92 | + public Map<String, String> getPublishAttributes() { | ||
93 | + return publishAttributes; | ||
94 | + } | ||
95 | + | ||
96 | + public void setPublishAttributes(Map<String, String> publishAttributes) { | ||
97 | + this.publishAttributes = publishAttributes; | ||
98 | + } | ||
99 | + | ||
100 | +} |
1 | +package org.onlab.onos.optical.cfg; | ||
2 | + | ||
3 | +/** | ||
4 | + * Packet-optical link Java data object. | ||
5 | + */ | ||
6 | +class PktOptLink { | ||
7 | + private String srcNodeName; | ||
8 | + private String snkNodeName; | ||
9 | + private String srcNodeId; | ||
10 | + private String snkNodeId; | ||
11 | + private int srcPort; | ||
12 | + private int snkPort; | ||
13 | + private double bandwidth; | ||
14 | + private double cost; | ||
15 | + private long adminWeight; | ||
16 | + | ||
17 | + public PktOptLink(String srcName, String snkName) { | ||
18 | + this.srcNodeName = srcName; | ||
19 | + this.snkNodeName = snkName; | ||
20 | + } | ||
21 | + | ||
22 | + public PktOptLink() { | ||
23 | + // TODO Auto-generated constructor stub | ||
24 | + } | ||
25 | + | ||
26 | + public void setSrcNodeName(String name) { | ||
27 | + this.srcNodeName = name; | ||
28 | + } | ||
29 | + | ||
30 | + public String getSrcNodeName() { | ||
31 | + return this.srcNodeName; | ||
32 | + } | ||
33 | + | ||
34 | + public void setSnkNodeName(String name) { | ||
35 | + this.snkNodeName = name; | ||
36 | + } | ||
37 | + | ||
38 | + public String getSnkNodeName() { | ||
39 | + return this.snkNodeName; | ||
40 | + } | ||
41 | + | ||
42 | + public void setSrcNodeId(String nodeId) { | ||
43 | + this.srcNodeId = nodeId; | ||
44 | + } | ||
45 | + | ||
46 | + public String getSrcNodeId() { | ||
47 | + return this.srcNodeId; | ||
48 | + } | ||
49 | + | ||
50 | + public void setSnkNodeId(String nodeId) { | ||
51 | + this.snkNodeId = nodeId; | ||
52 | + } | ||
53 | + | ||
54 | + public String getSnkNodeId() { | ||
55 | + return this.snkNodeId; | ||
56 | + } | ||
57 | + | ||
58 | + public void setSrcPort(int port) { | ||
59 | + this.srcPort = port; | ||
60 | + } | ||
61 | + | ||
62 | + public int getSrcPort() { | ||
63 | + return this.srcPort; | ||
64 | + } | ||
65 | + | ||
66 | + public void setSnkPort(int port) { | ||
67 | + this.snkPort = port; | ||
68 | + } | ||
69 | + | ||
70 | + public int getSnkPort() { | ||
71 | + return this.snkPort; | ||
72 | + } | ||
73 | + | ||
74 | + public void setBandwdith(double x) { | ||
75 | + this.bandwidth = x; | ||
76 | + } | ||
77 | + | ||
78 | + public double getBandwidth() { | ||
79 | + return this.bandwidth; | ||
80 | + } | ||
81 | + | ||
82 | + public void setCost(double x) { | ||
83 | + this.cost = x; | ||
84 | + } | ||
85 | + | ||
86 | + public double getCost() { | ||
87 | + return this.cost; | ||
88 | + } | ||
89 | + | ||
90 | + public void setAdminWeight(long x) { | ||
91 | + this.adminWeight = x; | ||
92 | + } | ||
93 | + | ||
94 | + public long getAdminWeight() { | ||
95 | + return this.adminWeight; | ||
96 | + } | ||
97 | + | ||
98 | + @Override | ||
99 | + public String toString() { | ||
100 | + return new StringBuilder(" srcNodeName: ").append(this.srcNodeName) | ||
101 | + .append(" snkNodeName: ").append(this.snkNodeName) | ||
102 | + .append(" srcNodeId: ").append(this.srcNodeId) | ||
103 | + .append(" snkNodeId: ").append(this.snkNodeId) | ||
104 | + .append(" srcPort: ").append(this.srcPort) | ||
105 | + .append(" snkPort: ").append(this.snkPort) | ||
106 | + .append(" bandwidth: ").append(this.bandwidth) | ||
107 | + .append(" cost: ").append(this.cost) | ||
108 | + .append(" adminWeight: ").append(this.adminWeight).toString(); | ||
109 | + } | ||
110 | +} |
1 | +package org.onlab.onos.optical.cfg; | ||
2 | + | ||
3 | +/** | ||
4 | + * ROADM java data object converted from a JSON file. | ||
5 | + */ | ||
6 | +class Roadm { | ||
7 | + private String name; | ||
8 | + private String nodeID; | ||
9 | + private double longtitude; | ||
10 | + private double latitude; | ||
11 | + private int regenNum; | ||
12 | + | ||
13 | + //TODO use the following attributes when needed for configurations | ||
14 | + private int tPort10G; | ||
15 | + private int tPort40G; | ||
16 | + private int tPort100G; | ||
17 | + private int wPort; | ||
18 | + | ||
19 | + public Roadm() { | ||
20 | + } | ||
21 | + | ||
22 | + public Roadm(String name) { | ||
23 | + this.name = name; | ||
24 | + } | ||
25 | + | ||
26 | + public void setName(String name) { | ||
27 | + this.name = name; | ||
28 | + } | ||
29 | + | ||
30 | + public String getName() { | ||
31 | + return this.name; | ||
32 | + } | ||
33 | + | ||
34 | + public void setNodeId(String nameId) { | ||
35 | + this.nodeID = nameId; | ||
36 | + } | ||
37 | + | ||
38 | + public String getNodeId() { | ||
39 | + return this.nodeID; | ||
40 | + } | ||
41 | + | ||
42 | + public void setLongtitude(double x) { | ||
43 | + this.longtitude = x; | ||
44 | + } | ||
45 | + | ||
46 | + public double getLongtitude() { | ||
47 | + return this.longtitude; | ||
48 | + } | ||
49 | + | ||
50 | + public void setLatitude(double y) { | ||
51 | + this.latitude = y; | ||
52 | + } | ||
53 | + | ||
54 | + public double getLatitude() { | ||
55 | + return this.latitude; | ||
56 | + } | ||
57 | + | ||
58 | + public void setRegenNum(int num) { | ||
59 | + this.regenNum = num; | ||
60 | + } | ||
61 | + public int getRegenNum() { | ||
62 | + return this.regenNum; | ||
63 | + } | ||
64 | + | ||
65 | + public void setTport10GNum(int num) { | ||
66 | + this.tPort10G = num; | ||
67 | + } | ||
68 | + public int getTport10GNum() { | ||
69 | + return this.tPort10G; | ||
70 | + } | ||
71 | + | ||
72 | + public void setTport40GNum(int num) { | ||
73 | + this.tPort40G = num; | ||
74 | + } | ||
75 | + public int getTport40GNum() { | ||
76 | + return this.tPort40G; | ||
77 | + } | ||
78 | + | ||
79 | + public void setTport100GNum(int num) { | ||
80 | + this.tPort100G = num; | ||
81 | + } | ||
82 | + public int getTport100GNum() { | ||
83 | + return this.tPort100G; | ||
84 | + } | ||
85 | + | ||
86 | + public void setWportNum(int num) { | ||
87 | + this.wPort = num; | ||
88 | + } | ||
89 | + public int getWportNum() { | ||
90 | + return this.wPort; | ||
91 | + } | ||
92 | + | ||
93 | + @Override | ||
94 | + public String toString() { | ||
95 | + return new StringBuilder(" ROADM Name: ").append(this.name) | ||
96 | + .append(" nodeID: ").append(this.nodeID) | ||
97 | + .append(" longtitude: ").append(this.longtitude) | ||
98 | + .append(" latitude: ").append(this.latitude) | ||
99 | + .append(" regenNum: ").append(this.regenNum) | ||
100 | + .append(" 10GTportNum: ").append(this.tPort10G) | ||
101 | + .append(" 40GTportNum: ").append(this.tPort40G) | ||
102 | + .append(" 100GTportNum: ").append(this.tPort100G) | ||
103 | + .append(" WportNum: ").append(this.wPort).toString(); | ||
104 | + } | ||
105 | +} | ||
106 | + |
1 | +package org.onlab.onos.optical.cfg; | ||
2 | + | ||
3 | +/** | ||
4 | + * WDM Link Java data object converted from a JSON file. | ||
5 | + */ | ||
6 | +class WdmLink { | ||
7 | + private String srcNodeName; | ||
8 | + private String snkNodeName; | ||
9 | + private String srcNodeId; | ||
10 | + private String snkNodeId; | ||
11 | + private int srcPort; | ||
12 | + private int snkPort; | ||
13 | + private double distance; | ||
14 | + private double cost; | ||
15 | + private int wavelengthNumber; | ||
16 | + private long adminWeight; | ||
17 | + | ||
18 | + public WdmLink(String name1, String name2) { | ||
19 | + this.srcNodeName = name1; | ||
20 | + this.snkNodeName = name2; | ||
21 | + } | ||
22 | + | ||
23 | + public WdmLink() { | ||
24 | + // TODO Auto-generated constructor stub | ||
25 | + } | ||
26 | + | ||
27 | + public void setSrcNodeName(String name) { | ||
28 | + this.srcNodeName = name; | ||
29 | + } | ||
30 | + | ||
31 | + public String getSrcNodeName() { | ||
32 | + return this.srcNodeName; | ||
33 | + } | ||
34 | + | ||
35 | + public void setSnkNodeName(String name) { | ||
36 | + this.snkNodeName = name; | ||
37 | + } | ||
38 | + | ||
39 | + public String getSnkNodeName() { | ||
40 | + return this.snkNodeName; | ||
41 | + } | ||
42 | + | ||
43 | + public void setSrcNodeId(String nodeId) { | ||
44 | + this.srcNodeId = nodeId; | ||
45 | + } | ||
46 | + | ||
47 | + public String getSrcNodeId() { | ||
48 | + return this.srcNodeId; | ||
49 | + } | ||
50 | + | ||
51 | + public void setSnkNodeId(String nodeId) { | ||
52 | + this.snkNodeId = nodeId; | ||
53 | + } | ||
54 | + | ||
55 | + public String getSnkNodeId() { | ||
56 | + return this.snkNodeId; | ||
57 | + } | ||
58 | + | ||
59 | + public void setSrcPort(int port) { | ||
60 | + this.srcPort = port; | ||
61 | + } | ||
62 | + | ||
63 | + public int getSrcPort() { | ||
64 | + return this.srcPort; | ||
65 | + } | ||
66 | + | ||
67 | + public void setSnkPort(int port) { | ||
68 | + this.snkPort = port; | ||
69 | + } | ||
70 | + | ||
71 | + public int getSnkPort() { | ||
72 | + return this.snkPort; | ||
73 | + } | ||
74 | + | ||
75 | + public void setDistance(double x) { | ||
76 | + this.distance = x; | ||
77 | + } | ||
78 | + | ||
79 | + public double getDistance() { | ||
80 | + return this.distance; | ||
81 | + } | ||
82 | + | ||
83 | + public void setCost(double x) { | ||
84 | + this.cost = x; | ||
85 | + } | ||
86 | + | ||
87 | + public double getCost() { | ||
88 | + return this.cost; | ||
89 | + } | ||
90 | + | ||
91 | + public void setWavelengthNumber(int x) { | ||
92 | + this.wavelengthNumber = x; | ||
93 | + } | ||
94 | + | ||
95 | + public int getWavelengthNumber() { | ||
96 | + return this.wavelengthNumber; | ||
97 | + } | ||
98 | + | ||
99 | + public void setAdminWeight(long x) { | ||
100 | + this.adminWeight = x; | ||
101 | + } | ||
102 | + | ||
103 | + public long getAdminWeight() { | ||
104 | + return this.adminWeight; | ||
105 | + } | ||
106 | + | ||
107 | + @Override | ||
108 | + public String toString() { | ||
109 | + return new StringBuilder(" srcNodeName: ").append(this.srcNodeName) | ||
110 | + .append(" snkNodeName: ").append(this.snkNodeName) | ||
111 | + .append(" srcNodeId: ").append(this.srcNodeId) | ||
112 | + .append(" snkNodeId: ").append(this.snkNodeId) | ||
113 | + .append(" srcPort: ").append(this.srcPort) | ||
114 | + .append(" snkPort: ").append(this.snkPort) | ||
115 | + .append(" distance: ").append(this.distance) | ||
116 | + .append(" cost: ").append(this.cost) | ||
117 | + .append(" wavelengthNumber: ").append(this.wavelengthNumber) | ||
118 | + .append(" adminWeight: ").append(this.adminWeight).toString(); | ||
119 | + } | ||
120 | +} | ||
121 | + |
1 | +{ | ||
2 | + "opticalSwitches": [ | ||
3 | + { | ||
4 | + "allowed": true, | ||
5 | + "latitude": 37.6, | ||
6 | + "longitude": 122.3, | ||
7 | + "name": "SFO-W10", | ||
8 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:01", | ||
9 | + "params": { | ||
10 | + "numRegen": 0 | ||
11 | + }, | ||
12 | + "type": "Roadm" | ||
13 | + }, | ||
14 | + | ||
15 | + { | ||
16 | + "allowed": true, | ||
17 | + "latitude": 37.3, | ||
18 | + "longitude": 121.9, | ||
19 | + "name": "SJC-W10", | ||
20 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:02", | ||
21 | + "params": { | ||
22 | + "numRegen": 0 | ||
23 | + }, | ||
24 | + "type": "Roadm" | ||
25 | + }, | ||
26 | + | ||
27 | + { | ||
28 | + "allowed": true, | ||
29 | + "latitude": 33.9, | ||
30 | + "longitude": 118.4 | ||
31 | + "name": "LAX-W10", | ||
32 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:03", | ||
33 | + "params": { | ||
34 | + "numRegen": 0 | ||
35 | + }, | ||
36 | + "type": "Roadm" | ||
37 | + }, | ||
38 | + | ||
39 | + { | ||
40 | + "allowed": true, | ||
41 | + "latitude": 32.8, | ||
42 | + "longitude": 117.1, | ||
43 | + "name": "SDG-W10", | ||
44 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:04", | ||
45 | + "params": { | ||
46 | + "numRegen": 3 | ||
47 | + }, | ||
48 | + "type": "Roadm" | ||
49 | + }, | ||
50 | + | ||
51 | + { | ||
52 | + "allowed": true, | ||
53 | + "latitude": 44.8, | ||
54 | + "longitude": 93.1, | ||
55 | + "name": "MSP-M10", | ||
56 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:05", | ||
57 | + "params": { | ||
58 | + "numRegen": 3 | ||
59 | + }, | ||
60 | + "type": "Roadm" | ||
61 | + }, | ||
62 | + | ||
63 | + { | ||
64 | + "allowed": true, | ||
65 | + "latitude": 32.8, | ||
66 | + "longitude": 97.1, | ||
67 | + "name": "DFW-M10", | ||
68 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:06", | ||
69 | + "params": { | ||
70 | + "numRegen": 3 | ||
71 | + }, | ||
72 | + "type": "Roadm" | ||
73 | + }, | ||
74 | + | ||
75 | + { | ||
76 | + "allowed": true, | ||
77 | + "latitude": 41.8, | ||
78 | + "longitude": 120.1, | ||
79 | + "name": "CHG-N10", | ||
80 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:07", | ||
81 | + "params": { | ||
82 | + "numRegen": 3 | ||
83 | + }, | ||
84 | + "type": "Roadm" | ||
85 | + }, | ||
86 | + | ||
87 | + { | ||
88 | + "allowed": true, | ||
89 | + "latitude": 38.8, | ||
90 | + "longitude": 77.1, | ||
91 | + "name": "IAD-M10", | ||
92 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:08", | ||
93 | + "params": { | ||
94 | + "numRegen": 3 | ||
95 | + }, | ||
96 | + "type": "Roadm" | ||
97 | + }, | ||
98 | + | ||
99 | + { | ||
100 | + "allowed": true, | ||
101 | + "latitude": 40.8, | ||
102 | + "longitude": 73.1, | ||
103 | + "name": "JFK-E10", | ||
104 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:09", | ||
105 | + "params": { | ||
106 | + "numRegen": 0 | ||
107 | + }, | ||
108 | + "type": "Roadm" | ||
109 | + | ||
110 | + }, | ||
111 | + | ||
112 | + { | ||
113 | + "allowed": true, | ||
114 | + "latitude": 33.8, | ||
115 | + "longitude": 84.1, | ||
116 | + "name": "ATL-S10", | ||
117 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:0A", | ||
118 | + "params": { | ||
119 | + "numRegen": 0 | ||
120 | + }, | ||
121 | + "type": "Roadm" | ||
122 | + } | ||
123 | + | ||
124 | + ], | ||
125 | + | ||
126 | + "opticalLinks": [ | ||
127 | + { | ||
128 | + "allowed": true, | ||
129 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01", | ||
130 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:02", | ||
131 | + "params": { | ||
132 | + "distKms": 1000, | ||
133 | + "nodeName1": "SFO-W10", | ||
134 | + "nodeName2": "SJC-W10", | ||
135 | + "numWaves": 80, | ||
136 | + "port1": 10, | ||
137 | + "port2": 10 | ||
138 | + }, | ||
139 | + "type": "wdmLink" | ||
140 | + }, | ||
141 | + | ||
142 | + { | ||
143 | + "allowed": true, | ||
144 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02", | ||
145 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:03", | ||
146 | + "params": { | ||
147 | + "distKms": 1000, | ||
148 | + "nodeName1": "SJC-W10", | ||
149 | + "nodeName2": "LAX-W10", | ||
150 | + "numWaves": 80, | ||
151 | + "port1": 20, | ||
152 | + "port2": 10 | ||
153 | + }, | ||
154 | + "type": "wdmLink" | ||
155 | + }, | ||
156 | + | ||
157 | + { | ||
158 | + "allowed": true, | ||
159 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03", | ||
160 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04", | ||
161 | + "params": { | ||
162 | + "distKms": 1000, | ||
163 | + "nodeName1": "LAX-W10", | ||
164 | + "nodeName2": "SDG-W10", | ||
165 | + "numWaves": 80, | ||
166 | + "port1": 30, | ||
167 | + "port2": 10 | ||
168 | + }, | ||
169 | + "type": "wdmLink" | ||
170 | + }, | ||
171 | + | ||
172 | + { | ||
173 | + "allowed": true, | ||
174 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02", | ||
175 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:05", | ||
176 | + "params": { | ||
177 | + "distKms": 4000, | ||
178 | + "nodeName1": "SJC-W10", | ||
179 | + "nodeName2": "MSP-M10", | ||
180 | + "numWaves": 80, | ||
181 | + "port1": 20, | ||
182 | + "port2": 10 | ||
183 | + }, | ||
184 | + "type": "wdmLink" | ||
185 | + }, | ||
186 | + | ||
187 | + { | ||
188 | + | ||
189 | + "allowed": true, | ||
190 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03", | ||
191 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:06", | ||
192 | + "params": { | ||
193 | + "distKms": 5000, | ||
194 | + "nodeName1": "LAX-W10", | ||
195 | + "nodeName2": "DFW-M10", | ||
196 | + "numWaves": 80, | ||
197 | + "port1": 20, | ||
198 | + "port2": 10 | ||
199 | + }, | ||
200 | + "type": "wdmLink" | ||
201 | + }, | ||
202 | + | ||
203 | + { | ||
204 | + "allowed": true, | ||
205 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:05", | ||
206 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:06", | ||
207 | + "params": { | ||
208 | + "distKms": 3000, | ||
209 | + "nodeName1": "MSP-M10", | ||
210 | + "nodeName2": "DFW-M10", | ||
211 | + "numWaves": 80, | ||
212 | + "port1": 30, | ||
213 | + "port2": 20 | ||
214 | + }, | ||
215 | + "type": "wdmLink" | ||
216 | + }, | ||
217 | + | ||
218 | + { | ||
219 | + "allowed": true, | ||
220 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:05", | ||
221 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:07", | ||
222 | + "params": { | ||
223 | + "distKms": 3000, | ||
224 | + "nodeName1": "MSP-M10", | ||
225 | + "nodeName2": "CHG-N10", | ||
226 | + "numWaves": 80, | ||
227 | + "port1": 20, | ||
228 | + "port2": 21 | ||
229 | + }, | ||
230 | + "type": "wdmLink" | ||
231 | + }, | ||
232 | + | ||
233 | + { | ||
234 | + | ||
235 | + "allowed": true, | ||
236 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:06", | ||
237 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:08", | ||
238 | + "params": { | ||
239 | + "distKms": 4000, | ||
240 | + "nodeName1": "DFW-M10", | ||
241 | + "nodeName2": "IAD-M10", | ||
242 | + "numWaves": 80, | ||
243 | + "port1": 30, | ||
244 | + "port2": 10 | ||
245 | + }, | ||
246 | + "type": "wdmLink" | ||
247 | + }, | ||
248 | + | ||
249 | + { | ||
250 | + | ||
251 | + "allowed": true, | ||
252 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:07", | ||
253 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:08", | ||
254 | + "params": { | ||
255 | + "distKms": 4000, | ||
256 | + "nodeName1": "CHG-M10", | ||
257 | + "nodeName2": "IAD-M10", | ||
258 | + "numWaves": 80, | ||
259 | + "port1": 30, | ||
260 | + "port2": 20 | ||
261 | + }, | ||
262 | + "type": "wdmLink" | ||
263 | + }, | ||
264 | + | ||
265 | + { | ||
266 | + "allowed": true, | ||
267 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:07", | ||
268 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:09", | ||
269 | + "params": { | ||
270 | + "distKms": 5000, | ||
271 | + "nodeName1": "CHG-M10", | ||
272 | + "nodeName2": "JFK-E10", | ||
273 | + "numWaves": 80, | ||
274 | + "port1": 20, | ||
275 | + "port2": 10 | ||
276 | + }, | ||
277 | + "type": "wdmLink" | ||
278 | + }, | ||
279 | + | ||
280 | + { | ||
281 | + "allowed": true, | ||
282 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:08", | ||
283 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0A", | ||
284 | + "params": { | ||
285 | + "distKms": 3000, | ||
286 | + "nodeName1": "IAD-M10", | ||
287 | + "nodeName2": "ATL-S10", | ||
288 | + "numWaves": 80, | ||
289 | + "port1": 30, | ||
290 | + "port2": 10 | ||
291 | + }, | ||
292 | + "type": "wdmLink" | ||
293 | + }, | ||
294 | + | ||
295 | + { | ||
296 | + | ||
297 | + "allowed": true, | ||
298 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:09", | ||
299 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0A", | ||
300 | + "params": { | ||
301 | + "distKms": 4000, | ||
302 | + "nodeName1": "JFK-E10", | ||
303 | + "nodeName2": "ATL-S10", | ||
304 | + "numWaves": 80, | ||
305 | + "port1": 20, | ||
306 | + "port2": 20 | ||
307 | + }, | ||
308 | + "type": "wdmLink" | ||
309 | + }, | ||
310 | + | ||
311 | + | ||
312 | + { | ||
313 | + "allowed": true, | ||
314 | + "nodeDpid1": "00:00:ff:ff:ff:ff:00:01", | ||
315 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:01", | ||
316 | + "params": { | ||
317 | + "nodeName1": "SFO-R10", | ||
318 | + "nodeName2": "SFO-W10", | ||
319 | + "port1": 10, | ||
320 | + "port2": 1 | ||
321 | + }, | ||
322 | + "type": "pktOptLink" | ||
323 | + }, | ||
324 | + | ||
325 | + { | ||
326 | + "allowed": true, | ||
327 | + "nodeDpid1": "00:00:ff:ff:ff:ff:00:03", | ||
328 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:03", | ||
329 | + "params": { | ||
330 | + "nodeName1": "LAX-R10", | ||
331 | + "nodeName2": "LAX-W10", | ||
332 | + "port1": 10, | ||
333 | + "port2": 1 | ||
334 | + }, | ||
335 | + "type": "pktOptLink" | ||
336 | + }, | ||
337 | + | ||
338 | + { | ||
339 | + "allowed": true, | ||
340 | + "nodeDpid1": "00:00:ff:ff:ff:ff:00:04", | ||
341 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04", | ||
342 | + "params": { | ||
343 | + "nodeName1": "SDG-R10", | ||
344 | + "nodeName2": "SDG-W10", | ||
345 | + "port1": 10, | ||
346 | + "port2": 1 | ||
347 | + }, | ||
348 | + "type": "pktOptLink" | ||
349 | + }, | ||
350 | + | ||
351 | + { | ||
352 | + "allowed": true, | ||
353 | + "nodeDpid1": "00:00:ff:ff:ff:ff:00:07", | ||
354 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:07", | ||
355 | + "params": { | ||
356 | + "nodeName1": "CHG-R10", | ||
357 | + "nodeName2": "CHG-W10", | ||
358 | + "port1": 10, | ||
359 | + "port2": 1 | ||
360 | + }, | ||
361 | + "type": "pktOptLink" | ||
362 | + }, | ||
363 | + | ||
364 | + { | ||
365 | + "allowed": true, | ||
366 | + "nodeDpid1": "00:00:ff:ff:ff:ff:00:09", | ||
367 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:09", | ||
368 | + "params": { | ||
369 | + "nodeName1": "JFK-R10", | ||
370 | + "nodeName2": "JFK-W10", | ||
371 | + "port1": 10, | ||
372 | + "port2": 1 | ||
373 | + }, | ||
374 | + "type": "pktOptLink" | ||
375 | + }, | ||
376 | + | ||
377 | + { | ||
378 | + "allowed": true, | ||
379 | + "nodeDpid1": "00:00:ff:ff:ff:ff:00:0A", | ||
380 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0A", | ||
381 | + "params": { | ||
382 | + "nodeName1": "ATL-R10", | ||
383 | + "nodeName2": "ATL-W10", | ||
384 | + "port1": 10, | ||
385 | + "port2": 1 | ||
386 | + }, | ||
387 | + "type": "pktOptLink" | ||
388 | + }, | ||
389 | + | ||
390 | + ] | ||
391 | +} |
1 | +{ | ||
2 | + "opticalSwitches": [ | ||
3 | + { | ||
4 | + "allowed": true, | ||
5 | + "latitude": 37.6, | ||
6 | + "longitude": 122.3, | ||
7 | + "name": "ROADM1", | ||
8 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:01", | ||
9 | + "params": { | ||
10 | + "numRegen": 0 | ||
11 | + }, | ||
12 | + "type": "Roadm" | ||
13 | + }, | ||
14 | + | ||
15 | + { | ||
16 | + "allowed": true, | ||
17 | + "latitude": 37.3, | ||
18 | + "longitude": 121.9, | ||
19 | + "name": "ROADM2", | ||
20 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:02", | ||
21 | + "params": { | ||
22 | + "numRegen": 0 | ||
23 | + }, | ||
24 | + "type": "Roadm" | ||
25 | + }, | ||
26 | + | ||
27 | + { | ||
28 | + "allowed": true, | ||
29 | + "latitude": 33.9, | ||
30 | + "longitude": 118.4, | ||
31 | + "name": "ROADM3", | ||
32 | + "nodeDpid": "00:00:ff:ff:ff:ff:ff:03", | ||
33 | + "params": { | ||
34 | + "numRegen": 2 | ||
35 | + }, | ||
36 | + "type": "Roadm" | ||
37 | + } | ||
38 | + ], | ||
39 | + | ||
40 | + "opticalLinks": [ | ||
41 | + { | ||
42 | + "allowed": true, | ||
43 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01", | ||
44 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:03", | ||
45 | + "params": { | ||
46 | + "distKms": 1000, | ||
47 | + "nodeName1": "ROADM1", | ||
48 | + "nodeName2": "ROADM3", | ||
49 | + "numWaves": 80, | ||
50 | + "port1": 10, | ||
51 | + "port2": 30 | ||
52 | + }, | ||
53 | + "type": "wdmLink" | ||
54 | + }, | ||
55 | + | ||
56 | + { | ||
57 | + "allowed": true, | ||
58 | + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03", | ||
59 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:02", | ||
60 | + "params": { | ||
61 | + "distKms": 2000, | ||
62 | + "nodeName1": "ROADM3", | ||
63 | + "nodeName2": "ROADM2", | ||
64 | + "numWaves": 80, | ||
65 | + "port1": 31, | ||
66 | + "port2": 20 | ||
67 | + }, | ||
68 | + "type": "wdmLink" | ||
69 | + }, | ||
70 | + | ||
71 | + | ||
72 | + { | ||
73 | + "allowed": true, | ||
74 | + "nodeDpid1": "00:00:ff:ff:ff:ff:00:01", | ||
75 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:01", | ||
76 | + "params": { | ||
77 | + "nodeName1": "ROUTER1", | ||
78 | + "nodeName2": "ROADM1", | ||
79 | + "bandWidth": 100000, | ||
80 | + "port1": 10, | ||
81 | + "port2": 11 | ||
82 | + }, | ||
83 | + "type": "pktOptLink" | ||
84 | + }, | ||
85 | + | ||
86 | + { | ||
87 | + "allowed": true, | ||
88 | + "nodeDpid1": "00:00:ff:ff:ff:ff:00:02", | ||
89 | + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:02", | ||
90 | + "params": { | ||
91 | + "nodeName1": "ROUTER2", | ||
92 | + "nodeName2": "ROADM2", | ||
93 | + "bandWidth": 100000, | ||
94 | + "port1": 10, | ||
95 | + "port2": 21 | ||
96 | + }, | ||
97 | + "type": "pktOptLink" | ||
98 | + } | ||
99 | + | ||
100 | + ] | ||
101 | +} |
... | @@ -25,6 +25,8 @@ | ... | @@ -25,6 +25,8 @@ |
25 | <module>proxyarp</module> | 25 | <module>proxyarp</module> |
26 | <module>config</module> | 26 | <module>config</module> |
27 | <module>sdnip</module> | 27 | <module>sdnip</module> |
28 | + <module>calendar</module> | ||
29 | + <module>optical</module> | ||
28 | </modules> | 30 | </modules> |
29 | 31 | ||
30 | <properties> | 32 | <properties> | ... | ... |
... | @@ -36,6 +36,36 @@ | ... | @@ -36,6 +36,36 @@ |
36 | <groupId>com.google.guava</groupId> | 36 | <groupId>com.google.guava</groupId> |
37 | <artifactId>guava</artifactId> | 37 | <artifactId>guava</artifactId> |
38 | </dependency> | 38 | </dependency> |
39 | + | ||
40 | + <dependency> | ||
41 | + <groupId>org.onlab.onos</groupId> | ||
42 | + <artifactId>onlab-thirdparty</artifactId> | ||
43 | + </dependency> | ||
44 | + | ||
45 | + <dependency> | ||
46 | + <groupId>org.onlab.onos</groupId> | ||
47 | + <artifactId>onlab-misc</artifactId> | ||
48 | + </dependency> | ||
49 | + | ||
50 | + <dependency> | ||
51 | + <groupId>org.onlab.onos</groupId> | ||
52 | + <artifactId>onos-cli</artifactId> | ||
53 | + <version>${project.version}</version> | ||
54 | + </dependency> | ||
55 | + <dependency> | ||
56 | + <groupId>org.apache.karaf.shell</groupId> | ||
57 | + <artifactId>org.apache.karaf.shell.console</artifactId> | ||
58 | + </dependency> | ||
59 | + <dependency> | ||
60 | + <groupId>org.osgi</groupId> | ||
61 | + <artifactId>org.osgi.core</artifactId> | ||
62 | + </dependency> | ||
63 | + | ||
64 | + <dependency> | ||
65 | + <groupId>org.easymock</groupId> | ||
66 | + <artifactId>easymock</artifactId> | ||
67 | + <scope>test</scope> | ||
68 | + </dependency> | ||
39 | </dependencies> | 69 | </dependencies> |
40 | 70 | ||
41 | </project> | 71 | </project> | ... | ... |
... | @@ -18,11 +18,11 @@ import com.google.common.collect.Sets; | ... | @@ -18,11 +18,11 @@ import com.google.common.collect.Sets; |
18 | /** | 18 | /** |
19 | * Provides IntefaceService using PortAddresses data from the HostService. | 19 | * Provides IntefaceService using PortAddresses data from the HostService. |
20 | */ | 20 | */ |
21 | -public class HostServiceBasedInterfaceService implements InterfaceService { | 21 | +public class HostToInterfaceAdaptor implements InterfaceService { |
22 | 22 | ||
23 | private final HostService hostService; | 23 | private final HostService hostService; |
24 | 24 | ||
25 | - public HostServiceBasedInterfaceService(HostService hostService) { | 25 | + public HostToInterfaceAdaptor(HostService hostService) { |
26 | this.hostService = checkNotNull(hostService); | 26 | this.hostService = checkNotNull(hostService); |
27 | } | 27 | } |
28 | 28 | ... | ... |
... | @@ -25,10 +25,10 @@ import org.slf4j.LoggerFactory; | ... | @@ -25,10 +25,10 @@ import org.slf4j.LoggerFactory; |
25 | /** | 25 | /** |
26 | * Manages the connectivity requirements between peers. | 26 | * Manages the connectivity requirements between peers. |
27 | */ | 27 | */ |
28 | -public class PeerConnectivity { | 28 | +public class PeerConnectivityManager { |
29 | 29 | ||
30 | private static final Logger log = LoggerFactory.getLogger( | 30 | private static final Logger log = LoggerFactory.getLogger( |
31 | - PeerConnectivity.class); | 31 | + PeerConnectivityManager.class); |
32 | 32 | ||
33 | // TODO these shouldn't be defined here | 33 | // TODO these shouldn't be defined here |
34 | private static final short BGP_PORT = 179; | 34 | private static final short BGP_PORT = 179; |
... | @@ -41,7 +41,7 @@ public class PeerConnectivity { | ... | @@ -41,7 +41,7 @@ public class PeerConnectivity { |
41 | // TODO this sucks. | 41 | // TODO this sucks. |
42 | private int intentId = 0; | 42 | private int intentId = 0; |
43 | 43 | ||
44 | - public PeerConnectivity(SdnIpConfigService configInfoService, | 44 | + public PeerConnectivityManager(SdnIpConfigService configInfoService, |
45 | InterfaceService interfaceService, IntentService intentService) { | 45 | InterfaceService interfaceService, IntentService intentService) { |
46 | this.configInfoService = configInfoService; | 46 | this.configInfoService = configInfoService; |
47 | this.interfaceService = interfaceService; | 47 | this.interfaceService = interfaceService; |
... | @@ -126,8 +126,8 @@ public class PeerConnectivity { | ... | @@ -126,8 +126,8 @@ public class PeerConnectivity { |
126 | TrafficSelector selector = DefaultTrafficSelector.builder() | 126 | TrafficSelector selector = DefaultTrafficSelector.builder() |
127 | .matchEthType(Ethernet.TYPE_IPV4) | 127 | .matchEthType(Ethernet.TYPE_IPV4) |
128 | .matchIPProtocol(IPv4.PROTOCOL_TCP) | 128 | .matchIPProtocol(IPv4.PROTOCOL_TCP) |
129 | - .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH)) | 129 | + .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH)) |
130 | - .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH)) | 130 | + .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH)) |
131 | .matchTcpDst(BGP_PORT) | 131 | .matchTcpDst(BGP_PORT) |
132 | .build(); | 132 | .build(); |
133 | 133 | ||
... | @@ -147,8 +147,8 @@ public class PeerConnectivity { | ... | @@ -147,8 +147,8 @@ public class PeerConnectivity { |
147 | selector = DefaultTrafficSelector.builder() | 147 | selector = DefaultTrafficSelector.builder() |
148 | .matchEthType(Ethernet.TYPE_IPV4) | 148 | .matchEthType(Ethernet.TYPE_IPV4) |
149 | .matchIPProtocol(IPv4.PROTOCOL_TCP) | 149 | .matchIPProtocol(IPv4.PROTOCOL_TCP) |
150 | - .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH)) | 150 | + .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH)) |
151 | - .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH)) | 151 | + .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH)) |
152 | .matchTcpSrc(BGP_PORT) | 152 | .matchTcpSrc(BGP_PORT) |
153 | .build(); | 153 | .build(); |
154 | 154 | ||
... | @@ -165,8 +165,8 @@ public class PeerConnectivity { | ... | @@ -165,8 +165,8 @@ public class PeerConnectivity { |
165 | selector = DefaultTrafficSelector.builder() | 165 | selector = DefaultTrafficSelector.builder() |
166 | .matchEthType(Ethernet.TYPE_IPV4) | 166 | .matchEthType(Ethernet.TYPE_IPV4) |
167 | .matchIPProtocol(IPv4.PROTOCOL_TCP) | 167 | .matchIPProtocol(IPv4.PROTOCOL_TCP) |
168 | - .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH)) | 168 | + .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH)) |
169 | - .matchIPDst(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH)) | 169 | + .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH)) |
170 | .matchTcpDst(BGP_PORT) | 170 | .matchTcpDst(BGP_PORT) |
171 | .build(); | 171 | .build(); |
172 | 172 | ||
... | @@ -183,8 +183,8 @@ public class PeerConnectivity { | ... | @@ -183,8 +183,8 @@ public class PeerConnectivity { |
183 | selector = DefaultTrafficSelector.builder() | 183 | selector = DefaultTrafficSelector.builder() |
184 | .matchEthType(Ethernet.TYPE_IPV4) | 184 | .matchEthType(Ethernet.TYPE_IPV4) |
185 | .matchIPProtocol(IPv4.PROTOCOL_TCP) | 185 | .matchIPProtocol(IPv4.PROTOCOL_TCP) |
186 | - .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH)) | 186 | + .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH)) |
187 | - .matchIPDst(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH)) | 187 | + .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH)) |
188 | .matchTcpSrc(BGP_PORT) | 188 | .matchTcpSrc(BGP_PORT) |
189 | .build(); | 189 | .build(); |
190 | 190 | ||
... | @@ -251,8 +251,8 @@ public class PeerConnectivity { | ... | @@ -251,8 +251,8 @@ public class PeerConnectivity { |
251 | TrafficSelector selector = DefaultTrafficSelector.builder() | 251 | TrafficSelector selector = DefaultTrafficSelector.builder() |
252 | .matchEthType(Ethernet.TYPE_IPV4) | 252 | .matchEthType(Ethernet.TYPE_IPV4) |
253 | .matchIPProtocol(IPv4.PROTOCOL_ICMP) | 253 | .matchIPProtocol(IPv4.PROTOCOL_ICMP) |
254 | - .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH)) | 254 | + .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH)) |
255 | - .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH)) | 255 | + .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH)) |
256 | .build(); | 256 | .build(); |
257 | 257 | ||
258 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 258 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
... | @@ -269,8 +269,8 @@ public class PeerConnectivity { | ... | @@ -269,8 +269,8 @@ public class PeerConnectivity { |
269 | selector = DefaultTrafficSelector.builder() | 269 | selector = DefaultTrafficSelector.builder() |
270 | .matchEthType(Ethernet.TYPE_IPV4) | 270 | .matchEthType(Ethernet.TYPE_IPV4) |
271 | .matchIPProtocol(IPv4.PROTOCOL_ICMP) | 271 | .matchIPProtocol(IPv4.PROTOCOL_ICMP) |
272 | - .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH)) | 272 | + .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH)) |
273 | - .matchIPDst(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH)) | 273 | + .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH)) |
274 | .build(); | 274 | .build(); |
275 | 275 | ||
276 | PointToPointIntent reversedIntent = new PointToPointIntent( | 276 | PointToPointIntent reversedIntent = new PointToPointIntent( | ... | ... |
1 | +package org.onlab.onos.sdnip; | ||
2 | + | ||
3 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
4 | + | ||
5 | +import java.util.Objects; | ||
6 | + | ||
7 | +import org.onlab.packet.IpAddress; | ||
8 | +import org.onlab.packet.IpPrefix; | ||
9 | + | ||
10 | +import com.google.common.base.MoreObjects; | ||
11 | + | ||
12 | +/** | ||
13 | + * Represents a route entry for an IP prefix. | ||
14 | + */ | ||
15 | +public class RouteEntry { | ||
16 | + private final IpPrefix prefix; // The IP prefix | ||
17 | + private final IpAddress nextHop; // Next-hop IP address | ||
18 | + | ||
19 | + /** | ||
20 | + * Class constructor. | ||
21 | + * | ||
22 | + * @param prefix the IP prefix of the route | ||
23 | + * @param nextHop the next hop IP address for the route | ||
24 | + */ | ||
25 | + public RouteEntry(IpPrefix prefix, IpAddress nextHop) { | ||
26 | + this.prefix = checkNotNull(prefix); | ||
27 | + this.nextHop = checkNotNull(nextHop); | ||
28 | + } | ||
29 | + | ||
30 | + /** | ||
31 | + * Returns the IP prefix of the route. | ||
32 | + * | ||
33 | + * @return the IP prefix of the route | ||
34 | + */ | ||
35 | + public IpPrefix prefix() { | ||
36 | + return prefix; | ||
37 | + } | ||
38 | + | ||
39 | + /** | ||
40 | + * Returns the next hop IP address for the route. | ||
41 | + * | ||
42 | + * @return the next hop IP address for the route | ||
43 | + */ | ||
44 | + public IpAddress nextHop() { | ||
45 | + return nextHop; | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * Creates the binary string representation of an IPv4 prefix. | ||
50 | + * The string length is equal to the prefix length. | ||
51 | + * | ||
52 | + * @param ip4Prefix the IPv4 prefix to use | ||
53 | + * @return the binary string representation | ||
54 | + */ | ||
55 | + static String createBinaryString(IpPrefix ip4Prefix) { | ||
56 | + if (ip4Prefix.prefixLength() == 0) { | ||
57 | + return ""; | ||
58 | + } | ||
59 | + | ||
60 | + StringBuilder result = new StringBuilder(ip4Prefix.prefixLength()); | ||
61 | + long value = ip4Prefix.toInt(); | ||
62 | + for (int i = 0; i < ip4Prefix.prefixLength(); i++) { | ||
63 | + long mask = 1 << (IpAddress.MAX_INET_MASK - 1 - i); | ||
64 | + result.append(((value & mask) == 0) ? "0" : "1"); | ||
65 | + } | ||
66 | + return result.toString(); | ||
67 | + } | ||
68 | + | ||
69 | + @Override | ||
70 | + public boolean equals(Object other) { | ||
71 | + if (this == other) { | ||
72 | + return true; | ||
73 | + } | ||
74 | + | ||
75 | + // | ||
76 | + // NOTE: Subclasses are considered as change of identity, hence | ||
77 | + // equals() will return false if the class type doesn't match. | ||
78 | + // | ||
79 | + if (other == null || getClass() != other.getClass()) { | ||
80 | + return false; | ||
81 | + } | ||
82 | + | ||
83 | + RouteEntry otherRoute = (RouteEntry) other; | ||
84 | + return Objects.equals(this.prefix, otherRoute.prefix) && | ||
85 | + Objects.equals(this.nextHop, otherRoute.nextHop); | ||
86 | + } | ||
87 | + | ||
88 | + @Override | ||
89 | + public int hashCode() { | ||
90 | + return Objects.hash(prefix, nextHop); | ||
91 | + } | ||
92 | + | ||
93 | + @Override | ||
94 | + public String toString() { | ||
95 | + return MoreObjects.toStringHelper(getClass()) | ||
96 | + .add("prefix", prefix) | ||
97 | + .add("nextHop", nextHop) | ||
98 | + .toString(); | ||
99 | + } | ||
100 | +} |
1 | +package org.onlab.onos.sdnip; | ||
2 | + | ||
3 | +/** | ||
4 | + * An interface to receive route updates from route providers. | ||
5 | + */ | ||
6 | +public interface RouteListener { | ||
7 | + /** | ||
8 | + * Receives a route update from a route provider. | ||
9 | + * | ||
10 | + * @param routeUpdate the updated route information | ||
11 | + */ | ||
12 | + public void update(RouteUpdate routeUpdate); | ||
13 | +} |
1 | +package org.onlab.onos.sdnip; | ||
2 | + | ||
3 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
4 | + | ||
5 | +import java.util.Objects; | ||
6 | + | ||
7 | +import com.google.common.base.MoreObjects; | ||
8 | + | ||
9 | +/** | ||
10 | + * Represents a change in routing information. | ||
11 | + */ | ||
12 | +public class RouteUpdate { | ||
13 | + private final Type type; // The route update type | ||
14 | + private final RouteEntry routeEntry; // The updated route entry | ||
15 | + | ||
16 | + /** | ||
17 | + * Specifies the type of a route update. | ||
18 | + * <p/> | ||
19 | + * Route updates can either provide updated information for a route, or | ||
20 | + * withdraw a previously updated route. | ||
21 | + */ | ||
22 | + public enum Type { | ||
23 | + /** | ||
24 | + * The update contains updated route information for a route. | ||
25 | + */ | ||
26 | + UPDATE, | ||
27 | + /** | ||
28 | + * The update withdraws the route, meaning any previous information is | ||
29 | + * no longer valid. | ||
30 | + */ | ||
31 | + DELETE | ||
32 | + } | ||
33 | + | ||
34 | + /** | ||
35 | + * Class constructor. | ||
36 | + * | ||
37 | + * @param type the type of the route update | ||
38 | + * @param routeEntry the route entry with the update | ||
39 | + */ | ||
40 | + public RouteUpdate(Type type, RouteEntry routeEntry) { | ||
41 | + this.type = type; | ||
42 | + this.routeEntry = checkNotNull(routeEntry); | ||
43 | + } | ||
44 | + | ||
45 | + /** | ||
46 | + * Returns the type of the route update. | ||
47 | + * | ||
48 | + * @return the type of the update | ||
49 | + */ | ||
50 | + public Type type() { | ||
51 | + return type; | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
55 | + * Returns the route entry the route update is for. | ||
56 | + * | ||
57 | + * @return the route entry the route update is for | ||
58 | + */ | ||
59 | + public RouteEntry routeEntry() { | ||
60 | + return routeEntry; | ||
61 | + } | ||
62 | + | ||
63 | + @Override | ||
64 | + public boolean equals(Object other) { | ||
65 | + if (other == this) { | ||
66 | + return true; | ||
67 | + } | ||
68 | + | ||
69 | + if (!(other instanceof RouteUpdate)) { | ||
70 | + return false; | ||
71 | + } | ||
72 | + | ||
73 | + RouteUpdate otherUpdate = (RouteUpdate) other; | ||
74 | + | ||
75 | + return Objects.equals(this.type, otherUpdate.type) && | ||
76 | + Objects.equals(this.routeEntry, otherUpdate.routeEntry); | ||
77 | + } | ||
78 | + | ||
79 | + @Override | ||
80 | + public int hashCode() { | ||
81 | + return Objects.hash(type, routeEntry); | ||
82 | + } | ||
83 | + | ||
84 | + @Override | ||
85 | + public String toString() { | ||
86 | + return MoreObjects.toStringHelper(getClass()) | ||
87 | + .add("type", type) | ||
88 | + .add("routeEntry", routeEntry) | ||
89 | + .toString(); | ||
90 | + } | ||
91 | +} |
This diff is collapsed. Click to expand it.
... | @@ -2,21 +2,30 @@ package org.onlab.onos.sdnip; | ... | @@ -2,21 +2,30 @@ package org.onlab.onos.sdnip; |
2 | 2 | ||
3 | import static org.slf4j.LoggerFactory.getLogger; | 3 | import static org.slf4j.LoggerFactory.getLogger; |
4 | 4 | ||
5 | +import java.util.Collection; | ||
6 | + | ||
5 | import org.apache.felix.scr.annotations.Activate; | 7 | import org.apache.felix.scr.annotations.Activate; |
6 | import org.apache.felix.scr.annotations.Component; | 8 | import org.apache.felix.scr.annotations.Component; |
7 | import org.apache.felix.scr.annotations.Deactivate; | 9 | import org.apache.felix.scr.annotations.Deactivate; |
8 | import org.apache.felix.scr.annotations.Reference; | 10 | import org.apache.felix.scr.annotations.Reference; |
9 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 11 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
12 | +import org.apache.felix.scr.annotations.Service; | ||
10 | import org.onlab.onos.net.host.HostService; | 13 | import org.onlab.onos.net.host.HostService; |
11 | import org.onlab.onos.net.intent.IntentService; | 14 | import org.onlab.onos.net.intent.IntentService; |
15 | +import org.onlab.onos.sdnip.RouteUpdate.Type; | ||
16 | +import org.onlab.onos.sdnip.bgp.BgpRouteEntry; | ||
17 | +import org.onlab.onos.sdnip.bgp.BgpSessionManager; | ||
12 | import org.onlab.onos.sdnip.config.SdnIpConfigReader; | 18 | import org.onlab.onos.sdnip.config.SdnIpConfigReader; |
19 | +import org.onlab.packet.IpAddress; | ||
20 | +import org.onlab.packet.IpPrefix; | ||
13 | import org.slf4j.Logger; | 21 | import org.slf4j.Logger; |
14 | 22 | ||
15 | /** | 23 | /** |
16 | - * Placeholder SDN-IP component. | 24 | + * Component for the SDN-IP peering application. |
17 | */ | 25 | */ |
18 | @Component(immediate = true) | 26 | @Component(immediate = true) |
19 | -public class SdnIp { | 27 | +@Service |
28 | +public class SdnIp implements SdnIpService { | ||
20 | 29 | ||
21 | private final Logger log = getLogger(getClass()); | 30 | private final Logger log = getLogger(getClass()); |
22 | 31 | ||
... | @@ -27,7 +36,9 @@ public class SdnIp { | ... | @@ -27,7 +36,9 @@ public class SdnIp { |
27 | protected HostService hostService; | 36 | protected HostService hostService; |
28 | 37 | ||
29 | private SdnIpConfigReader config; | 38 | private SdnIpConfigReader config; |
30 | - private PeerConnectivity peerConnectivity; | 39 | + private PeerConnectivityManager peerConnectivity; |
40 | + private Router router; | ||
41 | + private BgpSessionManager bgpSessionManager; | ||
31 | 42 | ||
32 | @Activate | 43 | @Activate |
33 | protected void activate() { | 44 | protected void activate() { |
... | @@ -36,15 +47,40 @@ public class SdnIp { | ... | @@ -36,15 +47,40 @@ public class SdnIp { |
36 | config = new SdnIpConfigReader(); | 47 | config = new SdnIpConfigReader(); |
37 | config.init(); | 48 | config.init(); |
38 | 49 | ||
39 | - InterfaceService interfaceService = new HostServiceBasedInterfaceService(hostService); | 50 | + InterfaceService interfaceService = new HostToInterfaceAdaptor(hostService); |
40 | 51 | ||
41 | - peerConnectivity = new PeerConnectivity(config, interfaceService, intentService); | 52 | + peerConnectivity = new PeerConnectivityManager(config, interfaceService, intentService); |
42 | peerConnectivity.start(); | 53 | peerConnectivity.start(); |
43 | 54 | ||
55 | + router = new Router(intentService, hostService, config, interfaceService); | ||
56 | + router.start(); | ||
57 | + | ||
58 | + bgpSessionManager = new BgpSessionManager(router); | ||
59 | + bgpSessionManager.startUp(2000); // TODO | ||
60 | + | ||
61 | + // TODO need to disable link discovery on external ports | ||
62 | + | ||
63 | + router.update(new RouteUpdate(Type.UPDATE, new RouteEntry( | ||
64 | + IpPrefix.valueOf("172.16.20.0/24"), | ||
65 | + IpAddress.valueOf("192.168.10.1")))); | ||
44 | } | 66 | } |
45 | 67 | ||
46 | @Deactivate | 68 | @Deactivate |
47 | protected void deactivate() { | 69 | protected void deactivate() { |
48 | log.info("Stopped"); | 70 | log.info("Stopped"); |
49 | } | 71 | } |
72 | + | ||
73 | + @Override | ||
74 | + public Collection<BgpRouteEntry> getBgpRoutes() { | ||
75 | + return bgpSessionManager.getBgpRoutes(); | ||
76 | + } | ||
77 | + | ||
78 | + @Override | ||
79 | + public Collection<RouteEntry> getRoutes() { | ||
80 | + return router.getRoutes(); | ||
81 | + } | ||
82 | + | ||
83 | + static String dpidToUri(String dpid) { | ||
84 | + return "of:" + dpid.replace(":", ""); | ||
85 | + } | ||
50 | } | 86 | } | ... | ... |
1 | +package org.onlab.onos.sdnip; | ||
2 | + | ||
3 | +import java.util.Collection; | ||
4 | + | ||
5 | +import org.onlab.onos.sdnip.bgp.BgpRouteEntry; | ||
6 | + | ||
7 | +/** | ||
8 | + * Service interface exported by SDN-IP. | ||
9 | + */ | ||
10 | +public interface SdnIpService { | ||
11 | + /** | ||
12 | + * Gets the BGP routes. | ||
13 | + * | ||
14 | + * @return the BGP routes | ||
15 | + */ | ||
16 | + public Collection<BgpRouteEntry> getBgpRoutes(); | ||
17 | + | ||
18 | + /** | ||
19 | + * Gets all the routes known to SDN-IP. | ||
20 | + * | ||
21 | + * @return the SDN-IP routes | ||
22 | + */ | ||
23 | + public Collection<RouteEntry> getRoutes(); | ||
24 | +} |
This diff is collapsed. Click to expand it.
1 | +package org.onlab.onos.sdnip.bgp; | ||
2 | + | ||
3 | +import org.jboss.netty.buffer.ChannelBuffer; | ||
4 | +import org.jboss.netty.buffer.ChannelBuffers; | ||
5 | +import org.jboss.netty.channel.Channel; | ||
6 | +import org.jboss.netty.channel.ChannelHandlerContext; | ||
7 | +import org.jboss.netty.handler.codec.frame.FrameDecoder; | ||
8 | +import org.onlab.onos.sdnip.bgp.BgpConstants.Notifications.MessageHeaderError; | ||
9 | +import org.slf4j.Logger; | ||
10 | +import org.slf4j.LoggerFactory; | ||
11 | + | ||
12 | +/** | ||
13 | + * Class for handling the decoding of the BGP messages. | ||
14 | + */ | ||
15 | +class BgpFrameDecoder extends FrameDecoder { | ||
16 | + private static final Logger log = | ||
17 | + LoggerFactory.getLogger(BgpFrameDecoder.class); | ||
18 | + | ||
19 | + private final BgpSession bgpSession; | ||
20 | + | ||
21 | + /** | ||
22 | + * Constructor for a given BGP Session. | ||
23 | + * | ||
24 | + * @param bgpSession the BGP session state to use. | ||
25 | + */ | ||
26 | + BgpFrameDecoder(BgpSession bgpSession) { | ||
27 | + this.bgpSession = bgpSession; | ||
28 | + } | ||
29 | + | ||
30 | + @Override | ||
31 | + protected Object decode(ChannelHandlerContext ctx, | ||
32 | + Channel channel, | ||
33 | + ChannelBuffer buf) throws Exception { | ||
34 | + // | ||
35 | + // NOTE: If we close the channel during the decoding, we might still | ||
36 | + // see some incoming messages while the channel closing is completed. | ||
37 | + // | ||
38 | + if (bgpSession.isClosed()) { | ||
39 | + return null; | ||
40 | + } | ||
41 | + | ||
42 | + log.trace("BGP Peer: decode(): remoteAddr = {} localAddr = {} " + | ||
43 | + "messageSize = {}", | ||
44 | + ctx.getChannel().getRemoteAddress(), | ||
45 | + ctx.getChannel().getLocalAddress(), | ||
46 | + buf.readableBytes()); | ||
47 | + | ||
48 | + // Test for minimum length of the BGP message | ||
49 | + if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) { | ||
50 | + // No enough data received | ||
51 | + return null; | ||
52 | + } | ||
53 | + | ||
54 | + // | ||
55 | + // Mark the current buffer position in case we haven't received | ||
56 | + // the whole message. | ||
57 | + // | ||
58 | + buf.markReaderIndex(); | ||
59 | + | ||
60 | + // | ||
61 | + // Read and check the BGP message Marker field: it must be all ones | ||
62 | + // (See RFC 4271, Section 4.1) | ||
63 | + // | ||
64 | + byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH]; | ||
65 | + buf.readBytes(marker); | ||
66 | + for (int i = 0; i < marker.length; i++) { | ||
67 | + if (marker[i] != (byte) 0xff) { | ||
68 | + log.debug("BGP RX Error: invalid marker {} at position {}", | ||
69 | + marker[i], i); | ||
70 | + // | ||
71 | + // ERROR: Connection Not Synchronized | ||
72 | + // | ||
73 | + // Send NOTIFICATION and close the connection | ||
74 | + int errorCode = MessageHeaderError.ERROR_CODE; | ||
75 | + int errorSubcode = | ||
76 | + MessageHeaderError.CONNECTION_NOT_SYNCHRONIZED; | ||
77 | + ChannelBuffer txMessage = | ||
78 | + bgpSession.prepareBgpNotification(errorCode, errorSubcode, | ||
79 | + null); | ||
80 | + ctx.getChannel().write(txMessage); | ||
81 | + bgpSession.closeChannel(ctx); | ||
82 | + return null; | ||
83 | + } | ||
84 | + } | ||
85 | + | ||
86 | + // | ||
87 | + // Read and check the BGP message Length field | ||
88 | + // | ||
89 | + int length = buf.readUnsignedShort(); | ||
90 | + if ((length < BgpConstants.BGP_HEADER_LENGTH) || | ||
91 | + (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) { | ||
92 | + log.debug("BGP RX Error: invalid Length field {}. " + | ||
93 | + "Must be between {} and {}", | ||
94 | + length, | ||
95 | + BgpConstants.BGP_HEADER_LENGTH, | ||
96 | + BgpConstants.BGP_MESSAGE_MAX_LENGTH); | ||
97 | + // | ||
98 | + // ERROR: Bad Message Length | ||
99 | + // | ||
100 | + // Send NOTIFICATION and close the connection | ||
101 | + ChannelBuffer txMessage = | ||
102 | + bgpSession.prepareBgpNotificationBadMessageLength(length); | ||
103 | + ctx.getChannel().write(txMessage); | ||
104 | + bgpSession.closeChannel(ctx); | ||
105 | + return null; | ||
106 | + } | ||
107 | + | ||
108 | + // | ||
109 | + // Test whether the rest of the message is received: | ||
110 | + // So far we have read the Marker (16 octets) and the | ||
111 | + // Length (2 octets) fields. | ||
112 | + // | ||
113 | + int remainingMessageLen = | ||
114 | + length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2; | ||
115 | + if (buf.readableBytes() < remainingMessageLen) { | ||
116 | + // No enough data received | ||
117 | + buf.resetReaderIndex(); | ||
118 | + return null; | ||
119 | + } | ||
120 | + | ||
121 | + // | ||
122 | + // Read the BGP message Type field, and process based on that type | ||
123 | + // | ||
124 | + int type = buf.readUnsignedByte(); | ||
125 | + remainingMessageLen--; // Adjust after reading the type | ||
126 | + ChannelBuffer message = buf.readBytes(remainingMessageLen); | ||
127 | + | ||
128 | + // | ||
129 | + // Process the remaining of the message based on the message type | ||
130 | + // | ||
131 | + switch (type) { | ||
132 | + case BgpConstants.BGP_TYPE_OPEN: | ||
133 | + bgpSession.processBgpOpen(ctx, message); | ||
134 | + break; | ||
135 | + case BgpConstants.BGP_TYPE_UPDATE: | ||
136 | + bgpSession.processBgpUpdate(ctx, message); | ||
137 | + break; | ||
138 | + case BgpConstants.BGP_TYPE_NOTIFICATION: | ||
139 | + bgpSession.processBgpNotification(ctx, message); | ||
140 | + break; | ||
141 | + case BgpConstants.BGP_TYPE_KEEPALIVE: | ||
142 | + bgpSession.processBgpKeepalive(ctx, message); | ||
143 | + break; | ||
144 | + default: | ||
145 | + // | ||
146 | + // ERROR: Bad Message Type | ||
147 | + // | ||
148 | + // Send NOTIFICATION and close the connection | ||
149 | + int errorCode = MessageHeaderError.ERROR_CODE; | ||
150 | + int errorSubcode = MessageHeaderError.BAD_MESSAGE_TYPE; | ||
151 | + ChannelBuffer data = ChannelBuffers.buffer(1); | ||
152 | + data.writeByte(type); | ||
153 | + ChannelBuffer txMessage = | ||
154 | + bgpSession.prepareBgpNotification(errorCode, errorSubcode, | ||
155 | + data); | ||
156 | + ctx.getChannel().write(txMessage); | ||
157 | + bgpSession.closeChannel(ctx); | ||
158 | + return null; | ||
159 | + } | ||
160 | + return null; | ||
161 | + } | ||
162 | +} |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 | +package org.onlab.onos.sdnip.cli; | ||
2 | + | ||
3 | +import org.apache.karaf.shell.commands.Command; | ||
4 | +import org.onlab.onos.cli.AbstractShellCommand; | ||
5 | +import org.onlab.onos.sdnip.SdnIpService; | ||
6 | +import org.onlab.onos.sdnip.bgp.BgpConstants; | ||
7 | +import org.onlab.onos.sdnip.bgp.BgpRouteEntry; | ||
8 | + | ||
9 | +/** | ||
10 | + * Command to show the routes learned through BGP. | ||
11 | + */ | ||
12 | +@Command(scope = "onos", name = "bgp-routes", | ||
13 | + description = "Lists all routes received from BGP") | ||
14 | +public class BgpRoutesListCommand extends AbstractShellCommand { | ||
15 | + | ||
16 | + private static final String FORMAT = | ||
17 | + "prefix=%s, nexthop=%s, origin=%s, localpref=%s, med=%s, aspath=%s, bgpid=%s"; | ||
18 | + | ||
19 | + @Override | ||
20 | + protected void execute() { | ||
21 | + SdnIpService service = get(SdnIpService.class); | ||
22 | + | ||
23 | + for (BgpRouteEntry route : service.getBgpRoutes()) { | ||
24 | + printRoute(route); | ||
25 | + } | ||
26 | + } | ||
27 | + | ||
28 | + private void printRoute(BgpRouteEntry route) { | ||
29 | + if (route != null) { | ||
30 | + print(FORMAT, route.prefix(), route.nextHop(), | ||
31 | + originToString(route.getOrigin()), route.getLocalPref(), | ||
32 | + route.getMultiExitDisc(), route.getAsPath(), | ||
33 | + route.getBgpSession().getRemoteBgpId()); | ||
34 | + } | ||
35 | + } | ||
36 | + | ||
37 | + private static String originToString(int origin) { | ||
38 | + String originString = "UNKNOWN"; | ||
39 | + | ||
40 | + switch (origin) { | ||
41 | + case BgpConstants.Update.Origin.IGP: | ||
42 | + originString = "IGP"; | ||
43 | + break; | ||
44 | + case BgpConstants.Update.Origin.EGP: | ||
45 | + originString = "EGP"; | ||
46 | + break; | ||
47 | + case BgpConstants.Update.Origin.INCOMPLETE: | ||
48 | + originString = "INCOMPLETE"; | ||
49 | + break; | ||
50 | + default: | ||
51 | + break; | ||
52 | + } | ||
53 | + | ||
54 | + return originString; | ||
55 | + } | ||
56 | + | ||
57 | +} |
1 | +package org.onlab.onos.sdnip.cli; | ||
2 | + | ||
3 | +import org.apache.karaf.shell.commands.Command; | ||
4 | +import org.onlab.onos.cli.AbstractShellCommand; | ||
5 | +import org.onlab.onos.sdnip.RouteEntry; | ||
6 | +import org.onlab.onos.sdnip.SdnIpService; | ||
7 | + | ||
8 | +/** | ||
9 | + * Command to show the list of routes in SDN-IP's routing table. | ||
10 | + */ | ||
11 | +@Command(scope = "onos", name = "routes", | ||
12 | + description = "Lists all routes known to SDN-IP") | ||
13 | +public class RoutesListCommand extends AbstractShellCommand { | ||
14 | + | ||
15 | + private static final String FORMAT = | ||
16 | + "prefix=%s, nexthop=%s"; | ||
17 | + | ||
18 | + @Override | ||
19 | + protected void execute() { | ||
20 | + SdnIpService service = get(SdnIpService.class); | ||
21 | + | ||
22 | + for (RouteEntry route : service.getRoutes()) { | ||
23 | + printRoute(route); | ||
24 | + } | ||
25 | + } | ||
26 | + | ||
27 | + private void printRoute(RouteEntry route) { | ||
28 | + if (route != null) { | ||
29 | + print(FORMAT, route.prefix(), route.nextHop()); | ||
30 | + } | ||
31 | + } | ||
32 | +} |
1 | +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> | ||
2 | + | ||
3 | + <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> | ||
4 | + <command> | ||
5 | + <action class="org.onlab.onos.sdnip.cli.BgpRoutesListCommand"/> | ||
6 | + </command> | ||
7 | + <command> | ||
8 | + <action class="org.onlab.onos.sdnip.cli.RoutesListCommand"/> | ||
9 | + </command> | ||
10 | + </command-bundle> | ||
11 | +</blueprint> |
This diff is collapsed. Click to expand it.
1 | +package org.onlab.onos.sdnip; | ||
2 | + | ||
3 | +import static org.hamcrest.Matchers.is; | ||
4 | +import static org.hamcrest.Matchers.not; | ||
5 | +import static org.junit.Assert.assertThat; | ||
6 | + | ||
7 | +import org.junit.Test; | ||
8 | +import org.onlab.packet.IpAddress; | ||
9 | +import org.onlab.packet.IpPrefix; | ||
10 | + | ||
11 | +/** | ||
12 | + * Unit tests for the RouteEntry class. | ||
13 | + */ | ||
14 | +public class RouteEntryTest { | ||
15 | + /** | ||
16 | + * Tests valid class constructor. | ||
17 | + */ | ||
18 | + @Test | ||
19 | + public void testConstructor() { | ||
20 | + IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24"); | ||
21 | + IpAddress nextHop = IpAddress.valueOf("5.6.7.8"); | ||
22 | + | ||
23 | + RouteEntry routeEntry = new RouteEntry(prefix, nextHop); | ||
24 | + assertThat(routeEntry.toString(), | ||
25 | + is("RouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8}")); | ||
26 | + } | ||
27 | + | ||
28 | + /** | ||
29 | + * Tests invalid class constructor for null IPv4 prefix. | ||
30 | + */ | ||
31 | + @Test(expected = NullPointerException.class) | ||
32 | + public void testInvalidConstructorNullPrefix() { | ||
33 | + IpPrefix prefix = null; | ||
34 | + IpAddress nextHop = IpAddress.valueOf("5.6.7.8"); | ||
35 | + | ||
36 | + new RouteEntry(prefix, nextHop); | ||
37 | + } | ||
38 | + | ||
39 | + /** | ||
40 | + * Tests invalid class constructor for null IPv4 next-hop. | ||
41 | + */ | ||
42 | + @Test(expected = NullPointerException.class) | ||
43 | + public void testInvalidConstructorNullNextHop() { | ||
44 | + IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24"); | ||
45 | + IpAddress nextHop = null; | ||
46 | + | ||
47 | + new RouteEntry(prefix, nextHop); | ||
48 | + } | ||
49 | + | ||
50 | + /** | ||
51 | + * Tests getting the fields of a route entry. | ||
52 | + */ | ||
53 | + @Test | ||
54 | + public void testGetFields() { | ||
55 | + IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24"); | ||
56 | + IpAddress nextHop = IpAddress.valueOf("5.6.7.8"); | ||
57 | + | ||
58 | + RouteEntry routeEntry = new RouteEntry(prefix, nextHop); | ||
59 | + assertThat(routeEntry.prefix(), is(prefix)); | ||
60 | + assertThat(routeEntry.nextHop(), is(nextHop)); | ||
61 | + } | ||
62 | + | ||
63 | + /** | ||
64 | + * Tests creating a binary string from IPv4 prefix. | ||
65 | + */ | ||
66 | + @Test | ||
67 | + public void testCreateBinaryString() { | ||
68 | + IpPrefix prefix; | ||
69 | + | ||
70 | + prefix = IpPrefix.valueOf("0.0.0.0/0"); | ||
71 | + assertThat(RouteEntry.createBinaryString(prefix), is("")); | ||
72 | + | ||
73 | + prefix = IpPrefix.valueOf("192.168.166.0/22"); | ||
74 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
75 | + is("1100000010101000101001")); | ||
76 | + | ||
77 | + prefix = IpPrefix.valueOf("192.168.166.0/23"); | ||
78 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
79 | + is("11000000101010001010011")); | ||
80 | + | ||
81 | + prefix = IpPrefix.valueOf("192.168.166.0/24"); | ||
82 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
83 | + is("110000001010100010100110")); | ||
84 | + | ||
85 | + prefix = IpPrefix.valueOf("130.162.10.1/25"); | ||
86 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
87 | + is("1000001010100010000010100")); | ||
88 | + | ||
89 | + prefix = IpPrefix.valueOf("255.255.255.255/32"); | ||
90 | + assertThat(RouteEntry.createBinaryString(prefix), | ||
91 | + is("11111111111111111111111111111111")); | ||
92 | + } | ||
93 | + | ||
94 | + /** | ||
95 | + * Tests equality of {@link RouteEntry}. | ||
96 | + */ | ||
97 | + @Test | ||
98 | + public void testEquality() { | ||
99 | + IpPrefix prefix1 = IpPrefix.valueOf("1.2.3.0/24"); | ||
100 | + IpAddress nextHop1 = IpAddress.valueOf("5.6.7.8"); | ||
101 | + RouteEntry routeEntry1 = new RouteEntry(prefix1, nextHop1); | ||
102 | + | ||
103 | + IpPrefix prefix2 = IpPrefix.valueOf("1.2.3.0/24"); | ||
104 | + IpAddress nextHop2 = IpAddress.valueOf("5.6.7.8"); | ||
105 | + RouteEntry routeEntry2 = new RouteEntry(prefix2, nextHop2); | ||
106 | + | ||
107 | + assertThat(routeEntry1, is(routeEntry2)); | ||
108 | + } | ||
109 | + | ||
110 | + /** | ||
111 | + * Tests non-equality of {@link RouteEntry}. | ||
112 | + */ | ||
113 | + @Test | ||
114 | + public void testNonEquality() { | ||
115 | + IpPrefix prefix1 = IpPrefix.valueOf("1.2.3.0/24"); | ||
116 | + IpAddress nextHop1 = IpAddress.valueOf("5.6.7.8"); | ||
117 | + RouteEntry routeEntry1 = new RouteEntry(prefix1, nextHop1); | ||
118 | + | ||
119 | + IpPrefix prefix2 = IpPrefix.valueOf("1.2.3.0/25"); // Different | ||
120 | + IpAddress nextHop2 = IpAddress.valueOf("5.6.7.8"); | ||
121 | + RouteEntry routeEntry2 = new RouteEntry(prefix2, nextHop2); | ||
122 | + | ||
123 | + IpPrefix prefix3 = IpPrefix.valueOf("1.2.3.0/24"); | ||
124 | + IpAddress nextHop3 = IpAddress.valueOf("5.6.7.9"); // Different | ||
125 | + RouteEntry routeEntry3 = new RouteEntry(prefix3, nextHop3); | ||
126 | + | ||
127 | + assertThat(routeEntry1, is(not(routeEntry2))); | ||
128 | + assertThat(routeEntry1, is(not(routeEntry3))); | ||
129 | + } | ||
130 | + | ||
131 | + /** | ||
132 | + * Tests object string representation. | ||
133 | + */ | ||
134 | + @Test | ||
135 | + public void testToString() { | ||
136 | + IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24"); | ||
137 | + IpAddress nextHop = IpAddress.valueOf("5.6.7.8"); | ||
138 | + RouteEntry routeEntry = new RouteEntry(prefix, nextHop); | ||
139 | + | ||
140 | + assertThat(routeEntry.toString(), | ||
141 | + is("RouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8}")); | ||
142 | + } | ||
143 | +} |
1 | +package org.onlab.onos.sdnip.bgp; | ||
2 | + | ||
3 | +import static org.hamcrest.Matchers.is; | ||
4 | +import static org.hamcrest.Matchers.not; | ||
5 | +import static org.junit.Assert.assertThat; | ||
6 | + | ||
7 | +import java.util.ArrayList; | ||
8 | + | ||
9 | +import org.junit.Test; | ||
10 | + | ||
11 | +/** | ||
12 | + * Unit tests for the BgpRouteEntry.AsPath class. | ||
13 | + */ | ||
14 | +public class AsPathTest { | ||
15 | + /** | ||
16 | + * Generates an AS Path. | ||
17 | + * | ||
18 | + * @return a generated AS Path | ||
19 | + */ | ||
20 | + private BgpRouteEntry.AsPath generateAsPath() { | ||
21 | + ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); | ||
22 | + byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | ||
23 | + ArrayList<Long> segmentAsNumbers1 = new ArrayList<>(); | ||
24 | + segmentAsNumbers1.add((long) 1); | ||
25 | + segmentAsNumbers1.add((long) 2); | ||
26 | + segmentAsNumbers1.add((long) 3); | ||
27 | + BgpRouteEntry.PathSegment pathSegment1 = | ||
28 | + new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1); | ||
29 | + pathSegments.add(pathSegment1); | ||
30 | + // | ||
31 | + byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET; | ||
32 | + ArrayList<Long> segmentAsNumbers2 = new ArrayList<>(); | ||
33 | + segmentAsNumbers2.add((long) 4); | ||
34 | + segmentAsNumbers2.add((long) 5); | ||
35 | + segmentAsNumbers2.add((long) 6); | ||
36 | + BgpRouteEntry.PathSegment pathSegment2 = | ||
37 | + new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2); | ||
38 | + pathSegments.add(pathSegment2); | ||
39 | + // | ||
40 | + BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments); | ||
41 | + | ||
42 | + return asPath; | ||
43 | + } | ||
44 | + | ||
45 | + /** | ||
46 | + * Tests valid class constructor. | ||
47 | + */ | ||
48 | + @Test | ||
49 | + public void testConstructor() { | ||
50 | + BgpRouteEntry.AsPath asPath = generateAsPath(); | ||
51 | + | ||
52 | + String expectedString = | ||
53 | + "AsPath{pathSegments=" + | ||
54 | + "[PathSegment{type=2, segmentAsNumbers=[1, 2, 3]}, " + | ||
55 | + "PathSegment{type=1, segmentAsNumbers=[4, 5, 6]}]}"; | ||
56 | + assertThat(asPath.toString(), is(expectedString)); | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * Tests invalid class constructor for null Path Segments. | ||
61 | + */ | ||
62 | + @Test(expected = NullPointerException.class) | ||
63 | + public void testInvalidConstructorNullPathSegments() { | ||
64 | + ArrayList<BgpRouteEntry.PathSegment> pathSegments = null; | ||
65 | + new BgpRouteEntry.AsPath(pathSegments); | ||
66 | + } | ||
67 | + | ||
68 | + /** | ||
69 | + * Tests getting the fields of an AS Path. | ||
70 | + */ | ||
71 | + @Test | ||
72 | + public void testGetFields() { | ||
73 | + // Create the fields to compare against | ||
74 | + ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); | ||
75 | + byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | ||
76 | + ArrayList<Long> segmentAsNumbers1 = new ArrayList<>(); | ||
77 | + segmentAsNumbers1.add((long) 1); | ||
78 | + segmentAsNumbers1.add((long) 2); | ||
79 | + segmentAsNumbers1.add((long) 3); | ||
80 | + BgpRouteEntry.PathSegment pathSegment1 = | ||
81 | + new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1); | ||
82 | + pathSegments.add(pathSegment1); | ||
83 | + // | ||
84 | + byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET; | ||
85 | + ArrayList<Long> segmentAsNumbers2 = new ArrayList<>(); | ||
86 | + segmentAsNumbers2.add((long) 4); | ||
87 | + segmentAsNumbers2.add((long) 5); | ||
88 | + segmentAsNumbers2.add((long) 6); | ||
89 | + BgpRouteEntry.PathSegment pathSegment2 = | ||
90 | + new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2); | ||
91 | + pathSegments.add(pathSegment2); | ||
92 | + | ||
93 | + // Generate the entry to test | ||
94 | + BgpRouteEntry.AsPath asPath = generateAsPath(); | ||
95 | + | ||
96 | + assertThat(asPath.getPathSegments(), is(pathSegments)); | ||
97 | + } | ||
98 | + | ||
99 | + /** | ||
100 | + * Tests getting the AS Path Length. | ||
101 | + */ | ||
102 | + @Test | ||
103 | + public void testGetAsPathLength() { | ||
104 | + BgpRouteEntry.AsPath asPath = generateAsPath(); | ||
105 | + assertThat(asPath.getAsPathLength(), is(4)); | ||
106 | + | ||
107 | + // Create an empty AS Path | ||
108 | + ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); | ||
109 | + asPath = new BgpRouteEntry.AsPath(pathSegments); | ||
110 | + assertThat(asPath.getAsPathLength(), is(0)); | ||
111 | + } | ||
112 | + | ||
113 | + /** | ||
114 | + * Tests equality of {@link BgpRouteEntry.AsPath}. | ||
115 | + */ | ||
116 | + @Test | ||
117 | + public void testEquality() { | ||
118 | + BgpRouteEntry.AsPath asPath1 = generateAsPath(); | ||
119 | + BgpRouteEntry.AsPath asPath2 = generateAsPath(); | ||
120 | + | ||
121 | + assertThat(asPath1, is(asPath2)); | ||
122 | + } | ||
123 | + | ||
124 | + /** | ||
125 | + * Tests non-equality of {@link BgpRouteEntry.AsPath}. | ||
126 | + */ | ||
127 | + @Test | ||
128 | + public void testNonEquality() { | ||
129 | + BgpRouteEntry.AsPath asPath1 = generateAsPath(); | ||
130 | + | ||
131 | + // Setup AS Path 2 | ||
132 | + ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>(); | ||
133 | + byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | ||
134 | + ArrayList<Long> segmentAsNumbers1 = new ArrayList<>(); | ||
135 | + segmentAsNumbers1.add((long) 1); | ||
136 | + segmentAsNumbers1.add((long) 2); | ||
137 | + segmentAsNumbers1.add((long) 3); | ||
138 | + BgpRouteEntry.PathSegment pathSegment1 = | ||
139 | + new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1); | ||
140 | + pathSegments.add(pathSegment1); | ||
141 | + // | ||
142 | + byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET; | ||
143 | + ArrayList<Long> segmentAsNumbers2 = new ArrayList<>(); | ||
144 | + segmentAsNumbers2.add((long) 4); | ||
145 | + segmentAsNumbers2.add((long) 55); // Different | ||
146 | + segmentAsNumbers2.add((long) 6); | ||
147 | + BgpRouteEntry.PathSegment pathSegment2 = | ||
148 | + new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2); | ||
149 | + pathSegments.add(pathSegment2); | ||
150 | + // | ||
151 | + BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments); | ||
152 | + | ||
153 | + assertThat(asPath1, is(not(asPath2))); | ||
154 | + } | ||
155 | + | ||
156 | + /** | ||
157 | + * Tests object string representation. | ||
158 | + */ | ||
159 | + @Test | ||
160 | + public void testToString() { | ||
161 | + BgpRouteEntry.AsPath asPath = generateAsPath(); | ||
162 | + | ||
163 | + String expectedString = | ||
164 | + "AsPath{pathSegments=" + | ||
165 | + "[PathSegment{type=2, segmentAsNumbers=[1, 2, 3]}, " + | ||
166 | + "PathSegment{type=1, segmentAsNumbers=[4, 5, 6]}]}"; | ||
167 | + assertThat(asPath.toString(), is(expectedString)); | ||
168 | + } | ||
169 | +} |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 | +package org.onlab.onos.sdnip.bgp; | ||
2 | + | ||
3 | +import static org.hamcrest.Matchers.is; | ||
4 | +import static org.hamcrest.Matchers.not; | ||
5 | +import static org.junit.Assert.assertThat; | ||
6 | + | ||
7 | +import java.util.ArrayList; | ||
8 | + | ||
9 | +import org.junit.Test; | ||
10 | + | ||
11 | +/** | ||
12 | + * Unit tests for the BgpRouteEntry.PathSegment class. | ||
13 | + */ | ||
14 | +public class PathSegmentTest { | ||
15 | + /** | ||
16 | + * Generates a Path Segment. | ||
17 | + * | ||
18 | + * @return a generated PathSegment | ||
19 | + */ | ||
20 | + private BgpRouteEntry.PathSegment generatePathSegment() { | ||
21 | + byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | ||
22 | + ArrayList<Long> segmentAsNumbers = new ArrayList<>(); | ||
23 | + segmentAsNumbers.add((long) 1); | ||
24 | + segmentAsNumbers.add((long) 2); | ||
25 | + segmentAsNumbers.add((long) 3); | ||
26 | + BgpRouteEntry.PathSegment pathSegment = | ||
27 | + new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); | ||
28 | + | ||
29 | + return pathSegment; | ||
30 | + } | ||
31 | + | ||
32 | + /** | ||
33 | + * Tests valid class constructor. | ||
34 | + */ | ||
35 | + @Test | ||
36 | + public void testConstructor() { | ||
37 | + BgpRouteEntry.PathSegment pathSegment = generatePathSegment(); | ||
38 | + | ||
39 | + String expectedString = | ||
40 | + "PathSegment{type=2, segmentAsNumbers=[1, 2, 3]}"; | ||
41 | + assertThat(pathSegment.toString(), is(expectedString)); | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Tests invalid class constructor for null Segment AS Numbers. | ||
46 | + */ | ||
47 | + @Test(expected = NullPointerException.class) | ||
48 | + public void testInvalidConstructorNullSegmentAsNumbers() { | ||
49 | + byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | ||
50 | + ArrayList<Long> segmentAsNumbers = null; | ||
51 | + new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
55 | + * Tests getting the fields of a Path Segment. | ||
56 | + */ | ||
57 | + @Test | ||
58 | + public void testGetFields() { | ||
59 | + // Create the fields to compare against | ||
60 | + byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | ||
61 | + ArrayList<Long> segmentAsNumbers = new ArrayList<>(); | ||
62 | + segmentAsNumbers.add((long) 1); | ||
63 | + segmentAsNumbers.add((long) 2); | ||
64 | + segmentAsNumbers.add((long) 3); | ||
65 | + | ||
66 | + // Generate the entry to test | ||
67 | + BgpRouteEntry.PathSegment pathSegment = generatePathSegment(); | ||
68 | + | ||
69 | + assertThat(pathSegment.getType(), is(pathSegmentType)); | ||
70 | + assertThat(pathSegment.getSegmentAsNumbers(), is(segmentAsNumbers)); | ||
71 | + } | ||
72 | + | ||
73 | + /** | ||
74 | + * Tests equality of {@link BgpRouteEntry.PathSegment}. | ||
75 | + */ | ||
76 | + @Test | ||
77 | + public void testEquality() { | ||
78 | + BgpRouteEntry.PathSegment pathSegment1 = generatePathSegment(); | ||
79 | + BgpRouteEntry.PathSegment pathSegment2 = generatePathSegment(); | ||
80 | + | ||
81 | + assertThat(pathSegment1, is(pathSegment2)); | ||
82 | + } | ||
83 | + | ||
84 | + /** | ||
85 | + * Tests non-equality of {@link BgpRouteEntry.PathSegment}. | ||
86 | + */ | ||
87 | + @Test | ||
88 | + public void testNonEquality() { | ||
89 | + BgpRouteEntry.PathSegment pathSegment1 = generatePathSegment(); | ||
90 | + | ||
91 | + // Setup Path Segment 2 | ||
92 | + byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | ||
93 | + ArrayList<Long> segmentAsNumbers = new ArrayList<>(); | ||
94 | + segmentAsNumbers.add((long) 1); | ||
95 | + segmentAsNumbers.add((long) 22); // Different | ||
96 | + segmentAsNumbers.add((long) 3); | ||
97 | + // | ||
98 | + BgpRouteEntry.PathSegment pathSegment2 = | ||
99 | + new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers); | ||
100 | + | ||
101 | + assertThat(pathSegment1, is(not(pathSegment2))); | ||
102 | + } | ||
103 | + | ||
104 | + /** | ||
105 | + * Tests object string representation. | ||
106 | + */ | ||
107 | + @Test | ||
108 | + public void testToString() { | ||
109 | + BgpRouteEntry.PathSegment pathSegment = generatePathSegment(); | ||
110 | + | ||
111 | + String expectedString = | ||
112 | + "PathSegment{type=2, segmentAsNumbers=[1, 2, 3]}"; | ||
113 | + assertThat(pathSegment.toString(), is(expectedString)); | ||
114 | + } | ||
115 | +} |
1 | +package org.onlab.onos.sdnip.bgp; | ||
2 | + | ||
3 | +import java.util.Collection; | ||
4 | + | ||
5 | +import org.jboss.netty.buffer.ChannelBuffer; | ||
6 | +import org.jboss.netty.buffer.ChannelBuffers; | ||
7 | +import org.jboss.netty.channel.ChannelHandlerContext; | ||
8 | +import org.jboss.netty.channel.ChannelStateEvent; | ||
9 | +import org.jboss.netty.channel.SimpleChannelHandler; | ||
10 | +import org.onlab.packet.IpAddress; | ||
11 | +import org.onlab.packet.IpPrefix; | ||
12 | + | ||
13 | +/** | ||
14 | + * Class for handling the remote BGP Peer session. | ||
15 | + */ | ||
16 | +class TestBgpPeerChannelHandler extends SimpleChannelHandler { | ||
17 | + static final long PEER_AS = 65001; | ||
18 | + static final int PEER_HOLDTIME = 120; // 120 seconds | ||
19 | + final IpAddress bgpId; // The BGP ID | ||
20 | + final long localPref; // Local preference for routes | ||
21 | + final long multiExitDisc = 20; // MED value | ||
22 | + | ||
23 | + ChannelHandlerContext savedCtx; | ||
24 | + | ||
25 | + /** | ||
26 | + * Constructor for given BGP ID. | ||
27 | + * | ||
28 | + * @param bgpId the BGP ID to use | ||
29 | + * @param localPref the local preference for the routes to use | ||
30 | + */ | ||
31 | + TestBgpPeerChannelHandler(IpAddress bgpId, | ||
32 | + long localPref) { | ||
33 | + this.bgpId = bgpId; | ||
34 | + this.localPref = localPref; | ||
35 | + } | ||
36 | + | ||
37 | + /** | ||
38 | + * Closes the channel. | ||
39 | + */ | ||
40 | + void closeChannel() { | ||
41 | + savedCtx.getChannel().close(); | ||
42 | + } | ||
43 | + | ||
44 | + @Override | ||
45 | + public void channelConnected(ChannelHandlerContext ctx, | ||
46 | + ChannelStateEvent channelEvent) { | ||
47 | + this.savedCtx = ctx; | ||
48 | + // Prepare and transmit BGP OPEN message | ||
49 | + ChannelBuffer message = prepareBgpOpen(); | ||
50 | + ctx.getChannel().write(message); | ||
51 | + | ||
52 | + // Prepare and transmit BGP KEEPALIVE message | ||
53 | + message = prepareBgpKeepalive(); | ||
54 | + ctx.getChannel().write(message); | ||
55 | + } | ||
56 | + | ||
57 | + @Override | ||
58 | + public void channelDisconnected(ChannelHandlerContext ctx, | ||
59 | + ChannelStateEvent channelEvent) { | ||
60 | + // Nothing to do | ||
61 | + } | ||
62 | + | ||
63 | + /** | ||
64 | + * Prepares BGP OPEN message. | ||
65 | + * | ||
66 | + * @return the message to transmit (BGP header included) | ||
67 | + */ | ||
68 | + ChannelBuffer prepareBgpOpen() { | ||
69 | + ChannelBuffer message = | ||
70 | + ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); | ||
71 | + message.writeByte(BgpConstants.BGP_VERSION); | ||
72 | + message.writeShort((int) PEER_AS); | ||
73 | + message.writeShort(PEER_HOLDTIME); | ||
74 | + message.writeInt(bgpId.toInt()); | ||
75 | + message.writeByte(0); // No Optional Parameters | ||
76 | + return prepareBgpMessage(BgpConstants.BGP_TYPE_OPEN, message); | ||
77 | + } | ||
78 | + | ||
79 | + /** | ||
80 | + * Prepares BGP UPDATE message. | ||
81 | + * | ||
82 | + * @param nextHopRouter the next-hop router address for the routes to add | ||
83 | + * @param addedRoutes the routes to add | ||
84 | + * @param withdrawnRoutes the routes to withdraw | ||
85 | + * @return the message to transmit (BGP header included) | ||
86 | + */ | ||
87 | + ChannelBuffer prepareBgpUpdate(IpAddress nextHopRouter, | ||
88 | + Collection<IpPrefix> addedRoutes, | ||
89 | + Collection<IpPrefix> withdrawnRoutes) { | ||
90 | + int attrFlags; | ||
91 | + ChannelBuffer message = | ||
92 | + ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); | ||
93 | + ChannelBuffer pathAttributes = | ||
94 | + ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); | ||
95 | + | ||
96 | + // Encode the Withdrawn Routes | ||
97 | + ChannelBuffer encodedPrefixes = encodePackedPrefixes(withdrawnRoutes); | ||
98 | + message.writeShort(encodedPrefixes.readableBytes()); | ||
99 | + message.writeBytes(encodedPrefixes); | ||
100 | + | ||
101 | + // Encode the Path Attributes | ||
102 | + // ORIGIN: IGP | ||
103 | + attrFlags = 0x40; // Transitive flag | ||
104 | + pathAttributes.writeByte(attrFlags); | ||
105 | + pathAttributes.writeByte(BgpConstants.Update.Origin.TYPE); | ||
106 | + pathAttributes.writeByte(1); // Data length | ||
107 | + pathAttributes.writeByte(BgpConstants.Update.Origin.IGP); | ||
108 | + // AS_PATH: Two Path Segments of 3 ASes each | ||
109 | + attrFlags = 0x40; // Transitive flag | ||
110 | + pathAttributes.writeByte(attrFlags); | ||
111 | + pathAttributes.writeByte(BgpConstants.Update.AsPath.TYPE); | ||
112 | + pathAttributes.writeByte(16); // Data length | ||
113 | + byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE; | ||
114 | + pathAttributes.writeByte(pathSegmentType1); | ||
115 | + pathAttributes.writeByte(3); // Three ASes | ||
116 | + pathAttributes.writeShort(65010); // AS=65010 | ||
117 | + pathAttributes.writeShort(65020); // AS=65020 | ||
118 | + pathAttributes.writeShort(65030); // AS=65030 | ||
119 | + byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET; | ||
120 | + pathAttributes.writeByte(pathSegmentType2); | ||
121 | + pathAttributes.writeByte(3); // Three ASes | ||
122 | + pathAttributes.writeShort(65041); // AS=65041 | ||
123 | + pathAttributes.writeShort(65042); // AS=65042 | ||
124 | + pathAttributes.writeShort(65043); // AS=65043 | ||
125 | + // NEXT_HOP: nextHopRouter | ||
126 | + attrFlags = 0x40; // Transitive flag | ||
127 | + pathAttributes.writeByte(attrFlags); | ||
128 | + pathAttributes.writeByte(BgpConstants.Update.NextHop.TYPE); | ||
129 | + pathAttributes.writeByte(4); // Data length | ||
130 | + pathAttributes.writeInt(nextHopRouter.toInt()); // Next-hop router | ||
131 | + // LOCAL_PREF: localPref | ||
132 | + attrFlags = 0x40; // Transitive flag | ||
133 | + pathAttributes.writeByte(attrFlags); | ||
134 | + pathAttributes.writeByte(BgpConstants.Update.LocalPref.TYPE); | ||
135 | + pathAttributes.writeByte(4); // Data length | ||
136 | + pathAttributes.writeInt((int) localPref); // Preference value | ||
137 | + // MULTI_EXIT_DISC: multiExitDisc | ||
138 | + attrFlags = 0x80; // Optional | ||
139 | + // Non-Transitive flag | ||
140 | + pathAttributes.writeByte(attrFlags); | ||
141 | + pathAttributes.writeByte(BgpConstants.Update.MultiExitDisc.TYPE); | ||
142 | + pathAttributes.writeByte(4); // Data length | ||
143 | + pathAttributes.writeInt((int) multiExitDisc); // Preference value | ||
144 | + // The NLRI prefixes | ||
145 | + encodedPrefixes = encodePackedPrefixes(addedRoutes); | ||
146 | + | ||
147 | + // Write the Path Attributes, beginning with its length | ||
148 | + message.writeShort(pathAttributes.readableBytes()); | ||
149 | + message.writeBytes(pathAttributes); | ||
150 | + message.writeBytes(encodedPrefixes); | ||
151 | + | ||
152 | + return prepareBgpMessage(BgpConstants.BGP_TYPE_UPDATE, message); | ||
153 | + } | ||
154 | + | ||
155 | + /** | ||
156 | + * Encodes a collection of IPv4 network prefixes in a packed format. | ||
157 | + * <p> | ||
158 | + * The IPv4 prefixes are encoded in the form: | ||
159 | + * <Length, Prefix> where Length is the length in bits of the IPv4 prefix, | ||
160 | + * and Prefix is the IPv4 prefix (padded with trailing bits to the end | ||
161 | + * of an octet). | ||
162 | + * | ||
163 | + * @param prefixes the prefixes to encode | ||
164 | + * @return the buffer with the encoded prefixes | ||
165 | + */ | ||
166 | + private ChannelBuffer encodePackedPrefixes(Collection<IpPrefix> prefixes) { | ||
167 | + ChannelBuffer message = | ||
168 | + ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); | ||
169 | + | ||
170 | + // Write each of the prefixes | ||
171 | + for (IpPrefix prefix : prefixes) { | ||
172 | + int prefixBitlen = prefix.prefixLength(); | ||
173 | + int prefixBytelen = (prefixBitlen + 7) / 8; // Round-up | ||
174 | + message.writeByte(prefixBitlen); | ||
175 | + | ||
176 | + IpAddress address = prefix.toIpAddress(); | ||
177 | + long value = address.toInt() & 0xffffffffL; | ||
178 | + for (int i = 0; i < IpAddress.INET_LEN; i++) { | ||
179 | + if (prefixBytelen-- == 0) { | ||
180 | + break; | ||
181 | + } | ||
182 | + long nextByte = | ||
183 | + (value >> ((IpAddress.INET_LEN - i - 1) * 8)) & 0xff; | ||
184 | + message.writeByte((int) nextByte); | ||
185 | + } | ||
186 | + } | ||
187 | + | ||
188 | + return message; | ||
189 | + } | ||
190 | + | ||
191 | + /** | ||
192 | + * Prepares BGP KEEPALIVE message. | ||
193 | + * | ||
194 | + * @return the message to transmit (BGP header included) | ||
195 | + */ | ||
196 | + ChannelBuffer prepareBgpKeepalive() { | ||
197 | + ChannelBuffer message = | ||
198 | + ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); | ||
199 | + return prepareBgpMessage(BgpConstants.BGP_TYPE_KEEPALIVE, message); | ||
200 | + } | ||
201 | + | ||
202 | + /** | ||
203 | + * Prepares BGP NOTIFICATION message. | ||
204 | + * | ||
205 | + * @param errorCode the BGP NOTIFICATION Error Code | ||
206 | + * @param errorSubcode the BGP NOTIFICATION Error Subcode if applicable, | ||
207 | + * otherwise BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC | ||
208 | + * @param payload the BGP NOTIFICATION Data if applicable, otherwise null | ||
209 | + * @return the message to transmit (BGP header included) | ||
210 | + */ | ||
211 | + ChannelBuffer prepareBgpNotification(int errorCode, int errorSubcode, | ||
212 | + ChannelBuffer data) { | ||
213 | + ChannelBuffer message = | ||
214 | + ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH); | ||
215 | + // Prepare the NOTIFICATION message payload | ||
216 | + message.writeByte(errorCode); | ||
217 | + message.writeByte(errorSubcode); | ||
218 | + if (data != null) { | ||
219 | + message.writeBytes(data); | ||
220 | + } | ||
221 | + return prepareBgpMessage(BgpConstants.BGP_TYPE_NOTIFICATION, message); | ||
222 | + } | ||
223 | + | ||
224 | + /** | ||
225 | + * Prepares BGP message. | ||
226 | + * | ||
227 | + * @param type the BGP message type | ||
228 | + * @param payload the message payload to transmit (BGP header excluded) | ||
229 | + * @return the message to transmit (BGP header included) | ||
230 | + */ | ||
231 | + private ChannelBuffer prepareBgpMessage(int type, ChannelBuffer payload) { | ||
232 | + ChannelBuffer message = | ||
233 | + ChannelBuffers.buffer(BgpConstants.BGP_HEADER_LENGTH + | ||
234 | + payload.readableBytes()); | ||
235 | + | ||
236 | + // Write the marker | ||
237 | + for (int i = 0; i < BgpConstants.BGP_HEADER_MARKER_LENGTH; i++) { | ||
238 | + message.writeByte(0xff); | ||
239 | + } | ||
240 | + | ||
241 | + // Write the rest of the BGP header | ||
242 | + message.writeShort(BgpConstants.BGP_HEADER_LENGTH + | ||
243 | + payload.readableBytes()); | ||
244 | + message.writeByte(type); | ||
245 | + | ||
246 | + // Write the payload | ||
247 | + message.writeBytes(payload); | ||
248 | + return message; | ||
249 | + } | ||
250 | +} |
1 | +package org.onlab.onos.sdnip.bgp; | ||
2 | + | ||
3 | +import java.util.concurrent.CountDownLatch; | ||
4 | + | ||
5 | +import org.jboss.netty.buffer.ChannelBuffer; | ||
6 | +import org.jboss.netty.channel.Channel; | ||
7 | +import org.jboss.netty.channel.ChannelHandlerContext; | ||
8 | +import org.jboss.netty.handler.codec.frame.FrameDecoder; | ||
9 | +import org.onlab.packet.IpAddress; | ||
10 | + | ||
11 | +/** | ||
12 | + * Class for handling the decoding of the BGP messages at the remote | ||
13 | + * BGP peer session. | ||
14 | + */ | ||
15 | +class TestBgpPeerFrameDecoder extends FrameDecoder { | ||
16 | + int remoteBgpVersion; // 1 octet | ||
17 | + long remoteAs; // 2 octets | ||
18 | + long remoteHoldtime; // 2 octets | ||
19 | + IpAddress remoteBgpIdentifier; // 4 octets -> IPv4 address | ||
20 | + | ||
21 | + final CountDownLatch receivedOpenMessageLatch = new CountDownLatch(1); | ||
22 | + final CountDownLatch receivedKeepaliveMessageLatch = new CountDownLatch(1); | ||
23 | + | ||
24 | + @Override | ||
25 | + protected Object decode(ChannelHandlerContext ctx, | ||
26 | + Channel channel, | ||
27 | + ChannelBuffer buf) throws Exception { | ||
28 | + // Test for minimum length of the BGP message | ||
29 | + if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) { | ||
30 | + // No enough data received | ||
31 | + return null; | ||
32 | + } | ||
33 | + | ||
34 | + // | ||
35 | + // Mark the current buffer position in case we haven't received | ||
36 | + // the whole message. | ||
37 | + // | ||
38 | + buf.markReaderIndex(); | ||
39 | + | ||
40 | + // | ||
41 | + // Read and check the BGP message Marker field: it must be all ones | ||
42 | + // | ||
43 | + byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH]; | ||
44 | + buf.readBytes(marker); | ||
45 | + for (int i = 0; i < marker.length; i++) { | ||
46 | + if (marker[i] != (byte) 0xff) { | ||
47 | + // ERROR: Connection Not Synchronized. Close the channel. | ||
48 | + ctx.getChannel().close(); | ||
49 | + return null; | ||
50 | + } | ||
51 | + } | ||
52 | + | ||
53 | + // | ||
54 | + // Read and check the BGP message Length field | ||
55 | + // | ||
56 | + int length = buf.readUnsignedShort(); | ||
57 | + if ((length < BgpConstants.BGP_HEADER_LENGTH) || | ||
58 | + (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) { | ||
59 | + // ERROR: Bad Message Length. Close the channel. | ||
60 | + ctx.getChannel().close(); | ||
61 | + return null; | ||
62 | + } | ||
63 | + | ||
64 | + // | ||
65 | + // Test whether the rest of the message is received: | ||
66 | + // So far we have read the Marker (16 octets) and the | ||
67 | + // Length (2 octets) fields. | ||
68 | + // | ||
69 | + int remainingMessageLen = | ||
70 | + length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2; | ||
71 | + if (buf.readableBytes() < remainingMessageLen) { | ||
72 | + // No enough data received | ||
73 | + buf.resetReaderIndex(); | ||
74 | + return null; | ||
75 | + } | ||
76 | + | ||
77 | + // | ||
78 | + // Read the BGP message Type field, and process based on that type | ||
79 | + // | ||
80 | + int type = buf.readUnsignedByte(); | ||
81 | + remainingMessageLen--; // Adjust after reading the type | ||
82 | + ChannelBuffer message = buf.readBytes(remainingMessageLen); | ||
83 | + | ||
84 | + // | ||
85 | + // Process the remaining of the message based on the message type | ||
86 | + // | ||
87 | + switch (type) { | ||
88 | + case BgpConstants.BGP_TYPE_OPEN: | ||
89 | + processBgpOpen(ctx, message); | ||
90 | + break; | ||
91 | + case BgpConstants.BGP_TYPE_UPDATE: | ||
92 | + // NOTE: Not used as part of the test, because ONOS does not | ||
93 | + // originate UPDATE messages. | ||
94 | + break; | ||
95 | + case BgpConstants.BGP_TYPE_NOTIFICATION: | ||
96 | + // NOTE: Not used as part of the testing (yet) | ||
97 | + break; | ||
98 | + case BgpConstants.BGP_TYPE_KEEPALIVE: | ||
99 | + processBgpKeepalive(ctx, message); | ||
100 | + break; | ||
101 | + default: | ||
102 | + // ERROR: Bad Message Type. Close the channel. | ||
103 | + ctx.getChannel().close(); | ||
104 | + return null; | ||
105 | + } | ||
106 | + | ||
107 | + return null; | ||
108 | + } | ||
109 | + | ||
110 | + /** | ||
111 | + * Processes BGP OPEN message. | ||
112 | + * | ||
113 | + * @param ctx the Channel Handler Context. | ||
114 | + * @param message the message to process. | ||
115 | + */ | ||
116 | + private void processBgpOpen(ChannelHandlerContext ctx, | ||
117 | + ChannelBuffer message) { | ||
118 | + int minLength = | ||
119 | + BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH; | ||
120 | + if (message.readableBytes() < minLength) { | ||
121 | + // ERROR: Bad Message Length. Close the channel. | ||
122 | + ctx.getChannel().close(); | ||
123 | + return; | ||
124 | + } | ||
125 | + | ||
126 | + // | ||
127 | + // Parse the OPEN message | ||
128 | + // | ||
129 | + remoteBgpVersion = message.readUnsignedByte(); | ||
130 | + remoteAs = message.readUnsignedShort(); | ||
131 | + remoteHoldtime = message.readUnsignedShort(); | ||
132 | + remoteBgpIdentifier = IpAddress.valueOf((int) message.readUnsignedInt()); | ||
133 | + // Optional Parameters | ||
134 | + int optParamLen = message.readUnsignedByte(); | ||
135 | + if (message.readableBytes() < optParamLen) { | ||
136 | + // ERROR: Bad Message Length. Close the channel. | ||
137 | + ctx.getChannel().close(); | ||
138 | + return; | ||
139 | + } | ||
140 | + message.readBytes(optParamLen); // NOTE: data ignored | ||
141 | + | ||
142 | + // BGP OPEN message successfully received | ||
143 | + receivedOpenMessageLatch.countDown(); | ||
144 | + } | ||
145 | + | ||
146 | + /** | ||
147 | + * Processes BGP KEEPALIVE message. | ||
148 | + * | ||
149 | + * @param ctx the Channel Handler Context. | ||
150 | + * @param message the message to process. | ||
151 | + */ | ||
152 | + private void processBgpKeepalive(ChannelHandlerContext ctx, | ||
153 | + ChannelBuffer message) { | ||
154 | + if (message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH != | ||
155 | + BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) { | ||
156 | + // ERROR: Bad Message Length. Close the channel. | ||
157 | + ctx.getChannel().close(); | ||
158 | + return; | ||
159 | + } | ||
160 | + // BGP KEEPALIVE message successfully received | ||
161 | + receivedKeepaliveMessageLatch.countDown(); | ||
162 | + } | ||
163 | +} |
... | @@ -26,6 +26,16 @@ | ... | @@ -26,6 +26,16 @@ |
26 | <groupId>org.onlab.onos</groupId> | 26 | <groupId>org.onlab.onos</groupId> |
27 | <artifactId>onlab-osgi</artifactId> | 27 | <artifactId>onlab-osgi</artifactId> |
28 | </dependency> | 28 | </dependency> |
29 | + | ||
30 | + <dependency> | ||
31 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
32 | + <artifactId>jackson-databind</artifactId> | ||
33 | + </dependency> | ||
34 | + <dependency> | ||
35 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
36 | + <artifactId>jackson-annotations</artifactId> | ||
37 | + </dependency> | ||
38 | + | ||
29 | <dependency> | 39 | <dependency> |
30 | <groupId>org.osgi</groupId> | 40 | <groupId>org.osgi</groupId> |
31 | <artifactId>org.osgi.core</artifactId> | 41 | <artifactId>org.osgi.core</artifactId> | ... | ... |
1 | package org.onlab.onos.cli; | 1 | package org.onlab.onos.cli; |
2 | 2 | ||
3 | +import org.apache.karaf.shell.commands.Option; | ||
3 | import org.apache.karaf.shell.console.OsgiCommandSupport; | 4 | import org.apache.karaf.shell.console.OsgiCommandSupport; |
4 | import org.onlab.osgi.DefaultServiceDirectory; | 5 | import org.onlab.osgi.DefaultServiceDirectory; |
5 | import org.onlab.osgi.ServiceNotFoundException; | 6 | import org.onlab.osgi.ServiceNotFoundException; |
... | @@ -9,6 +10,10 @@ import org.onlab.osgi.ServiceNotFoundException; | ... | @@ -9,6 +10,10 @@ import org.onlab.osgi.ServiceNotFoundException; |
9 | */ | 10 | */ |
10 | public abstract class AbstractShellCommand extends OsgiCommandSupport { | 11 | public abstract class AbstractShellCommand extends OsgiCommandSupport { |
11 | 12 | ||
13 | + @Option(name = "-j", aliases = "--json", description = "Output JSON", | ||
14 | + required = false, multiValued = false) | ||
15 | + private boolean json = false; | ||
16 | + | ||
12 | /** | 17 | /** |
13 | * Returns the reference to the implementation of the specified service. | 18 | * Returns the reference to the implementation of the specified service. |
14 | * | 19 | * |
... | @@ -46,6 +51,15 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport { | ... | @@ -46,6 +51,15 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport { |
46 | */ | 51 | */ |
47 | protected abstract void execute(); | 52 | protected abstract void execute(); |
48 | 53 | ||
54 | + /** | ||
55 | + * Indicates whether JSON format should be output. | ||
56 | + * | ||
57 | + * @return true if JSON is requested | ||
58 | + */ | ||
59 | + protected boolean outputJson() { | ||
60 | + return json; | ||
61 | + } | ||
62 | + | ||
49 | @Override | 63 | @Override |
50 | protected Object doExecute() throws Exception { | 64 | protected Object doExecute() throws Exception { |
51 | try { | 65 | try { | ... | ... |
1 | package org.onlab.onos.cli; | 1 | package org.onlab.onos.cli; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
3 | import com.google.common.collect.Lists; | 6 | import com.google.common.collect.Lists; |
4 | - | ||
5 | import org.apache.karaf.shell.commands.Command; | 7 | import org.apache.karaf.shell.commands.Command; |
6 | import org.onlab.onos.cluster.ClusterService; | 8 | import org.onlab.onos.cluster.ClusterService; |
7 | import org.onlab.onos.cluster.ControllerNode; | 9 | import org.onlab.onos.cluster.ControllerNode; |
... | @@ -26,15 +28,50 @@ public class MastersListCommand extends AbstractShellCommand { | ... | @@ -26,15 +28,50 @@ public class MastersListCommand extends AbstractShellCommand { |
26 | MastershipService mastershipService = get(MastershipService.class); | 28 | MastershipService mastershipService = get(MastershipService.class); |
27 | List<ControllerNode> nodes = newArrayList(service.getNodes()); | 29 | List<ControllerNode> nodes = newArrayList(service.getNodes()); |
28 | Collections.sort(nodes, Comparators.NODE_COMPARATOR); | 30 | Collections.sort(nodes, Comparators.NODE_COMPARATOR); |
31 | + | ||
32 | + if (outputJson()) { | ||
33 | + print("%s", json(service, mastershipService, nodes)); | ||
34 | + } else { | ||
35 | + for (ControllerNode node : nodes) { | ||
36 | + List<DeviceId> ids = Lists.newArrayList(mastershipService.getDevicesOf(node.id())); | ||
37 | + Collections.sort(ids, Comparators.ELEMENT_ID_COMPARATOR); | ||
38 | + print("%s: %d devices", node.id(), ids.size()); | ||
39 | + for (DeviceId deviceId : ids) { | ||
40 | + print(" %s", deviceId); | ||
41 | + } | ||
42 | + } | ||
43 | + } | ||
44 | + } | ||
45 | + | ||
46 | + // Produces JSON structure. | ||
47 | + private JsonNode json(ClusterService service, MastershipService mastershipService, | ||
48 | + List<ControllerNode> nodes) { | ||
49 | + ObjectMapper mapper = new ObjectMapper(); | ||
50 | + ArrayNode result = mapper.createArrayNode(); | ||
29 | ControllerNode self = service.getLocalNode(); | 51 | ControllerNode self = service.getLocalNode(); |
30 | for (ControllerNode node : nodes) { | 52 | for (ControllerNode node : nodes) { |
31 | List<DeviceId> ids = Lists.newArrayList(mastershipService.getDevicesOf(node.id())); | 53 | List<DeviceId> ids = Lists.newArrayList(mastershipService.getDevicesOf(node.id())); |
32 | - Collections.sort(ids, Comparators.ELEMENT_ID_COMPARATOR); | 54 | + result.add(mapper.createObjectNode() |
33 | - print("%s: %d devices", node.id(), ids.size()); | 55 | + .put("id", node.id().toString()) |
34 | - for (DeviceId deviceId : ids) { | 56 | + .put("size", ids.size()) |
35 | - print(" %s", deviceId); | 57 | + .set("devices", json(mapper, ids))); |
36 | - } | 58 | + } |
59 | + return result; | ||
60 | + } | ||
61 | + | ||
62 | + /** | ||
63 | + * Produces a JSON array containing the specified device identifiers. | ||
64 | + * | ||
65 | + * @param mapper object mapper | ||
66 | + * @param ids collection of device identifiers | ||
67 | + * @return JSON array | ||
68 | + */ | ||
69 | + public static JsonNode json(ObjectMapper mapper, Iterable<DeviceId> ids) { | ||
70 | + ArrayNode result = mapper.createArrayNode(); | ||
71 | + for (DeviceId deviceId : ids) { | ||
72 | + result.add(deviceId.toString()); | ||
37 | } | 73 | } |
74 | + return result; | ||
38 | } | 75 | } |
39 | 76 | ||
40 | } | 77 | } | ... | ... |
1 | package org.onlab.onos.cli; | 1 | package org.onlab.onos.cli; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
3 | import org.apache.karaf.shell.commands.Command; | 6 | import org.apache.karaf.shell.commands.Command; |
4 | import org.onlab.onos.cluster.ClusterService; | 7 | import org.onlab.onos.cluster.ClusterService; |
5 | import org.onlab.onos.cluster.ControllerNode; | 8 | import org.onlab.onos.cluster.ControllerNode; |
... | @@ -24,12 +27,32 @@ public class NodesListCommand extends AbstractShellCommand { | ... | @@ -24,12 +27,32 @@ public class NodesListCommand extends AbstractShellCommand { |
24 | ClusterService service = get(ClusterService.class); | 27 | ClusterService service = get(ClusterService.class); |
25 | List<ControllerNode> nodes = newArrayList(service.getNodes()); | 28 | List<ControllerNode> nodes = newArrayList(service.getNodes()); |
26 | Collections.sort(nodes, Comparators.NODE_COMPARATOR); | 29 | Collections.sort(nodes, Comparators.NODE_COMPARATOR); |
30 | + if (outputJson()) { | ||
31 | + print("%s", json(service, nodes)); | ||
32 | + } else { | ||
33 | + ControllerNode self = service.getLocalNode(); | ||
34 | + for (ControllerNode node : nodes) { | ||
35 | + print(FMT, node.id(), node.ip(), node.tcpPort(), | ||
36 | + service.getState(node.id()), | ||
37 | + node.equals(self) ? "*" : ""); | ||
38 | + } | ||
39 | + } | ||
40 | + } | ||
41 | + | ||
42 | + // Produces JSON structure. | ||
43 | + private JsonNode json(ClusterService service, List<ControllerNode> nodes) { | ||
44 | + ObjectMapper mapper = new ObjectMapper(); | ||
45 | + ArrayNode result = mapper.createArrayNode(); | ||
27 | ControllerNode self = service.getLocalNode(); | 46 | ControllerNode self = service.getLocalNode(); |
28 | for (ControllerNode node : nodes) { | 47 | for (ControllerNode node : nodes) { |
29 | - print(FMT, node.id(), node.ip(), node.tcpPort(), | 48 | + result.add(mapper.createObjectNode() |
30 | - service.getState(node.id()), | 49 | + .put("id", node.id().toString()) |
31 | - node.equals(self) ? "*" : ""); | 50 | + .put("ip", node.ip().toString()) |
51 | + .put("tcpPort", node.tcpPort()) | ||
52 | + .put("state", service.getState(node.id()).toString()) | ||
53 | + .put("self", node.equals(self))); | ||
32 | } | 54 | } |
55 | + return result; | ||
33 | } | 56 | } |
34 | 57 | ||
35 | } | 58 | } | ... | ... |
1 | +package org.onlab.onos.cli; | ||
2 | + | ||
3 | +import static com.google.common.collect.Lists.newArrayList; | ||
4 | + | ||
5 | +import java.util.Collections; | ||
6 | +import java.util.List; | ||
7 | + | ||
8 | +import org.apache.karaf.shell.commands.Command; | ||
9 | +import org.onlab.onos.cluster.NodeId; | ||
10 | +import org.onlab.onos.mastership.MastershipService; | ||
11 | +import org.onlab.onos.net.Device; | ||
12 | +import org.onlab.onos.net.DeviceId; | ||
13 | +import org.onlab.onos.net.device.DeviceService; | ||
14 | + | ||
15 | + | ||
16 | +/** | ||
17 | + * Lists mastership roles of nodes for each device. | ||
18 | + */ | ||
19 | +@Command(scope = "onos", name = "roles", | ||
20 | + description = "Lists mastership roles of nodes for each device.") | ||
21 | +public class RolesCommand extends AbstractShellCommand { | ||
22 | + | ||
23 | + private static final String FMT_HDR = "%s: master=%s\nstandbys: %s nodes"; | ||
24 | + private static final String FMT_SB = "\t%s"; | ||
25 | + | ||
26 | + @Override | ||
27 | + protected void execute() { | ||
28 | + DeviceService deviceService = get(DeviceService.class); | ||
29 | + MastershipService roleService = get(MastershipService.class); | ||
30 | + | ||
31 | + for (Device d : getSortedDevices(deviceService)) { | ||
32 | + DeviceId did = d.id(); | ||
33 | + printRoles(roleService, did); | ||
34 | + } | ||
35 | + } | ||
36 | + | ||
37 | + /** | ||
38 | + * Returns the list of devices sorted using the device ID URIs. | ||
39 | + * | ||
40 | + * @param service device service | ||
41 | + * @return sorted device list | ||
42 | + */ | ||
43 | + protected static List<Device> getSortedDevices(DeviceService service) { | ||
44 | + List<Device> devices = newArrayList(service.getDevices()); | ||
45 | + Collections.sort(devices, Comparators.ELEMENT_COMPARATOR); | ||
46 | + return devices; | ||
47 | + } | ||
48 | + | ||
49 | + /** | ||
50 | + * Prints the role information for a device. | ||
51 | + * | ||
52 | + * @param deviceId the ID of the device | ||
53 | + * @param master the current master | ||
54 | + */ | ||
55 | + protected void printRoles(MastershipService service, DeviceId deviceId) { | ||
56 | + List<NodeId> nodes = service.getNodesFor(deviceId); | ||
57 | + NodeId first = null; | ||
58 | + NodeId master = null; | ||
59 | + | ||
60 | + if (!nodes.isEmpty()) { | ||
61 | + first = nodes.get(0); | ||
62 | + } | ||
63 | + if (first != null && | ||
64 | + first.equals(service.getMasterFor(deviceId))) { | ||
65 | + master = nodes.get(0); | ||
66 | + nodes.remove(master); | ||
67 | + } | ||
68 | + print(FMT_HDR, deviceId, master == null ? "NONE" : master, nodes.size()); | ||
69 | + | ||
70 | + for (NodeId nid : nodes) { | ||
71 | + print(FMT_SB, nid); | ||
72 | + } | ||
73 | + } | ||
74 | +} |
1 | package org.onlab.onos.cli; | 1 | package org.onlab.onos.cli; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
3 | import org.apache.karaf.shell.commands.Command; | 4 | import org.apache.karaf.shell.commands.Command; |
4 | import org.onlab.onos.CoreService; | 5 | import org.onlab.onos.CoreService; |
5 | import org.onlab.onos.cluster.ClusterService; | 6 | import org.onlab.onos.cluster.ClusterService; |
... | @@ -22,18 +23,32 @@ public class SummaryCommand extends AbstractShellCommand { | ... | @@ -22,18 +23,32 @@ public class SummaryCommand extends AbstractShellCommand { |
22 | protected void execute() { | 23 | protected void execute() { |
23 | TopologyService topologyService = get(TopologyService.class); | 24 | TopologyService topologyService = get(TopologyService.class); |
24 | Topology topology = topologyService.currentTopology(); | 25 | Topology topology = topologyService.currentTopology(); |
25 | - print("node=%s, version=%s", | 26 | + if (outputJson()) { |
26 | - get(ClusterService.class).getLocalNode().ip(), | 27 | + print("%s", new ObjectMapper().createObjectNode() |
27 | - get(CoreService.class).version().toString()); | 28 | + .put("node", get(ClusterService.class).getLocalNode().ip().toString()) |
28 | - print("nodes=%d, devices=%d, links=%d, hosts=%d, clusters=%s, paths=%d, flows=%d, intents=%d", | 29 | + .put("version", get(CoreService.class).version().toString()) |
29 | - get(ClusterService.class).getNodes().size(), | 30 | + .put("nodes", get(ClusterService.class).getNodes().size()) |
30 | - get(DeviceService.class).getDeviceCount(), | 31 | + .put("devices", get(DeviceService.class).getDeviceCount()) |
31 | - get(LinkService.class).getLinkCount(), | 32 | + .put("links", get(LinkService.class).getLinkCount()) |
32 | - get(HostService.class).getHostCount(), | 33 | + .put("hosts", get(HostService.class).getHostCount()) |
33 | - topologyService.getClusters(topology).size(), | 34 | + .put("clusters", topologyService.getClusters(topology).size()) |
34 | - topology.pathCount(), | 35 | + .put("paths", topology.pathCount()) |
35 | - get(FlowRuleService.class).getFlowRuleCount(), | 36 | + .put("flows", get(FlowRuleService.class).getFlowRuleCount()) |
36 | - get(IntentService.class).getIntentCount()); | 37 | + .put("intents", get(IntentService.class).getIntentCount())); |
38 | + } else { | ||
39 | + print("node=%s, version=%s", | ||
40 | + get(ClusterService.class).getLocalNode().ip(), | ||
41 | + get(CoreService.class).version().toString()); | ||
42 | + print("nodes=%d, devices=%d, links=%d, hosts=%d, clusters=%s, paths=%d, flows=%d, intents=%d", | ||
43 | + get(ClusterService.class).getNodes().size(), | ||
44 | + get(DeviceService.class).getDeviceCount(), | ||
45 | + get(LinkService.class).getLinkCount(), | ||
46 | + get(HostService.class).getHostCount(), | ||
47 | + topologyService.getClusters(topology).size(), | ||
48 | + topology.pathCount(), | ||
49 | + get(FlowRuleService.class).getFlowRuleCount(), | ||
50 | + get(IntentService.class).getIntentCount()); | ||
51 | + } | ||
37 | } | 52 | } |
38 | 53 | ||
39 | } | 54 | } | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
3 | import com.google.common.collect.Lists; | 4 | import com.google.common.collect.Lists; |
4 | import org.apache.karaf.shell.commands.Argument; | 5 | import org.apache.karaf.shell.commands.Argument; |
5 | import org.apache.karaf.shell.commands.Command; | 6 | import org.apache.karaf.shell.commands.Command; |
... | @@ -10,6 +11,7 @@ import org.onlab.onos.net.topology.TopologyCluster; | ... | @@ -10,6 +11,7 @@ import org.onlab.onos.net.topology.TopologyCluster; |
10 | import java.util.Collections; | 11 | import java.util.Collections; |
11 | import java.util.List; | 12 | import java.util.List; |
12 | 13 | ||
14 | +import static org.onlab.onos.cli.MastersListCommand.json; | ||
13 | import static org.onlab.onos.net.topology.ClusterId.clusterId; | 15 | import static org.onlab.onos.net.topology.ClusterId.clusterId; |
14 | 16 | ||
15 | /** | 17 | /** |
... | @@ -33,11 +35,14 @@ public class ClusterDevicesCommand extends ClustersListCommand { | ... | @@ -33,11 +35,14 @@ public class ClusterDevicesCommand extends ClustersListCommand { |
33 | } else { | 35 | } else { |
34 | List<DeviceId> ids = Lists.newArrayList(service.getClusterDevices(topology, cluster)); | 36 | List<DeviceId> ids = Lists.newArrayList(service.getClusterDevices(topology, cluster)); |
35 | Collections.sort(ids, Comparators.ELEMENT_ID_COMPARATOR); | 37 | Collections.sort(ids, Comparators.ELEMENT_ID_COMPARATOR); |
36 | - for (DeviceId deviceId : ids) { | 38 | + if (outputJson()) { |
37 | - print("%s", deviceId); | 39 | + print("%s", json(new ObjectMapper(), ids)); |
40 | + } else { | ||
41 | + for (DeviceId deviceId : ids) { | ||
42 | + print("%s", deviceId); | ||
43 | + } | ||
38 | } | 44 | } |
39 | } | 45 | } |
40 | } | 46 | } |
41 | 47 | ||
42 | - | ||
43 | } | 48 | } | ... | ... |
... | @@ -5,6 +5,7 @@ import org.apache.karaf.shell.commands.Command; | ... | @@ -5,6 +5,7 @@ import org.apache.karaf.shell.commands.Command; |
5 | import org.onlab.onos.net.Link; | 5 | import org.onlab.onos.net.Link; |
6 | import org.onlab.onos.net.topology.TopologyCluster; | 6 | import org.onlab.onos.net.topology.TopologyCluster; |
7 | 7 | ||
8 | +import static org.onlab.onos.cli.net.LinksListCommand.json; | ||
8 | import static org.onlab.onos.cli.net.LinksListCommand.linkString; | 9 | import static org.onlab.onos.cli.net.LinksListCommand.linkString; |
9 | import static org.onlab.onos.net.topology.ClusterId.clusterId; | 10 | import static org.onlab.onos.net.topology.ClusterId.clusterId; |
10 | 11 | ||
... | @@ -26,6 +27,8 @@ public class ClusterLinksCommand extends ClustersListCommand { | ... | @@ -26,6 +27,8 @@ public class ClusterLinksCommand extends ClustersListCommand { |
26 | TopologyCluster cluster = service.getCluster(topology, clusterId(cid)); | 27 | TopologyCluster cluster = service.getCluster(topology, clusterId(cid)); |
27 | if (cluster == null) { | 28 | if (cluster == null) { |
28 | error("No such cluster %s", cid); | 29 | error("No such cluster %s", cid); |
30 | + } else if (outputJson()) { | ||
31 | + print("%s", json(service.getClusterLinks(topology, cluster))); | ||
29 | } else { | 32 | } else { |
30 | for (Link link : service.getClusterLinks(topology, cluster)) { | 33 | for (Link link : service.getClusterLinks(topology, cluster)) { |
31 | print(linkString(link)); | 34 | print(linkString(link)); | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
3 | import com.google.common.collect.Lists; | 6 | import com.google.common.collect.Lists; |
4 | import org.apache.karaf.shell.commands.Command; | 7 | import org.apache.karaf.shell.commands.Command; |
5 | import org.onlab.onos.cli.Comparators; | 8 | import org.onlab.onos.cli.Comparators; |
... | @@ -24,9 +27,26 @@ public class ClustersListCommand extends TopologyCommand { | ... | @@ -24,9 +27,26 @@ public class ClustersListCommand extends TopologyCommand { |
24 | List<TopologyCluster> clusters = Lists.newArrayList(service.getClusters(topology)); | 27 | List<TopologyCluster> clusters = Lists.newArrayList(service.getClusters(topology)); |
25 | Collections.sort(clusters, Comparators.CLUSTER_COMPARATOR); | 28 | Collections.sort(clusters, Comparators.CLUSTER_COMPARATOR); |
26 | 29 | ||
30 | + if (outputJson()) { | ||
31 | + print("%s", json(clusters)); | ||
32 | + } else { | ||
33 | + for (TopologyCluster cluster : clusters) { | ||
34 | + print(FMT, cluster.id().index(), cluster.deviceCount(), cluster.linkCount()); | ||
35 | + } | ||
36 | + } | ||
37 | + } | ||
38 | + | ||
39 | + // Produces a JSON result. | ||
40 | + private JsonNode json(Iterable<TopologyCluster> clusters) { | ||
41 | + ObjectMapper mapper = new ObjectMapper(); | ||
42 | + ArrayNode result = mapper.createArrayNode(); | ||
27 | for (TopologyCluster cluster : clusters) { | 43 | for (TopologyCluster cluster : clusters) { |
28 | - print(FMT, cluster.id().index(), cluster.deviceCount(), cluster.linkCount()); | 44 | + result.add(mapper.createObjectNode() |
45 | + .put("id", cluster.id().index()) | ||
46 | + .put("deviceCount", cluster.deviceCount()) | ||
47 | + .put("linkCount", cluster.linkCount())); | ||
29 | } | 48 | } |
49 | + return result; | ||
30 | } | 50 | } |
31 | 51 | ||
32 | } | 52 | } | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
6 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
3 | import org.apache.karaf.shell.commands.Argument; | 7 | import org.apache.karaf.shell.commands.Argument; |
4 | import org.apache.karaf.shell.commands.Command; | 8 | import org.apache.karaf.shell.commands.Command; |
9 | +import org.apache.karaf.shell.commands.Option; | ||
5 | import org.onlab.onos.cli.Comparators; | 10 | import org.onlab.onos.cli.Comparators; |
6 | import org.onlab.onos.net.Device; | 11 | import org.onlab.onos.net.Device; |
7 | import org.onlab.onos.net.Port; | 12 | import org.onlab.onos.net.Port; |
... | @@ -22,6 +27,14 @@ public class DevicePortsListCommand extends DevicesListCommand { | ... | @@ -22,6 +27,14 @@ public class DevicePortsListCommand extends DevicesListCommand { |
22 | 27 | ||
23 | private static final String FMT = " port=%s, state=%s"; | 28 | private static final String FMT = " port=%s, state=%s"; |
24 | 29 | ||
30 | + @Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports", | ||
31 | + required = false, multiValued = false) | ||
32 | + private boolean enabled = false; | ||
33 | + | ||
34 | + @Option(name = "-d", aliases = "--disabled", description = "Show only disabled ports", | ||
35 | + required = false, multiValued = false) | ||
36 | + private boolean disabled = false; | ||
37 | + | ||
25 | @Argument(index = 0, name = "uri", description = "Device ID", | 38 | @Argument(index = 0, name = "uri", description = "Device ID", |
26 | required = false, multiValued = false) | 39 | required = false, multiValued = false) |
27 | String uri = null; | 40 | String uri = null; |
... | @@ -30,26 +43,78 @@ public class DevicePortsListCommand extends DevicesListCommand { | ... | @@ -30,26 +43,78 @@ public class DevicePortsListCommand extends DevicesListCommand { |
30 | protected void execute() { | 43 | protected void execute() { |
31 | DeviceService service = get(DeviceService.class); | 44 | DeviceService service = get(DeviceService.class); |
32 | if (uri == null) { | 45 | if (uri == null) { |
33 | - for (Device device : getSortedDevices(service)) { | 46 | + if (outputJson()) { |
34 | - printDevice(service, device); | 47 | + print("%s", jsonPorts(service, getSortedDevices(service))); |
48 | + } else { | ||
49 | + for (Device device : getSortedDevices(service)) { | ||
50 | + printDevice(service, device); | ||
51 | + } | ||
35 | } | 52 | } |
53 | + | ||
36 | } else { | 54 | } else { |
37 | Device device = service.getDevice(deviceId(uri)); | 55 | Device device = service.getDevice(deviceId(uri)); |
38 | if (device == null) { | 56 | if (device == null) { |
39 | error("No such device %s", uri); | 57 | error("No such device %s", uri); |
58 | + } else if (outputJson()) { | ||
59 | + print("%s", jsonPorts(service, new ObjectMapper(), device)); | ||
40 | } else { | 60 | } else { |
41 | printDevice(service, device); | 61 | printDevice(service, device); |
42 | } | 62 | } |
43 | } | 63 | } |
44 | } | 64 | } |
45 | 65 | ||
66 | + /** | ||
67 | + * Produces JSON array containing ports of the specified devices. | ||
68 | + * | ||
69 | + * @param service device service | ||
70 | + * @param devices collection of devices | ||
71 | + * @return JSON array | ||
72 | + */ | ||
73 | + public JsonNode jsonPorts(DeviceService service, Iterable<Device> devices) { | ||
74 | + ObjectMapper mapper = new ObjectMapper(); | ||
75 | + ArrayNode result = mapper.createArrayNode(); | ||
76 | + for (Device device : devices) { | ||
77 | + result.add(jsonPorts(service, mapper, device)); | ||
78 | + } | ||
79 | + return result; | ||
80 | + } | ||
81 | + | ||
82 | + /** | ||
83 | + * Produces JSON array containing ports of the specified device. | ||
84 | + * | ||
85 | + * @param service device service | ||
86 | + * @param mapper object mapper | ||
87 | + * @param device infrastructure devices | ||
88 | + * @return JSON array | ||
89 | + */ | ||
90 | + public JsonNode jsonPorts(DeviceService service, ObjectMapper mapper, Device device) { | ||
91 | + ObjectNode result = mapper.createObjectNode(); | ||
92 | + ArrayNode ports = mapper.createArrayNode(); | ||
93 | + for (Port port : service.getPorts(device.id())) { | ||
94 | + if (isIncluded(port)) { | ||
95 | + ports.add(mapper.createObjectNode() | ||
96 | + .put("port", port.number().toString()) | ||
97 | + .put("isEnabled", port.isEnabled())); | ||
98 | + } | ||
99 | + } | ||
100 | + return result.put("device", device.id().toString()).set("ports", ports); | ||
101 | + } | ||
102 | + | ||
103 | + // Determines if a port should be included in output. | ||
104 | + private boolean isIncluded(Port port) { | ||
105 | + return enabled && port.isEnabled() || disabled && !port.isEnabled() || | ||
106 | + !enabled && !disabled; | ||
107 | + } | ||
108 | + | ||
46 | @Override | 109 | @Override |
47 | protected void printDevice(DeviceService service, Device device) { | 110 | protected void printDevice(DeviceService service, Device device) { |
48 | super.printDevice(service, device); | 111 | super.printDevice(service, device); |
49 | List<Port> ports = new ArrayList<>(service.getPorts(device.id())); | 112 | List<Port> ports = new ArrayList<>(service.getPorts(device.id())); |
50 | Collections.sort(ports, Comparators.PORT_COMPARATOR); | 113 | Collections.sort(ports, Comparators.PORT_COMPARATOR); |
51 | for (Port port : ports) { | 114 | for (Port port : ports) { |
52 | - print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled"); | 115 | + if (isIncluded(port)) { |
116 | + print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled"); | ||
117 | + } | ||
53 | } | 118 | } |
54 | } | 119 | } |
55 | 120 | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
6 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
3 | import org.apache.karaf.shell.commands.Command; | 7 | import org.apache.karaf.shell.commands.Command; |
4 | import org.onlab.onos.cli.AbstractShellCommand; | 8 | import org.onlab.onos.cli.AbstractShellCommand; |
5 | import org.onlab.onos.cli.Comparators; | 9 | import org.onlab.onos.cli.Comparators; |
... | @@ -24,12 +28,55 @@ public class DevicesListCommand extends AbstractShellCommand { | ... | @@ -24,12 +28,55 @@ public class DevicesListCommand extends AbstractShellCommand { |
24 | @Override | 28 | @Override |
25 | protected void execute() { | 29 | protected void execute() { |
26 | DeviceService service = get(DeviceService.class); | 30 | DeviceService service = get(DeviceService.class); |
27 | - for (Device device : getSortedDevices(service)) { | 31 | + if (outputJson()) { |
28 | - printDevice(service, device); | 32 | + print("%s", json(service, getSortedDevices(service))); |
33 | + } else { | ||
34 | + for (Device device : getSortedDevices(service)) { | ||
35 | + printDevice(service, device); | ||
36 | + } | ||
29 | } | 37 | } |
30 | } | 38 | } |
31 | 39 | ||
32 | /** | 40 | /** |
41 | + * Returns JSON node representing the specified devices. | ||
42 | + * | ||
43 | + * @param service device service | ||
44 | + * @param devices collection of devices | ||
45 | + * @return JSON node | ||
46 | + */ | ||
47 | + public static JsonNode json(DeviceService service, Iterable<Device> devices) { | ||
48 | + ObjectMapper mapper = new ObjectMapper(); | ||
49 | + ArrayNode result = mapper.createArrayNode(); | ||
50 | + for (Device device : devices) { | ||
51 | + result.add(json(service, mapper, device)); | ||
52 | + } | ||
53 | + return result; | ||
54 | + } | ||
55 | + | ||
56 | + /** | ||
57 | + * Returns JSON node representing the specified device. | ||
58 | + * | ||
59 | + * @param service device service | ||
60 | + * @param mapper object mapper | ||
61 | + * @param device infrastructure device | ||
62 | + * @return JSON node | ||
63 | + */ | ||
64 | + public static ObjectNode json(DeviceService service, ObjectMapper mapper, | ||
65 | + Device device) { | ||
66 | + ObjectNode result = mapper.createObjectNode(); | ||
67 | + if (device != null) { | ||
68 | + result.put("id", device.id().toString()) | ||
69 | + .put("available", service.isAvailable(device.id())) | ||
70 | + .put("role", service.getRole(device.id()).toString()) | ||
71 | + .put("mfr", device.manufacturer()) | ||
72 | + .put("hw", device.hwVersion()) | ||
73 | + .put("sw", device.swVersion()) | ||
74 | + .put("serial", device.serialNumber()); | ||
75 | + } | ||
76 | + return result; | ||
77 | + } | ||
78 | + | ||
79 | + /** | ||
33 | * Returns the list of devices sorted using the device ID URIs. | 80 | * Returns the list of devices sorted using the device ID URIs. |
34 | * | 81 | * |
35 | * @param service device service | 82 | * @param service device service | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
6 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
3 | import com.google.common.collect.Maps; | 7 | import com.google.common.collect.Maps; |
4 | import org.apache.karaf.shell.commands.Argument; | 8 | import org.apache.karaf.shell.commands.Argument; |
5 | import org.apache.karaf.shell.commands.Command; | 9 | import org.apache.karaf.shell.commands.Command; |
... | @@ -12,6 +16,8 @@ import org.onlab.onos.net.device.DeviceService; | ... | @@ -12,6 +16,8 @@ import org.onlab.onos.net.device.DeviceService; |
12 | import org.onlab.onos.net.flow.FlowEntry; | 16 | import org.onlab.onos.net.flow.FlowEntry; |
13 | import org.onlab.onos.net.flow.FlowEntry.FlowEntryState; | 17 | import org.onlab.onos.net.flow.FlowEntry.FlowEntryState; |
14 | import org.onlab.onos.net.flow.FlowRuleService; | 18 | import org.onlab.onos.net.flow.FlowRuleService; |
19 | +import org.onlab.onos.net.flow.criteria.Criterion; | ||
20 | +import org.onlab.onos.net.flow.instructions.Instruction; | ||
15 | 21 | ||
16 | import java.util.Collections; | 22 | import java.util.Collections; |
17 | import java.util.List; | 23 | import java.util.List; |
... | @@ -48,9 +54,73 @@ public class FlowsListCommand extends AbstractShellCommand { | ... | @@ -48,9 +54,73 @@ public class FlowsListCommand extends AbstractShellCommand { |
48 | DeviceService deviceService = get(DeviceService.class); | 54 | DeviceService deviceService = get(DeviceService.class); |
49 | FlowRuleService service = get(FlowRuleService.class); | 55 | FlowRuleService service = get(FlowRuleService.class); |
50 | Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service); | 56 | Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service); |
51 | - for (Device d : getSortedDevices(deviceService)) { | 57 | + |
52 | - printFlows(d, flows.get(d), coreService); | 58 | + if (outputJson()) { |
59 | + print("%s", json(coreService, getSortedDevices(deviceService), flows)); | ||
60 | + } else { | ||
61 | + for (Device d : getSortedDevices(deviceService)) { | ||
62 | + printFlows(d, flows.get(d), coreService); | ||
63 | + } | ||
64 | + } | ||
65 | + } | ||
66 | + | ||
67 | + /** | ||
68 | + * Produces a JSON array of flows grouped by the each device. | ||
69 | + * | ||
70 | + * @param coreService core service | ||
71 | + * @param devices collection of devices to group flow by | ||
72 | + * @param flows collection of flows per each device | ||
73 | + * @return JSON array | ||
74 | + */ | ||
75 | + private JsonNode json(CoreService coreService, Iterable<Device> devices, | ||
76 | + Map<Device, List<FlowEntry>> flows) { | ||
77 | + ObjectMapper mapper = new ObjectMapper(); | ||
78 | + ArrayNode result = mapper.createArrayNode(); | ||
79 | + for (Device device : devices) { | ||
80 | + result.add(json(coreService, mapper, device, flows.get(device))); | ||
53 | } | 81 | } |
82 | + return result; | ||
83 | + } | ||
84 | + | ||
85 | + // Produces JSON object with the flows of the given device. | ||
86 | + private ObjectNode json(CoreService coreService, ObjectMapper mapper, | ||
87 | + Device device, List<FlowEntry> flows) { | ||
88 | + ObjectNode result = mapper.createObjectNode(); | ||
89 | + ArrayNode array = mapper.createArrayNode(); | ||
90 | + | ||
91 | + for (FlowEntry flow : flows) { | ||
92 | + array.add(json(coreService, mapper, flow)); | ||
93 | + } | ||
94 | + | ||
95 | + result.put("device", device.id().toString()) | ||
96 | + .put("flowCount", flows.size()) | ||
97 | + .set("flows", array); | ||
98 | + return result; | ||
99 | + } | ||
100 | + | ||
101 | + // Produces JSON structure with the specified flow data. | ||
102 | + private ObjectNode json(CoreService coreService, ObjectMapper mapper, | ||
103 | + FlowEntry flow) { | ||
104 | + ObjectNode result = mapper.createObjectNode(); | ||
105 | + ArrayNode crit = mapper.createArrayNode(); | ||
106 | + for (Criterion c : flow.selector().criteria()) { | ||
107 | + crit.add(c.toString()); | ||
108 | + } | ||
109 | + | ||
110 | + ArrayNode instr = mapper.createArrayNode(); | ||
111 | + for (Instruction i : flow.treatment().instructions()) { | ||
112 | + instr.add(i.toString()); | ||
113 | + } | ||
114 | + | ||
115 | + result.put("flowId", Long.toHexString(flow.id().value())) | ||
116 | + .put("state", flow.state().toString()) | ||
117 | + .put("bytes", flow.bytes()) | ||
118 | + .put("packets", flow.packets()) | ||
119 | + .put("life", flow.life()) | ||
120 | + .put("appId", coreService.getAppId(flow.appId()).name()); | ||
121 | + result.set("selector", crit); | ||
122 | + result.set("treatment", instr); | ||
123 | + return result; | ||
54 | } | 124 | } |
55 | 125 | ||
56 | /** | 126 | /** | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
6 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
3 | import org.apache.karaf.shell.commands.Command; | 7 | import org.apache.karaf.shell.commands.Command; |
4 | import org.onlab.onos.cli.AbstractShellCommand; | 8 | import org.onlab.onos.cli.AbstractShellCommand; |
5 | import org.onlab.onos.cli.Comparators; | 9 | import org.onlab.onos.cli.Comparators; |
6 | import org.onlab.onos.net.Host; | 10 | import org.onlab.onos.net.Host; |
7 | import org.onlab.onos.net.host.HostService; | 11 | import org.onlab.onos.net.host.HostService; |
12 | +import org.onlab.packet.IpPrefix; | ||
8 | 13 | ||
9 | import java.util.Collections; | 14 | import java.util.Collections; |
10 | import java.util.List; | 15 | import java.util.List; |
... | @@ -15,7 +20,7 @@ import static com.google.common.collect.Lists.newArrayList; | ... | @@ -15,7 +20,7 @@ import static com.google.common.collect.Lists.newArrayList; |
15 | * Lists all currently-known hosts. | 20 | * Lists all currently-known hosts. |
16 | */ | 21 | */ |
17 | @Command(scope = "onos", name = "hosts", | 22 | @Command(scope = "onos", name = "hosts", |
18 | - description = "Lists all currently-known hosts.") | 23 | + description = "Lists all currently-known hosts.") |
19 | public class HostsListCommand extends AbstractShellCommand { | 24 | public class HostsListCommand extends AbstractShellCommand { |
20 | 25 | ||
21 | private static final String FMT = | 26 | private static final String FMT = |
... | @@ -24,11 +29,42 @@ public class HostsListCommand extends AbstractShellCommand { | ... | @@ -24,11 +29,42 @@ public class HostsListCommand extends AbstractShellCommand { |
24 | @Override | 29 | @Override |
25 | protected void execute() { | 30 | protected void execute() { |
26 | HostService service = get(HostService.class); | 31 | HostService service = get(HostService.class); |
27 | - for (Host host : getSortedHosts(service)) { | 32 | + if (outputJson()) { |
28 | - printHost(host); | 33 | + print("%s", json(getSortedHosts(service))); |
34 | + } else { | ||
35 | + for (Host host : getSortedHosts(service)) { | ||
36 | + printHost(host); | ||
37 | + } | ||
29 | } | 38 | } |
30 | } | 39 | } |
31 | 40 | ||
41 | + // Produces JSON structure. | ||
42 | + private static JsonNode json(Iterable<Host> hosts) { | ||
43 | + ObjectMapper mapper = new ObjectMapper(); | ||
44 | + ArrayNode result = mapper.createArrayNode(); | ||
45 | + for (Host host : hosts) { | ||
46 | + result.add(json(mapper, host)); | ||
47 | + } | ||
48 | + return result; | ||
49 | + } | ||
50 | + | ||
51 | + // Produces JSON structure. | ||
52 | + private static JsonNode json(ObjectMapper mapper, Host host) { | ||
53 | + ObjectNode loc = LinksListCommand.json(mapper, host.location()) | ||
54 | + .put("time", host.location().time()); | ||
55 | + ArrayNode ips = mapper.createArrayNode(); | ||
56 | + for (IpPrefix ip : host.ipAddresses()) { | ||
57 | + ips.add(ip.toString()); | ||
58 | + } | ||
59 | + ObjectNode result = mapper.createObjectNode() | ||
60 | + .put("id", host.id().toString()) | ||
61 | + .put("mac", host.mac().toString()) | ||
62 | + .put("vlan", host.vlan().toString()); | ||
63 | + result.set("location", loc); | ||
64 | + result.set("ips", ips); | ||
65 | + return result; | ||
66 | + } | ||
67 | + | ||
32 | /** | 68 | /** |
33 | * Returns the list of devices sorted using the device ID URIs. | 69 | * Returns the list of devices sorted using the device ID URIs. |
34 | * | 70 | * |
... | @@ -44,14 +80,14 @@ public class HostsListCommand extends AbstractShellCommand { | ... | @@ -44,14 +80,14 @@ public class HostsListCommand extends AbstractShellCommand { |
44 | /** | 80 | /** |
45 | * Prints information about a host. | 81 | * Prints information about a host. |
46 | * | 82 | * |
47 | - * @param host | 83 | + * @param host end-station host |
48 | */ | 84 | */ |
49 | protected void printHost(Host host) { | 85 | protected void printHost(Host host) { |
50 | if (host != null) { | 86 | if (host != null) { |
51 | print(FMT, host.id(), host.mac(), | 87 | print(FMT, host.id(), host.mac(), |
52 | - host.location().deviceId(), | 88 | + host.location().deviceId(), |
53 | - host.location().port(), | 89 | + host.location().port(), |
54 | - host.vlan(), host.ipAddresses()); | 90 | + host.vlan(), host.ipAddresses()); |
55 | } | 91 | } |
56 | } | 92 | } |
57 | - } | 93 | +} | ... | ... |
... | @@ -90,11 +90,15 @@ public class IntentPushTestCommand extends AbstractShellCommand | ... | @@ -90,11 +90,15 @@ public class IntentPushTestCommand extends AbstractShellCommand |
90 | service.submit(intent); | 90 | service.submit(intent); |
91 | } | 91 | } |
92 | try { | 92 | try { |
93 | - latch.await(5, TimeUnit.SECONDS); | 93 | + if (latch.await(10, TimeUnit.SECONDS)) { |
94 | - printResults(count); | 94 | + printResults(count); |
95 | + } else { | ||
96 | + print("I FAIL MISERABLY -> %d", latch.getCount()); | ||
97 | + } | ||
95 | } catch (InterruptedException e) { | 98 | } catch (InterruptedException e) { |
96 | print(e.toString()); | 99 | print(e.toString()); |
97 | } | 100 | } |
101 | + | ||
98 | service.removeListener(this); | 102 | service.removeListener(this); |
99 | } | 103 | } |
100 | 104 | ||
... | @@ -140,6 +144,8 @@ public class IntentPushTestCommand extends AbstractShellCommand | ... | @@ -140,6 +144,8 @@ public class IntentPushTestCommand extends AbstractShellCommand |
140 | } else { | 144 | } else { |
141 | log.warn("install event latch is null"); | 145 | log.warn("install event latch is null"); |
142 | } | 146 | } |
147 | + } else { | ||
148 | + log.info("I FAIL -> {}", event); | ||
143 | } | 149 | } |
144 | } | 150 | } |
145 | } | 151 | } | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
6 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
3 | import org.apache.karaf.shell.commands.Argument; | 7 | import org.apache.karaf.shell.commands.Argument; |
4 | import org.apache.karaf.shell.commands.Command; | 8 | import org.apache.karaf.shell.commands.Command; |
5 | import org.onlab.onos.cli.AbstractShellCommand; | 9 | import org.onlab.onos.cli.AbstractShellCommand; |
10 | +import org.onlab.onos.net.ConnectPoint; | ||
6 | import org.onlab.onos.net.Link; | 11 | import org.onlab.onos.net.Link; |
7 | import org.onlab.onos.net.link.LinkService; | 12 | import org.onlab.onos.net.link.LinkService; |
8 | 13 | ||
... | @@ -27,9 +32,55 @@ public class LinksListCommand extends AbstractShellCommand { | ... | @@ -27,9 +32,55 @@ public class LinksListCommand extends AbstractShellCommand { |
27 | LinkService service = get(LinkService.class); | 32 | LinkService service = get(LinkService.class); |
28 | Iterable<Link> links = uri != null ? | 33 | Iterable<Link> links = uri != null ? |
29 | service.getDeviceLinks(deviceId(uri)) : service.getLinks(); | 34 | service.getDeviceLinks(deviceId(uri)) : service.getLinks(); |
35 | + if (outputJson()) { | ||
36 | + print("%s", json(links)); | ||
37 | + } else { | ||
38 | + for (Link link : links) { | ||
39 | + print(linkString(link)); | ||
40 | + } | ||
41 | + } | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Produces a JSON array containing the specified links. | ||
46 | + * | ||
47 | + * @param links collection of links | ||
48 | + * @return JSON array | ||
49 | + */ | ||
50 | + public static JsonNode json(Iterable<Link> links) { | ||
51 | + ObjectMapper mapper = new ObjectMapper(); | ||
52 | + ArrayNode result = mapper.createArrayNode(); | ||
30 | for (Link link : links) { | 53 | for (Link link : links) { |
31 | - print(linkString(link)); | 54 | + result.add(json(mapper, link)); |
32 | } | 55 | } |
56 | + return result; | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * Produces a JSON object for the specified link. | ||
61 | + * | ||
62 | + * @param mapper object mapper | ||
63 | + * @param link link to encode | ||
64 | + * @return JSON object | ||
65 | + */ | ||
66 | + public static ObjectNode json(ObjectMapper mapper, Link link) { | ||
67 | + ObjectNode result = mapper.createObjectNode(); | ||
68 | + result.set("src", json(mapper, link.src())); | ||
69 | + result.set("dst", json(mapper, link.dst())); | ||
70 | + return result; | ||
71 | + } | ||
72 | + | ||
73 | + /** | ||
74 | + * Produces a JSON object for the specified connect point. | ||
75 | + * | ||
76 | + * @param mapper object mapper | ||
77 | + * @param connectPoint connection point to encode | ||
78 | + * @return JSON object | ||
79 | + */ | ||
80 | + public static ObjectNode json(ObjectMapper mapper, ConnectPoint connectPoint) { | ||
81 | + return mapper.createObjectNode() | ||
82 | + .put("device", connectPoint.deviceId().toString()) | ||
83 | + .put("port", connectPoint.port().toString()); | ||
33 | } | 84 | } |
34 | 85 | ||
35 | /** | 86 | /** | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.JsonNode; | ||
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
5 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
3 | import org.apache.karaf.shell.commands.Argument; | 6 | import org.apache.karaf.shell.commands.Argument; |
4 | import org.apache.karaf.shell.commands.Command; | 7 | import org.apache.karaf.shell.commands.Command; |
5 | import org.onlab.onos.net.Link; | 8 | import org.onlab.onos.net.Link; |
... | @@ -32,9 +35,30 @@ public class PathListCommand extends TopologyCommand { | ... | @@ -32,9 +35,30 @@ public class PathListCommand extends TopologyCommand { |
32 | protected void execute() { | 35 | protected void execute() { |
33 | init(); | 36 | init(); |
34 | Set<Path> paths = service.getPaths(topology, deviceId(src), deviceId(dst)); | 37 | Set<Path> paths = service.getPaths(topology, deviceId(src), deviceId(dst)); |
38 | + if (outputJson()) { | ||
39 | + print("%s", json(paths)); | ||
40 | + } else { | ||
41 | + for (Path path : paths) { | ||
42 | + print(pathString(path)); | ||
43 | + } | ||
44 | + } | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Produces a JSON array containing the specified paths. | ||
49 | + * | ||
50 | + * @param paths collection of paths | ||
51 | + * @return JSON array | ||
52 | + */ | ||
53 | + public static JsonNode json(Iterable<Path> paths) { | ||
54 | + ObjectMapper mapper = new ObjectMapper(); | ||
55 | + ArrayNode result = mapper.createArrayNode(); | ||
35 | for (Path path : paths) { | 56 | for (Path path : paths) { |
36 | - print(pathString(path)); | 57 | + result.add(LinksListCommand.json(mapper, path) |
58 | + .put("cost", path.cost()) | ||
59 | + .set("links", LinksListCommand.json(path.links()))); | ||
37 | } | 60 | } |
61 | + return result; | ||
38 | } | 62 | } |
39 | 63 | ||
40 | /** | 64 | /** | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
3 | import org.apache.karaf.shell.commands.Command; | 4 | import org.apache.karaf.shell.commands.Command; |
4 | import org.onlab.onos.cli.AbstractShellCommand; | 5 | import org.onlab.onos.cli.AbstractShellCommand; |
5 | import org.onlab.onos.net.topology.Topology; | 6 | import org.onlab.onos.net.topology.Topology; |
... | @@ -30,8 +31,17 @@ public class TopologyCommand extends AbstractShellCommand { | ... | @@ -30,8 +31,17 @@ public class TopologyCommand extends AbstractShellCommand { |
30 | @Override | 31 | @Override |
31 | protected void execute() { | 32 | protected void execute() { |
32 | init(); | 33 | init(); |
33 | - print(FMT, topology.time(), topology.deviceCount(), topology.linkCount(), | 34 | + if (outputJson()) { |
34 | - topology.clusterCount(), topology.pathCount()); | 35 | + print("%s", new ObjectMapper().createObjectNode() |
36 | + .put("time", topology.time()) | ||
37 | + .put("deviceCount", topology.deviceCount()) | ||
38 | + .put("linkCount", topology.linkCount()) | ||
39 | + .put("clusterCount", topology.clusterCount()) | ||
40 | + .put("pathCount", topology.pathCount())); | ||
41 | + } else { | ||
42 | + print(FMT, topology.time(), topology.deviceCount(), topology.linkCount(), | ||
43 | + topology.clusterCount(), topology.pathCount()); | ||
44 | + } | ||
35 | } | 45 | } |
36 | 46 | ||
37 | } | 47 | } | ... | ... |
... | @@ -13,6 +13,10 @@ | ... | @@ -13,6 +13,10 @@ |
13 | <command> | 13 | <command> |
14 | <action class="org.onlab.onos.cli.NodeRemoveCommand"/> | 14 | <action class="org.onlab.onos.cli.NodeRemoveCommand"/> |
15 | </command> | 15 | </command> |
16 | + | ||
17 | + <command> | ||
18 | + <action class="org.onlab.onos.cli.RolesCommand"/> | ||
19 | + </command> | ||
16 | <command> | 20 | <command> |
17 | <action class="org.onlab.onos.cli.MastersListCommand"/> | 21 | <action class="org.onlab.onos.cli.MastersListCommand"/> |
18 | <completers> | 22 | <completers> | ... | ... |
... | @@ -12,7 +12,11 @@ public final class ControllerNodeToNodeId | ... | @@ -12,7 +12,11 @@ public final class ControllerNodeToNodeId |
12 | 12 | ||
13 | @Override | 13 | @Override |
14 | public NodeId apply(ControllerNode input) { | 14 | public NodeId apply(ControllerNode input) { |
15 | - return input.id(); | 15 | + if (input == null) { |
16 | + return null; | ||
17 | + } else { | ||
18 | + return input.id(); | ||
19 | + } | ||
16 | } | 20 | } |
17 | 21 | ||
18 | /** | 22 | /** | ... | ... |
1 | package org.onlab.onos.mastership; | 1 | package org.onlab.onos.mastership; |
2 | 2 | ||
3 | +import java.util.List; | ||
3 | import java.util.Set; | 4 | import java.util.Set; |
4 | 5 | ||
5 | import org.onlab.onos.cluster.NodeId; | 6 | import org.onlab.onos.cluster.NodeId; |
... | @@ -50,6 +51,15 @@ public interface MastershipService { | ... | @@ -50,6 +51,15 @@ public interface MastershipService { |
50 | NodeId getMasterFor(DeviceId deviceId); | 51 | NodeId getMasterFor(DeviceId deviceId); |
51 | 52 | ||
52 | /** | 53 | /** |
54 | + * Returns controllers connected to a given device, in order of | ||
55 | + * preference. The first entry in the list is the current master. | ||
56 | + * | ||
57 | + * @param deviceId the identifier of the device | ||
58 | + * @return a list of controller IDs | ||
59 | + */ | ||
60 | + List<NodeId> getNodesFor(DeviceId deviceId); | ||
61 | + | ||
62 | + /** | ||
53 | * Returns the devices for which a controller is master. | 63 | * Returns the devices for which a controller is master. |
54 | * | 64 | * |
55 | * @param nodeId the ID of the controller | 65 | * @param nodeId the ID of the controller | ... | ... |
1 | package org.onlab.onos.mastership; | 1 | package org.onlab.onos.mastership; |
2 | 2 | ||
3 | +import java.util.List; | ||
3 | import java.util.Set; | 4 | import java.util.Set; |
4 | 5 | ||
5 | import org.onlab.onos.cluster.NodeId; | 6 | import org.onlab.onos.cluster.NodeId; |
... | @@ -41,6 +42,15 @@ public interface MastershipStore extends Store<MastershipEvent, MastershipStoreD | ... | @@ -41,6 +42,15 @@ public interface MastershipStore extends Store<MastershipEvent, MastershipStoreD |
41 | NodeId getMaster(DeviceId deviceId); | 42 | NodeId getMaster(DeviceId deviceId); |
42 | 43 | ||
43 | /** | 44 | /** |
45 | + * Returns the controllers connected to a device, in mastership- | ||
46 | + * preference order. | ||
47 | + * | ||
48 | + * @param deviceId the device identifier | ||
49 | + * @return an ordered list of controller IDs | ||
50 | + */ | ||
51 | + List<NodeId> getNodes(DeviceId deviceId); | ||
52 | + | ||
53 | + /** | ||
44 | * Returns the devices that a controller instance is master of. | 54 | * Returns the devices that a controller instance is master of. |
45 | * | 55 | * |
46 | * @param nodeId the instance identifier | 56 | * @param nodeId the instance identifier |
... | @@ -48,6 +58,7 @@ public interface MastershipStore extends Store<MastershipEvent, MastershipStoreD | ... | @@ -48,6 +58,7 @@ public interface MastershipStore extends Store<MastershipEvent, MastershipStoreD |
48 | */ | 58 | */ |
49 | Set<DeviceId> getDevices(NodeId nodeId); | 59 | Set<DeviceId> getDevices(NodeId nodeId); |
50 | 60 | ||
61 | + | ||
51 | /** | 62 | /** |
52 | * Sets a device's role for a specified controller instance. | 63 | * Sets a device's role for a specified controller instance. |
53 | * | 64 | * | ... | ... |
1 | package org.onlab.onos.net; | 1 | package org.onlab.onos.net; |
2 | 2 | ||
3 | import org.onlab.onos.net.provider.ProviderId; | 3 | import org.onlab.onos.net.provider.ProviderId; |
4 | +import org.onlab.packet.ChassisId; | ||
4 | 5 | ||
5 | import java.util.Objects; | 6 | import java.util.Objects; |
6 | 7 | ||
... | @@ -16,6 +17,7 @@ public class DefaultDevice extends AbstractElement implements Device { | ... | @@ -16,6 +17,7 @@ public class DefaultDevice extends AbstractElement implements Device { |
16 | private final String serialNumber; | 17 | private final String serialNumber; |
17 | private final String hwVersion; | 18 | private final String hwVersion; |
18 | private final String swVersion; | 19 | private final String swVersion; |
20 | + private final ChassisId chassisId; | ||
19 | 21 | ||
20 | // For serialization | 22 | // For serialization |
21 | private DefaultDevice() { | 23 | private DefaultDevice() { |
... | @@ -24,6 +26,7 @@ public class DefaultDevice extends AbstractElement implements Device { | ... | @@ -24,6 +26,7 @@ public class DefaultDevice extends AbstractElement implements Device { |
24 | this.hwVersion = null; | 26 | this.hwVersion = null; |
25 | this.swVersion = null; | 27 | this.swVersion = null; |
26 | this.serialNumber = null; | 28 | this.serialNumber = null; |
29 | + this.chassisId = null; | ||
27 | } | 30 | } |
28 | 31 | ||
29 | /** | 32 | /** |
... | @@ -40,13 +43,15 @@ public class DefaultDevice extends AbstractElement implements Device { | ... | @@ -40,13 +43,15 @@ public class DefaultDevice extends AbstractElement implements Device { |
40 | */ | 43 | */ |
41 | public DefaultDevice(ProviderId providerId, DeviceId id, Type type, | 44 | public DefaultDevice(ProviderId providerId, DeviceId id, Type type, |
42 | String manufacturer, String hwVersion, String swVersion, | 45 | String manufacturer, String hwVersion, String swVersion, |
43 | - String serialNumber, Annotations... annotations) { | 46 | + String serialNumber, ChassisId chassisId, |
47 | + Annotations... annotations) { | ||
44 | super(providerId, id, annotations); | 48 | super(providerId, id, annotations); |
45 | this.type = type; | 49 | this.type = type; |
46 | this.manufacturer = manufacturer; | 50 | this.manufacturer = manufacturer; |
47 | this.hwVersion = hwVersion; | 51 | this.hwVersion = hwVersion; |
48 | this.swVersion = swVersion; | 52 | this.swVersion = swVersion; |
49 | this.serialNumber = serialNumber; | 53 | this.serialNumber = serialNumber; |
54 | + this.chassisId = chassisId; | ||
50 | } | 55 | } |
51 | 56 | ||
52 | @Override | 57 | @Override |
... | @@ -80,6 +85,11 @@ public class DefaultDevice extends AbstractElement implements Device { | ... | @@ -80,6 +85,11 @@ public class DefaultDevice extends AbstractElement implements Device { |
80 | } | 85 | } |
81 | 86 | ||
82 | @Override | 87 | @Override |
88 | + public ChassisId chassisId() { | ||
89 | + return chassisId; | ||
90 | + } | ||
91 | + | ||
92 | + @Override | ||
83 | public int hashCode() { | 93 | public int hashCode() { |
84 | return Objects.hash(id, type, manufacturer, hwVersion, swVersion, serialNumber); | 94 | return Objects.hash(id, type, manufacturer, hwVersion, swVersion, serialNumber); |
85 | } | 95 | } | ... | ... |
1 | package org.onlab.onos.net; | 1 | package org.onlab.onos.net; |
2 | 2 | ||
3 | +import org.onlab.packet.ChassisId; | ||
4 | + | ||
3 | /** | 5 | /** |
4 | * Representation of a network infrastructure device. | 6 | * Representation of a network infrastructure device. |
5 | */ | 7 | */ |
... | @@ -54,6 +56,13 @@ public interface Device extends Element { | ... | @@ -54,6 +56,13 @@ public interface Device extends Element { |
54 | */ | 56 | */ |
55 | String serialNumber(); | 57 | String serialNumber(); |
56 | 58 | ||
59 | + /** | ||
60 | + * Returns the device chassis id. | ||
61 | + * | ||
62 | + * @return chassis id | ||
63 | + */ | ||
64 | + ChassisId chassisId(); | ||
65 | + | ||
57 | // Device realizedBy(); ? | 66 | // Device realizedBy(); ? |
58 | 67 | ||
59 | // ports are not provided directly, but rather via DeviceService.getPorts(Device device); | 68 | // ports are not provided directly, but rather via DeviceService.getPorts(Device device); | ... | ... |
... | @@ -2,6 +2,7 @@ package org.onlab.onos.net.device; | ... | @@ -2,6 +2,7 @@ package org.onlab.onos.net.device; |
2 | 2 | ||
3 | import org.onlab.onos.net.AbstractDescription; | 3 | import org.onlab.onos.net.AbstractDescription; |
4 | import org.onlab.onos.net.SparseAnnotations; | 4 | import org.onlab.onos.net.SparseAnnotations; |
5 | +import org.onlab.packet.ChassisId; | ||
5 | 6 | ||
6 | import java.net.URI; | 7 | import java.net.URI; |
7 | 8 | ||
... | @@ -20,6 +21,7 @@ public class DefaultDeviceDescription extends AbstractDescription | ... | @@ -20,6 +21,7 @@ public class DefaultDeviceDescription extends AbstractDescription |
20 | private final String hwVersion; | 21 | private final String hwVersion; |
21 | private final String swVersion; | 22 | private final String swVersion; |
22 | private final String serialNumber; | 23 | private final String serialNumber; |
24 | + private final ChassisId chassisId; | ||
23 | 25 | ||
24 | /** | 26 | /** |
25 | * Creates a device description using the supplied information. | 27 | * Creates a device description using the supplied information. |
... | @@ -34,7 +36,7 @@ public class DefaultDeviceDescription extends AbstractDescription | ... | @@ -34,7 +36,7 @@ public class DefaultDeviceDescription extends AbstractDescription |
34 | */ | 36 | */ |
35 | public DefaultDeviceDescription(URI uri, Type type, String manufacturer, | 37 | public DefaultDeviceDescription(URI uri, Type type, String manufacturer, |
36 | String hwVersion, String swVersion, | 38 | String hwVersion, String swVersion, |
37 | - String serialNumber, | 39 | + String serialNumber, ChassisId chassis, |
38 | SparseAnnotations... annotations) { | 40 | SparseAnnotations... annotations) { |
39 | super(annotations); | 41 | super(annotations); |
40 | this.uri = checkNotNull(uri, "Device URI cannot be null"); | 42 | this.uri = checkNotNull(uri, "Device URI cannot be null"); |
... | @@ -43,6 +45,7 @@ public class DefaultDeviceDescription extends AbstractDescription | ... | @@ -43,6 +45,7 @@ public class DefaultDeviceDescription extends AbstractDescription |
43 | this.hwVersion = hwVersion; | 45 | this.hwVersion = hwVersion; |
44 | this.swVersion = swVersion; | 46 | this.swVersion = swVersion; |
45 | this.serialNumber = serialNumber; | 47 | this.serialNumber = serialNumber; |
48 | + this.chassisId = chassis; | ||
46 | } | 49 | } |
47 | 50 | ||
48 | /** | 51 | /** |
... | @@ -54,7 +57,7 @@ public class DefaultDeviceDescription extends AbstractDescription | ... | @@ -54,7 +57,7 @@ public class DefaultDeviceDescription extends AbstractDescription |
54 | SparseAnnotations... annotations) { | 57 | SparseAnnotations... annotations) { |
55 | this(base.deviceURI(), base.type(), base.manufacturer(), | 58 | this(base.deviceURI(), base.type(), base.manufacturer(), |
56 | base.hwVersion(), base.swVersion(), base.serialNumber(), | 59 | base.hwVersion(), base.swVersion(), base.serialNumber(), |
57 | - annotations); | 60 | + base.chassisId(), annotations); |
58 | } | 61 | } |
59 | 62 | ||
60 | @Override | 63 | @Override |
... | @@ -88,6 +91,11 @@ public class DefaultDeviceDescription extends AbstractDescription | ... | @@ -88,6 +91,11 @@ public class DefaultDeviceDescription extends AbstractDescription |
88 | } | 91 | } |
89 | 92 | ||
90 | @Override | 93 | @Override |
94 | + public ChassisId chassisId() { | ||
95 | + return chassisId; | ||
96 | + } | ||
97 | + | ||
98 | + @Override | ||
91 | public String toString() { | 99 | public String toString() { |
92 | return toStringHelper(this) | 100 | return toStringHelper(this) |
93 | .add("uri", uri).add("type", type).add("mfr", manufacturer) | 101 | .add("uri", uri).add("type", type).add("mfr", manufacturer) |
... | @@ -104,5 +112,6 @@ public class DefaultDeviceDescription extends AbstractDescription | ... | @@ -104,5 +112,6 @@ public class DefaultDeviceDescription extends AbstractDescription |
104 | this.hwVersion = null; | 112 | this.hwVersion = null; |
105 | this.swVersion = null; | 113 | this.swVersion = null; |
106 | this.serialNumber = null; | 114 | this.serialNumber = null; |
115 | + this.chassisId = null; | ||
107 | } | 116 | } |
108 | } | 117 | } | ... | ... |
... | @@ -2,6 +2,7 @@ package org.onlab.onos.net.device; | ... | @@ -2,6 +2,7 @@ package org.onlab.onos.net.device; |
2 | 2 | ||
3 | import org.onlab.onos.net.Description; | 3 | import org.onlab.onos.net.Description; |
4 | import org.onlab.onos.net.Device; | 4 | import org.onlab.onos.net.Device; |
5 | +import org.onlab.packet.ChassisId; | ||
5 | 6 | ||
6 | import java.net.URI; | 7 | import java.net.URI; |
7 | 8 | ||
... | @@ -54,4 +55,11 @@ public interface DeviceDescription extends Description { | ... | @@ -54,4 +55,11 @@ public interface DeviceDescription extends Description { |
54 | */ | 55 | */ |
55 | String serialNumber(); | 56 | String serialNumber(); |
56 | 57 | ||
58 | + /** | ||
59 | + * Returns a device chassis id. | ||
60 | + * | ||
61 | + * @return chassis id | ||
62 | + */ | ||
63 | + ChassisId chassisId(); | ||
64 | + | ||
57 | } | 65 | } | ... | ... |
... | @@ -6,9 +6,10 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -6,9 +6,10 @@ import static org.slf4j.LoggerFactory.getLogger; |
6 | import org.onlab.onos.net.DeviceId; | 6 | import org.onlab.onos.net.DeviceId; |
7 | import org.slf4j.Logger; | 7 | import org.slf4j.Logger; |
8 | 8 | ||
9 | -public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { | 9 | +public class DefaultFlowEntry extends DefaultFlowRule |
10 | + implements FlowEntry, StoredFlowEntry { | ||
10 | 11 | ||
11 | - private final Logger log = getLogger(getClass()); | 12 | + private static final Logger log = getLogger(DefaultFlowEntry.class); |
12 | 13 | ||
13 | private long life; | 14 | private long life; |
14 | private long packets; | 15 | private long packets; | ... | ... |
... | @@ -11,7 +11,7 @@ import org.slf4j.Logger; | ... | @@ -11,7 +11,7 @@ import org.slf4j.Logger; |
11 | 11 | ||
12 | public class DefaultFlowRule implements FlowRule { | 12 | public class DefaultFlowRule implements FlowRule { |
13 | 13 | ||
14 | - private final Logger log = getLogger(getClass()); | 14 | + private static final Logger log = getLogger(DefaultFlowRule.class); |
15 | 15 | ||
16 | private final DeviceId deviceId; | 16 | private final DeviceId deviceId; |
17 | private final int priority; | 17 | private final int priority; | ... | ... |
... | @@ -65,6 +65,7 @@ public interface FlowEntry extends FlowRule { | ... | @@ -65,6 +65,7 @@ public interface FlowEntry extends FlowRule { |
65 | */ | 65 | */ |
66 | long bytes(); | 66 | long bytes(); |
67 | 67 | ||
68 | + // TODO: consider removing this attribute | ||
68 | /** | 69 | /** |
69 | * When this flow entry was last deemed active. | 70 | * When this flow entry was last deemed active. |
70 | * @return epoch time of last activity | 71 | * @return epoch time of last activity |
... | @@ -72,35 +73,6 @@ public interface FlowEntry extends FlowRule { | ... | @@ -72,35 +73,6 @@ public interface FlowEntry extends FlowRule { |
72 | long lastSeen(); | 73 | long lastSeen(); |
73 | 74 | ||
74 | /** | 75 | /** |
75 | - * Sets the last active epoch time. | ||
76 | - */ | ||
77 | - void setLastSeen(); | ||
78 | - | ||
79 | - /** | ||
80 | - * Sets the new state for this entry. | ||
81 | - * @param newState new flow entry state. | ||
82 | - */ | ||
83 | - void setState(FlowEntryState newState); | ||
84 | - | ||
85 | - /** | ||
86 | - * Sets how long this entry has been entered in the system. | ||
87 | - * @param life epoch time | ||
88 | - */ | ||
89 | - void setLife(long life); | ||
90 | - | ||
91 | - /** | ||
92 | - * Number of packets seen by this entry. | ||
93 | - * @param packets a long value | ||
94 | - */ | ||
95 | - void setPackets(long packets); | ||
96 | - | ||
97 | - /** | ||
98 | - * Number of bytes seen by this rule. | ||
99 | - * @param bytes a long value | ||
100 | - */ | ||
101 | - void setBytes(long bytes); | ||
102 | - | ||
103 | - /** | ||
104 | * Indicates the error type. | 76 | * Indicates the error type. |
105 | * @return an integer value of the error | 77 | * @return an integer value of the error |
106 | */ | 78 | */ | ... | ... |
1 | +package org.onlab.onos.net.flow; | ||
2 | + | ||
3 | + | ||
4 | +public interface StoredFlowEntry extends FlowEntry { | ||
5 | + | ||
6 | + /** | ||
7 | + * Sets the last active epoch time. | ||
8 | + */ | ||
9 | + void setLastSeen(); | ||
10 | + | ||
11 | + /** | ||
12 | + * Sets the new state for this entry. | ||
13 | + * @param newState new flow entry state. | ||
14 | + */ | ||
15 | + void setState(FlowEntryState newState); | ||
16 | + | ||
17 | + /** | ||
18 | + * Sets how long this entry has been entered in the system. | ||
19 | + * @param life epoch time | ||
20 | + */ | ||
21 | + void setLife(long life); | ||
22 | + | ||
23 | + /** | ||
24 | + * Number of packets seen by this entry. | ||
25 | + * @param packets a long value | ||
26 | + */ | ||
27 | + void setPackets(long packets); | ||
28 | + | ||
29 | + /** | ||
30 | + * Number of bytes seen by this rule. | ||
31 | + * @param bytes a long value | ||
32 | + */ | ||
33 | + void setBytes(long bytes); | ||
34 | + | ||
35 | +} |
1 | package org.onlab.onos.net.host; | 1 | package org.onlab.onos.net.host; |
2 | 2 | ||
3 | +import java.util.Collections; | ||
4 | +import java.util.Set; | ||
5 | + | ||
3 | import org.onlab.onos.net.AbstractDescription; | 6 | import org.onlab.onos.net.AbstractDescription; |
4 | import org.onlab.onos.net.HostLocation; | 7 | import org.onlab.onos.net.HostLocation; |
5 | import org.onlab.onos.net.SparseAnnotations; | 8 | import org.onlab.onos.net.SparseAnnotations; |
... | @@ -7,6 +10,8 @@ import org.onlab.packet.IpPrefix; | ... | @@ -7,6 +10,8 @@ import org.onlab.packet.IpPrefix; |
7 | import org.onlab.packet.MacAddress; | 10 | import org.onlab.packet.MacAddress; |
8 | import org.onlab.packet.VlanId; | 11 | import org.onlab.packet.VlanId; |
9 | 12 | ||
13 | +import com.google.common.collect.ImmutableSet; | ||
14 | + | ||
10 | import static com.google.common.base.MoreObjects.toStringHelper; | 15 | import static com.google.common.base.MoreObjects.toStringHelper; |
11 | 16 | ||
12 | /** | 17 | /** |
... | @@ -18,7 +23,7 @@ public class DefaultHostDescription extends AbstractDescription | ... | @@ -18,7 +23,7 @@ public class DefaultHostDescription extends AbstractDescription |
18 | private final MacAddress mac; | 23 | private final MacAddress mac; |
19 | private final VlanId vlan; | 24 | private final VlanId vlan; |
20 | private final HostLocation location; | 25 | private final HostLocation location; |
21 | - private final IpPrefix ip; | 26 | + private final Set<IpPrefix> ip; |
22 | 27 | ||
23 | /** | 28 | /** |
24 | * Creates a host description using the supplied information. | 29 | * Creates a host description using the supplied information. |
... | @@ -31,7 +36,7 @@ public class DefaultHostDescription extends AbstractDescription | ... | @@ -31,7 +36,7 @@ public class DefaultHostDescription extends AbstractDescription |
31 | public DefaultHostDescription(MacAddress mac, VlanId vlan, | 36 | public DefaultHostDescription(MacAddress mac, VlanId vlan, |
32 | HostLocation location, | 37 | HostLocation location, |
33 | SparseAnnotations... annotations) { | 38 | SparseAnnotations... annotations) { |
34 | - this(mac, vlan, location, null, annotations); | 39 | + this(mac, vlan, location, Collections.<IpPrefix>emptySet(), annotations); |
35 | } | 40 | } |
36 | 41 | ||
37 | /** | 42 | /** |
... | @@ -46,11 +51,26 @@ public class DefaultHostDescription extends AbstractDescription | ... | @@ -46,11 +51,26 @@ public class DefaultHostDescription extends AbstractDescription |
46 | public DefaultHostDescription(MacAddress mac, VlanId vlan, | 51 | public DefaultHostDescription(MacAddress mac, VlanId vlan, |
47 | HostLocation location, IpPrefix ip, | 52 | HostLocation location, IpPrefix ip, |
48 | SparseAnnotations... annotations) { | 53 | SparseAnnotations... annotations) { |
54 | + this(mac, vlan, location, ImmutableSet.of(ip), annotations); | ||
55 | + } | ||
56 | + | ||
57 | + /** | ||
58 | + * Creates a host description using the supplied information. | ||
59 | + * | ||
60 | + * @param mac host MAC address | ||
61 | + * @param vlan host VLAN identifier | ||
62 | + * @param location host location | ||
63 | + * @param ip host IP addresses | ||
64 | + * @param annotations optional key/value annotations map | ||
65 | + */ | ||
66 | + public DefaultHostDescription(MacAddress mac, VlanId vlan, | ||
67 | + HostLocation location, Set<IpPrefix> ip, | ||
68 | + SparseAnnotations... annotations) { | ||
49 | super(annotations); | 69 | super(annotations); |
50 | this.mac = mac; | 70 | this.mac = mac; |
51 | this.vlan = vlan; | 71 | this.vlan = vlan; |
52 | this.location = location; | 72 | this.location = location; |
53 | - this.ip = ip; | 73 | + this.ip = ImmutableSet.copyOf(ip); |
54 | } | 74 | } |
55 | 75 | ||
56 | @Override | 76 | @Override |
... | @@ -69,7 +89,7 @@ public class DefaultHostDescription extends AbstractDescription | ... | @@ -69,7 +89,7 @@ public class DefaultHostDescription extends AbstractDescription |
69 | } | 89 | } |
70 | 90 | ||
71 | @Override | 91 | @Override |
72 | - public IpPrefix ipAddress() { | 92 | + public Set<IpPrefix> ipAddress() { |
73 | return ip; | 93 | return ip; |
74 | } | 94 | } |
75 | 95 | ... | ... |
1 | package org.onlab.onos.net.host; | 1 | package org.onlab.onos.net.host; |
2 | 2 | ||
3 | +import java.util.Set; | ||
4 | + | ||
3 | import org.onlab.onos.net.Description; | 5 | import org.onlab.onos.net.Description; |
4 | import org.onlab.onos.net.HostLocation; | 6 | import org.onlab.onos.net.HostLocation; |
5 | import org.onlab.packet.IpPrefix; | 7 | import org.onlab.packet.IpPrefix; |
... | @@ -38,6 +40,6 @@ public interface HostDescription extends Description { | ... | @@ -38,6 +40,6 @@ public interface HostDescription extends Description { |
38 | * @return host IP address | 40 | * @return host IP address |
39 | */ | 41 | */ |
40 | // FIXME: Switch to IpAddress | 42 | // FIXME: Switch to IpAddress |
41 | - IpPrefix ipAddress(); | 43 | + Set<IpPrefix> ipAddress(); |
42 | 44 | ||
43 | } | 45 | } | ... | ... |
... | @@ -12,7 +12,7 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -12,7 +12,7 @@ import static com.google.common.base.Preconditions.checkNotNull; |
12 | /** | 12 | /** |
13 | * Abstraction of end-station to end-station bidirectional connectivity. | 13 | * Abstraction of end-station to end-station bidirectional connectivity. |
14 | */ | 14 | */ |
15 | -public class HostToHostIntent extends ConnectivityIntent { | 15 | +public final class HostToHostIntent extends ConnectivityIntent { |
16 | 16 | ||
17 | private final HostId one; | 17 | private final HostId one; |
18 | private final HostId two; | 18 | private final HostId two; | ... | ... |
... | @@ -4,6 +4,7 @@ import java.util.Collection; | ... | @@ -4,6 +4,7 @@ import java.util.Collection; |
4 | import java.util.Objects; | 4 | import java.util.Objects; |
5 | import java.util.Set; | 5 | import java.util.Set; |
6 | 6 | ||
7 | +import org.onlab.onos.net.ConnectPoint; | ||
7 | import org.onlab.onos.net.Link; | 8 | import org.onlab.onos.net.Link; |
8 | import org.onlab.onos.net.flow.TrafficSelector; | 9 | import org.onlab.onos.net.flow.TrafficSelector; |
9 | import org.onlab.onos.net.flow.TrafficTreatment; | 10 | import org.onlab.onos.net.flow.TrafficTreatment; |
... | @@ -14,10 +15,12 @@ import com.google.common.base.MoreObjects; | ... | @@ -14,10 +15,12 @@ import com.google.common.base.MoreObjects; |
14 | * Abstraction of a connectivity intent that is implemented by a set of path | 15 | * Abstraction of a connectivity intent that is implemented by a set of path |
15 | * segments. | 16 | * segments. |
16 | */ | 17 | */ |
17 | -public class LinkCollectionIntent extends ConnectivityIntent implements InstallableIntent { | 18 | +public final class LinkCollectionIntent extends ConnectivityIntent implements InstallableIntent { |
18 | 19 | ||
19 | private final Set<Link> links; | 20 | private final Set<Link> links; |
20 | 21 | ||
22 | + private final ConnectPoint egressPoint; | ||
23 | + | ||
21 | /** | 24 | /** |
22 | * Creates a new point-to-point intent with the supplied ingress/egress | 25 | * Creates a new point-to-point intent with the supplied ingress/egress |
23 | * ports and using the specified explicit path. | 26 | * ports and using the specified explicit path. |
... | @@ -26,19 +29,23 @@ public class LinkCollectionIntent extends ConnectivityIntent implements Installa | ... | @@ -26,19 +29,23 @@ public class LinkCollectionIntent extends ConnectivityIntent implements Installa |
26 | * @param selector traffic match | 29 | * @param selector traffic match |
27 | * @param treatment action | 30 | * @param treatment action |
28 | * @param links traversed links | 31 | * @param links traversed links |
32 | + * @param egressPoint egress point | ||
29 | * @throws NullPointerException {@code path} is null | 33 | * @throws NullPointerException {@code path} is null |
30 | */ | 34 | */ |
31 | public LinkCollectionIntent(IntentId id, | 35 | public LinkCollectionIntent(IntentId id, |
32 | TrafficSelector selector, | 36 | TrafficSelector selector, |
33 | TrafficTreatment treatment, | 37 | TrafficTreatment treatment, |
34 | - Set<Link> links) { | 38 | + Set<Link> links, |
39 | + ConnectPoint egressPoint) { | ||
35 | super(id, selector, treatment); | 40 | super(id, selector, treatment); |
36 | this.links = links; | 41 | this.links = links; |
42 | + this.egressPoint = egressPoint; | ||
37 | } | 43 | } |
38 | 44 | ||
39 | protected LinkCollectionIntent() { | 45 | protected LinkCollectionIntent() { |
40 | super(); | 46 | super(); |
41 | this.links = null; | 47 | this.links = null; |
48 | + this.egressPoint = null; | ||
42 | } | 49 | } |
43 | 50 | ||
44 | @Override | 51 | @Override |
... | @@ -46,10 +53,25 @@ public class LinkCollectionIntent extends ConnectivityIntent implements Installa | ... | @@ -46,10 +53,25 @@ public class LinkCollectionIntent extends ConnectivityIntent implements Installa |
46 | return links; | 53 | return links; |
47 | } | 54 | } |
48 | 55 | ||
56 | + /** | ||
57 | + * Returns the set of links that represent the network connections needed | ||
58 | + * by this intent. | ||
59 | + * | ||
60 | + * @return Set of links for the network hops needed by this intent | ||
61 | + */ | ||
49 | public Set<Link> links() { | 62 | public Set<Link> links() { |
50 | return links; | 63 | return links; |
51 | } | 64 | } |
52 | 65 | ||
66 | + /** | ||
67 | + * Returns the egress point of the intent. | ||
68 | + * | ||
69 | + * @return the egress point | ||
70 | + */ | ||
71 | + public ConnectPoint egressPoint() { | ||
72 | + return egressPoint; | ||
73 | + } | ||
74 | + | ||
53 | @Override | 75 | @Override |
54 | public boolean equals(Object o) { | 76 | public boolean equals(Object o) { |
55 | if (this == o) { | 77 | if (this == o) { |
... | @@ -64,12 +86,13 @@ public class LinkCollectionIntent extends ConnectivityIntent implements Installa | ... | @@ -64,12 +86,13 @@ public class LinkCollectionIntent extends ConnectivityIntent implements Installa |
64 | 86 | ||
65 | LinkCollectionIntent that = (LinkCollectionIntent) o; | 87 | LinkCollectionIntent that = (LinkCollectionIntent) o; |
66 | 88 | ||
67 | - return Objects.equals(this.links, that.links); | 89 | + return Objects.equals(this.links, that.links) && |
90 | + Objects.equals(this.egressPoint, that.egressPoint); | ||
68 | } | 91 | } |
69 | 92 | ||
70 | @Override | 93 | @Override |
71 | public int hashCode() { | 94 | public int hashCode() { |
72 | - return Objects.hash(super.hashCode(), links); | 95 | + return Objects.hash(super.hashCode(), links, egressPoint); |
73 | } | 96 | } |
74 | 97 | ||
75 | @Override | 98 | @Override |
... | @@ -79,6 +102,7 @@ public class LinkCollectionIntent extends ConnectivityIntent implements Installa | ... | @@ -79,6 +102,7 @@ public class LinkCollectionIntent extends ConnectivityIntent implements Installa |
79 | .add("match", selector()) | 102 | .add("match", selector()) |
80 | .add("action", treatment()) | 103 | .add("action", treatment()) |
81 | .add("links", links()) | 104 | .add("links", links()) |
105 | + .add("egress", egressPoint()) | ||
82 | .toString(); | 106 | .toString(); |
83 | } | 107 | } |
84 | } | 108 | } | ... | ... |
... | @@ -15,7 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -15,7 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; |
15 | /** | 15 | /** |
16 | * Abstraction of multiple source to single destination connectivity intent. | 16 | * Abstraction of multiple source to single destination connectivity intent. |
17 | */ | 17 | */ |
18 | -public class MultiPointToSinglePointIntent extends ConnectivityIntent { | 18 | +public final class MultiPointToSinglePointIntent extends ConnectivityIntent { |
19 | 19 | ||
20 | private final Set<ConnectPoint> ingressPoints; | 20 | private final Set<ConnectPoint> ingressPoints; |
21 | private final ConnectPoint egressPoint; | 21 | private final ConnectPoint egressPoint; | ... | ... |
... | @@ -24,7 +24,7 @@ public class DefaultInboundPacket implements InboundPacket { | ... | @@ -24,7 +24,7 @@ public class DefaultInboundPacket implements InboundPacket { |
24 | * @param parsed parsed ethernet frame | 24 | * @param parsed parsed ethernet frame |
25 | * @param unparsed unparsed raw bytes | 25 | * @param unparsed unparsed raw bytes |
26 | */ | 26 | */ |
27 | - public DefaultInboundPacket(ConnectPoint receivedFrom, Ethernet parsed, | 27 | + public DefaultInboundPacket(ConnectPoint receivedFrom, Ethernet parsed, |
28 | ByteBuffer unparsed) { | 28 | ByteBuffer unparsed) { |
29 | this.receivedFrom = receivedFrom; | 29 | this.receivedFrom = receivedFrom; |
30 | this.parsed = parsed; | 30 | this.parsed = parsed; | ... | ... |
... | @@ -62,6 +62,9 @@ public abstract class AbstractProviderRegistry<P extends Provider, S extends Pro | ... | @@ -62,6 +62,9 @@ public abstract class AbstractProviderRegistry<P extends Provider, S extends Pro |
62 | ((AbstractProviderService) service).invalidate(); | 62 | ((AbstractProviderService) service).invalidate(); |
63 | services.remove(provider.id()); | 63 | services.remove(provider.id()); |
64 | providers.remove(provider.id()); | 64 | providers.remove(provider.id()); |
65 | + if (!provider.id().isAncillary()) { | ||
66 | + providersByScheme.remove(provider.id().scheme()); | ||
67 | + } | ||
65 | } | 68 | } |
66 | } | 69 | } |
67 | 70 | ... | ... |
... | @@ -7,6 +7,8 @@ import org.onlab.onos.net.Provided; | ... | @@ -7,6 +7,8 @@ import org.onlab.onos.net.Provided; |
7 | */ | 7 | */ |
8 | public interface Topology extends Provided { | 8 | public interface Topology extends Provided { |
9 | 9 | ||
10 | + // FIXME: Following is not true right now. It is actually System.nanoTime(), | ||
11 | + // which has no relation to epoch time, wall clock, etc. | ||
10 | /** | 12 | /** |
11 | * Returns the time, specified in milliseconds since start of epoch, | 13 | * Returns the time, specified in milliseconds since start of epoch, |
12 | * when the topology became active and made available. | 14 | * when the topology became active and made available. | ... | ... |
... | @@ -37,6 +37,15 @@ public interface ClusterCommunicationService { | ... | @@ -37,6 +37,15 @@ public interface ClusterCommunicationService { |
37 | boolean multicast(ClusterMessage message, Set<NodeId> nodeIds) throws IOException; | 37 | boolean multicast(ClusterMessage message, Set<NodeId> nodeIds) throws IOException; |
38 | 38 | ||
39 | /** | 39 | /** |
40 | + * Sends a message synchronously. | ||
41 | + * @param message message to send | ||
42 | + * @param toNodeId recipient node identifier | ||
43 | + * @return ClusterMessageResponse which is reply future. | ||
44 | + * @throws IOException | ||
45 | + */ | ||
46 | + ClusterMessageResponse sendAndReceive(ClusterMessage message, NodeId toNodeId) throws IOException; | ||
47 | + | ||
48 | + /** | ||
40 | * Adds a new subscriber for the specified message subject. | 49 | * Adds a new subscriber for the specified message subject. |
41 | * | 50 | * |
42 | * @param subject message subject | 51 | * @param subject message subject | ... | ... |
1 | package org.onlab.onos.store.cluster.messaging; | 1 | package org.onlab.onos.store.cluster.messaging; |
2 | 2 | ||
3 | +import java.io.IOException; | ||
4 | + | ||
3 | import org.onlab.onos.cluster.NodeId; | 5 | import org.onlab.onos.cluster.NodeId; |
4 | 6 | ||
5 | // TODO: Should payload type be ByteBuffer? | 7 | // TODO: Should payload type be ByteBuffer? |
... | @@ -49,4 +51,14 @@ public class ClusterMessage { | ... | @@ -49,4 +51,14 @@ public class ClusterMessage { |
49 | public byte[] payload() { | 51 | public byte[] payload() { |
50 | return payload; | 52 | return payload; |
51 | } | 53 | } |
54 | + | ||
55 | + /** | ||
56 | + * Sends a response to the sender. | ||
57 | + * | ||
58 | + * @param data payload response. | ||
59 | + * @throws IOException | ||
60 | + */ | ||
61 | + public void respond(byte[] data) throws IOException { | ||
62 | + throw new IllegalStateException("One can only repond to message recived from others."); | ||
63 | + } | ||
52 | } | 64 | } | ... | ... |
core/api/src/main/java/org/onlab/onos/store/cluster/messaging/ClusterMessageResponse.java
0 → 100644
1 | +package org.onlab.onos.store.cluster.messaging; | ||
2 | + | ||
3 | +import java.util.concurrent.TimeUnit; | ||
4 | +import java.util.concurrent.TimeoutException; | ||
5 | + | ||
6 | +import org.onlab.onos.cluster.NodeId; | ||
7 | + | ||
8 | +public interface ClusterMessageResponse { | ||
9 | + public NodeId sender(); | ||
10 | + public byte[] get(long timeout, TimeUnit timeunit) throws TimeoutException; | ||
11 | + public byte[] get(long timeout) throws InterruptedException; | ||
12 | +} |
1 | package org.onlab.onos.cluster; | 1 | package org.onlab.onos.cluster; |
2 | 2 | ||
3 | +import static com.google.common.base.Predicates.notNull; | ||
3 | import static org.junit.Assert.*; | 4 | import static org.junit.Assert.*; |
4 | import static org.onlab.onos.cluster.ControllerNodeToNodeId.toNodeId; | 5 | import static org.onlab.onos.cluster.ControllerNodeToNodeId.toNodeId; |
5 | 6 | ||
... | @@ -30,12 +31,13 @@ public class ControllerNodeToNodeIdTest { | ... | @@ -30,12 +31,13 @@ public class ControllerNodeToNodeIdTest { |
30 | @Test | 31 | @Test |
31 | public final void testToNodeId() { | 32 | public final void testToNodeId() { |
32 | 33 | ||
33 | - final Iterable<ControllerNode> nodes = Arrays.asList(CN1, CN2, CN3); | 34 | + final Iterable<ControllerNode> nodes = Arrays.asList(CN1, CN2, CN3, null); |
34 | final List<NodeId> nodeIds = Arrays.asList(NID1, NID2, NID3); | 35 | final List<NodeId> nodeIds = Arrays.asList(NID1, NID2, NID3); |
35 | 36 | ||
36 | assertEquals(nodeIds, | 37 | assertEquals(nodeIds, |
37 | FluentIterable.from(nodes) | 38 | FluentIterable.from(nodes) |
38 | .transform(toNodeId()) | 39 | .transform(toNodeId()) |
40 | + .filter(notNull()) | ||
39 | .toList()); | 41 | .toList()); |
40 | } | 42 | } |
41 | 43 | ... | ... |
... | @@ -4,6 +4,7 @@ import org.onlab.onos.cluster.NodeId; | ... | @@ -4,6 +4,7 @@ import org.onlab.onos.cluster.NodeId; |
4 | import org.onlab.onos.net.DeviceId; | 4 | import org.onlab.onos.net.DeviceId; |
5 | import org.onlab.onos.net.MastershipRole; | 5 | import org.onlab.onos.net.MastershipRole; |
6 | 6 | ||
7 | +import java.util.List; | ||
7 | import java.util.Set; | 8 | import java.util.Set; |
8 | 9 | ||
9 | /** | 10 | /** |
... | @@ -46,4 +47,9 @@ public class MastershipServiceAdapter implements MastershipService { | ... | @@ -46,4 +47,9 @@ public class MastershipServiceAdapter implements MastershipService { |
46 | public MastershipTermService requestTermService() { | 47 | public MastershipTermService requestTermService() { |
47 | return null; | 48 | return null; |
48 | } | 49 | } |
50 | + | ||
51 | + @Override | ||
52 | + public List<NodeId> getNodesFor(DeviceId deviceId) { | ||
53 | + return null; | ||
54 | + } | ||
49 | } | 55 | } | ... | ... |
... | @@ -3,6 +3,7 @@ package org.onlab.onos.net; | ... | @@ -3,6 +3,7 @@ package org.onlab.onos.net; |
3 | import com.google.common.testing.EqualsTester; | 3 | import com.google.common.testing.EqualsTester; |
4 | import org.junit.Test; | 4 | import org.junit.Test; |
5 | import org.onlab.onos.net.provider.ProviderId; | 5 | import org.onlab.onos.net.provider.ProviderId; |
6 | +import org.onlab.packet.ChassisId; | ||
6 | 7 | ||
7 | import static org.junit.Assert.assertEquals; | 8 | import static org.junit.Assert.assertEquals; |
8 | import static org.onlab.onos.net.Device.Type.SWITCH; | 9 | import static org.onlab.onos.net.Device.Type.SWITCH; |
... | @@ -21,14 +22,15 @@ public class DefaultDeviceTest { | ... | @@ -21,14 +22,15 @@ public class DefaultDeviceTest { |
21 | static final String SW = "3.9.1"; | 22 | static final String SW = "3.9.1"; |
22 | static final String SN1 = "43311-12345"; | 23 | static final String SN1 = "43311-12345"; |
23 | static final String SN2 = "42346-43512"; | 24 | static final String SN2 = "42346-43512"; |
25 | + static final ChassisId CID = new ChassisId(); | ||
24 | 26 | ||
25 | @Test | 27 | @Test |
26 | public void testEquality() { | 28 | public void testEquality() { |
27 | - Device d1 = new DefaultDevice(PID, DID1, SWITCH, MFR, HW, SW, SN1); | 29 | + Device d1 = new DefaultDevice(PID, DID1, SWITCH, MFR, HW, SW, SN1, CID); |
28 | - Device d2 = new DefaultDevice(PID, DID1, SWITCH, MFR, HW, SW, SN1); | 30 | + Device d2 = new DefaultDevice(PID, DID1, SWITCH, MFR, HW, SW, SN1, CID); |
29 | - Device d3 = new DefaultDevice(PID, DID2, SWITCH, MFR, HW, SW, SN2); | 31 | + Device d3 = new DefaultDevice(PID, DID2, SWITCH, MFR, HW, SW, SN2, CID); |
30 | - Device d4 = new DefaultDevice(PID, DID2, SWITCH, MFR, HW, SW, SN2); | 32 | + Device d4 = new DefaultDevice(PID, DID2, SWITCH, MFR, HW, SW, SN2, CID); |
31 | - Device d5 = new DefaultDevice(PID, DID2, SWITCH, MFR, HW, SW, SN1); | 33 | + Device d5 = new DefaultDevice(PID, DID2, SWITCH, MFR, HW, SW, SN1, CID); |
32 | 34 | ||
33 | new EqualsTester().addEqualityGroup(d1, d2) | 35 | new EqualsTester().addEqualityGroup(d1, d2) |
34 | .addEqualityGroup(d3, d4) | 36 | .addEqualityGroup(d3, d4) |
... | @@ -38,13 +40,13 @@ public class DefaultDeviceTest { | ... | @@ -38,13 +40,13 @@ public class DefaultDeviceTest { |
38 | 40 | ||
39 | @Test | 41 | @Test |
40 | public void basics() { | 42 | public void basics() { |
41 | - Device device = new DefaultDevice(PID, DID1, SWITCH, MFR, HW, SW, SN1); | 43 | + Device device = new DefaultDevice(PID, DID1, SWITCH, MFR, HW, SW, SN1, CID); |
42 | validate(device); | 44 | validate(device); |
43 | } | 45 | } |
44 | 46 | ||
45 | @Test | 47 | @Test |
46 | public void annotations() { | 48 | public void annotations() { |
47 | - Device device = new DefaultDevice(PID, DID1, SWITCH, MFR, HW, SW, SN1, | 49 | + Device device = new DefaultDevice(PID, DID1, SWITCH, MFR, HW, SW, SN1, CID, |
48 | DefaultAnnotations.builder().set("foo", "bar").build()); | 50 | DefaultAnnotations.builder().set("foo", "bar").build()); |
49 | validate(device); | 51 | validate(device); |
50 | assertEquals("incorrect provider", "bar", device.annotations().value("foo")); | 52 | assertEquals("incorrect provider", "bar", device.annotations().value("foo")); | ... | ... |
... | @@ -3,6 +3,7 @@ package org.onlab.onos.net; | ... | @@ -3,6 +3,7 @@ package org.onlab.onos.net; |
3 | import com.google.common.testing.EqualsTester; | 3 | import com.google.common.testing.EqualsTester; |
4 | import org.junit.Test; | 4 | import org.junit.Test; |
5 | import org.onlab.onos.net.provider.ProviderId; | 5 | import org.onlab.onos.net.provider.ProviderId; |
6 | +import org.onlab.packet.ChassisId; | ||
6 | 7 | ||
7 | import static org.junit.Assert.assertEquals; | 8 | import static org.junit.Assert.assertEquals; |
8 | import static org.onlab.onos.net.Device.Type.SWITCH; | 9 | import static org.onlab.onos.net.Device.Type.SWITCH; |
... | @@ -22,7 +23,8 @@ public class DefaultPortTest { | ... | @@ -22,7 +23,8 @@ public class DefaultPortTest { |
22 | 23 | ||
23 | @Test | 24 | @Test |
24 | public void testEquality() { | 25 | public void testEquality() { |
25 | - Device device = new DefaultDevice(PID, DID1, SWITCH, "m", "h", "s", "n"); | 26 | + Device device = new DefaultDevice(PID, DID1, SWITCH, "m", "h", "s", "n", |
27 | + new ChassisId()); | ||
26 | Port p1 = new DefaultPort(device, portNumber(1), true); | 28 | Port p1 = new DefaultPort(device, portNumber(1), true); |
27 | Port p2 = new DefaultPort(device, portNumber(1), true); | 29 | Port p2 = new DefaultPort(device, portNumber(1), true); |
28 | Port p3 = new DefaultPort(device, portNumber(2), true); | 30 | Port p3 = new DefaultPort(device, portNumber(2), true); |
... | @@ -37,7 +39,8 @@ public class DefaultPortTest { | ... | @@ -37,7 +39,8 @@ public class DefaultPortTest { |
37 | 39 | ||
38 | @Test | 40 | @Test |
39 | public void basics() { | 41 | public void basics() { |
40 | - Device device = new DefaultDevice(PID, DID1, SWITCH, "m", "h", "s", "n"); | 42 | + Device device = new DefaultDevice(PID, DID1, SWITCH, "m", "h", "s", "n", |
43 | + new ChassisId()); | ||
41 | Port port = new DefaultPort(device, portNumber(1), true); | 44 | Port port = new DefaultPort(device, portNumber(1), true); |
42 | assertEquals("incorrect element", device, port.element()); | 45 | assertEquals("incorrect element", device, port.element()); |
43 | assertEquals("incorrect number", portNumber(1), port.number()); | 46 | assertEquals("incorrect number", portNumber(1), port.number()); | ... | ... |
1 | package org.onlab.onos.net; | 1 | package org.onlab.onos.net; |
2 | 2 | ||
3 | import org.onlab.onos.net.provider.ProviderId; | 3 | import org.onlab.onos.net.provider.ProviderId; |
4 | +import org.onlab.packet.ChassisId; | ||
4 | import org.onlab.packet.IpPrefix; | 5 | import org.onlab.packet.IpPrefix; |
5 | 6 | ||
6 | import java.util.ArrayList; | 7 | import java.util.ArrayList; |
... | @@ -37,7 +38,7 @@ public final class NetTestTools { | ... | @@ -37,7 +38,7 @@ public final class NetTestTools { |
37 | // Crates a new device with the specified id | 38 | // Crates a new device with the specified id |
38 | public static Device device(String id) { | 39 | public static Device device(String id) { |
39 | return new DefaultDevice(PID, did(id), Device.Type.SWITCH, | 40 | return new DefaultDevice(PID, did(id), Device.Type.SWITCH, |
40 | - "mfg", "1.0", "1.1", "1234"); | 41 | + "mfg", "1.0", "1.1", "1234", new ChassisId()); |
41 | } | 42 | } |
42 | 43 | ||
43 | // Crates a new host with the specified id | 44 | // Crates a new host with the specified id |
... | @@ -47,10 +48,16 @@ public final class NetTestTools { | ... | @@ -47,10 +48,16 @@ public final class NetTestTools { |
47 | new HashSet<IpPrefix>()); | 48 | new HashSet<IpPrefix>()); |
48 | } | 49 | } |
49 | 50 | ||
51 | + // Short-hand for creating a connection point. | ||
52 | + public static ConnectPoint connectPoint(String id, int port) { | ||
53 | + return new ConnectPoint(did(id), portNumber(port)); | ||
54 | + } | ||
55 | + | ||
50 | // Short-hand for creating a link. | 56 | // Short-hand for creating a link. |
51 | public static Link link(String src, int sp, String dst, int dp) { | 57 | public static Link link(String src, int sp, String dst, int dp) { |
52 | - return new DefaultLink(PID, new ConnectPoint(did(src), portNumber(sp)), | 58 | + return new DefaultLink(PID, |
53 | - new ConnectPoint(did(dst), portNumber(dp)), | 59 | + connectPoint(src, sp), |
60 | + connectPoint(dst, dp), | ||
54 | Link.Type.DIRECT); | 61 | Link.Type.DIRECT); |
55 | } | 62 | } |
56 | 63 | ... | ... |
1 | package org.onlab.onos.net.device; | 1 | package org.onlab.onos.net.device; |
2 | 2 | ||
3 | import org.junit.Test; | 3 | import org.junit.Test; |
4 | +import org.onlab.packet.ChassisId; | ||
4 | 5 | ||
5 | import java.net.URI; | 6 | import java.net.URI; |
6 | 7 | ||
... | @@ -18,12 +19,13 @@ public class DefaultDeviceDescriptionTest { | ... | @@ -18,12 +19,13 @@ public class DefaultDeviceDescriptionTest { |
18 | private static final String HW = "1.1.x"; | 19 | private static final String HW = "1.1.x"; |
19 | private static final String SW = "3.9.1"; | 20 | private static final String SW = "3.9.1"; |
20 | private static final String SN = "43311-12345"; | 21 | private static final String SN = "43311-12345"; |
22 | + private static final ChassisId CID = new ChassisId(); | ||
21 | 23 | ||
22 | 24 | ||
23 | @Test | 25 | @Test |
24 | public void basics() { | 26 | public void basics() { |
25 | DeviceDescription device = | 27 | DeviceDescription device = |
26 | - new DefaultDeviceDescription(DURI, SWITCH, MFR, HW, SW, SN); | 28 | + new DefaultDeviceDescription(DURI, SWITCH, MFR, HW, SW, SN, CID); |
27 | assertEquals("incorrect uri", DURI, device.deviceURI()); | 29 | assertEquals("incorrect uri", DURI, device.deviceURI()); |
28 | assertEquals("incorrect type", SWITCH, device.type()); | 30 | assertEquals("incorrect type", SWITCH, device.type()); |
29 | assertEquals("incorrect manufacturer", MFR, device.manufacturer()); | 31 | assertEquals("incorrect manufacturer", MFR, device.manufacturer()); |
... | @@ -31,6 +33,7 @@ public class DefaultDeviceDescriptionTest { | ... | @@ -31,6 +33,7 @@ public class DefaultDeviceDescriptionTest { |
31 | assertEquals("incorrect sw", SW, device.swVersion()); | 33 | assertEquals("incorrect sw", SW, device.swVersion()); |
32 | assertEquals("incorrect serial", SN, device.serialNumber()); | 34 | assertEquals("incorrect serial", SN, device.serialNumber()); |
33 | assertTrue("incorrect toString", device.toString().contains("uri=of:foo")); | 35 | assertTrue("incorrect toString", device.toString().contains("uri=of:foo")); |
36 | + assertTrue("Incorrect chassis", device.chassisId().value() == 0); | ||
34 | } | 37 | } |
35 | 38 | ||
36 | } | 39 | } | ... | ... |
... | @@ -11,6 +11,7 @@ import org.onlab.onos.net.Device; | ... | @@ -11,6 +11,7 @@ import org.onlab.onos.net.Device; |
11 | import org.onlab.onos.net.Port; | 11 | import org.onlab.onos.net.Port; |
12 | import org.onlab.onos.net.PortNumber; | 12 | import org.onlab.onos.net.PortNumber; |
13 | import org.onlab.onos.net.provider.ProviderId; | 13 | import org.onlab.onos.net.provider.ProviderId; |
14 | +import org.onlab.packet.ChassisId; | ||
14 | 15 | ||
15 | /** | 16 | /** |
16 | * Tests of the device event. | 17 | * Tests of the device event. |
... | @@ -19,7 +20,7 @@ public class DeviceEventTest extends AbstractEventTest { | ... | @@ -19,7 +20,7 @@ public class DeviceEventTest extends AbstractEventTest { |
19 | 20 | ||
20 | private Device createDevice() { | 21 | private Device createDevice() { |
21 | return new DefaultDevice(new ProviderId("of", "foo"), deviceId("of:foo"), | 22 | return new DefaultDevice(new ProviderId("of", "foo"), deviceId("of:foo"), |
22 | - Device.Type.SWITCH, "box", "hw", "sw", "sn"); | 23 | + Device.Type.SWITCH, "box", "hw", "sw", "sn", new ChassisId()); |
23 | } | 24 | } |
24 | 25 | ||
25 | @Override | 26 | @Override | ... | ... |
... | @@ -8,6 +8,8 @@ import org.onlab.packet.IpPrefix; | ... | @@ -8,6 +8,8 @@ import org.onlab.packet.IpPrefix; |
8 | import org.onlab.packet.MacAddress; | 8 | import org.onlab.packet.MacAddress; |
9 | import org.onlab.packet.VlanId; | 9 | import org.onlab.packet.VlanId; |
10 | 10 | ||
11 | +import com.google.common.collect.ImmutableSet; | ||
12 | + | ||
11 | import static org.junit.Assert.assertEquals; | 13 | import static org.junit.Assert.assertEquals; |
12 | import static org.junit.Assert.assertTrue; | 14 | import static org.junit.Assert.assertTrue; |
13 | 15 | ||
... | @@ -33,7 +35,7 @@ public class DefualtHostDecriptionTest { | ... | @@ -33,7 +35,7 @@ public class DefualtHostDecriptionTest { |
33 | assertEquals("incorrect mac", MAC, host.hwAddress()); | 35 | assertEquals("incorrect mac", MAC, host.hwAddress()); |
34 | assertEquals("incorrect vlan", VLAN, host.vlan()); | 36 | assertEquals("incorrect vlan", VLAN, host.vlan()); |
35 | assertEquals("incorrect location", LOC, host.location()); | 37 | assertEquals("incorrect location", LOC, host.location()); |
36 | - assertEquals("incorrect ip's", IP, host.ipAddress()); | 38 | + assertEquals("incorrect ip's", ImmutableSet.of(IP), host.ipAddress()); |
37 | assertTrue("incorrect toString", host.toString().contains("vlan=10")); | 39 | assertTrue("incorrect toString", host.toString().contains("vlan=10")); |
38 | } | 40 | } |
39 | 41 | ... | ... |
... | @@ -18,9 +18,9 @@ public class DefaultGraphDescriptionTest { | ... | @@ -18,9 +18,9 @@ public class DefaultGraphDescriptionTest { |
18 | 18 | ||
19 | private static final DeviceId D3 = deviceId("3"); | 19 | private static final DeviceId D3 = deviceId("3"); |
20 | 20 | ||
21 | - static final Device DEV1 = new DefaultDevice(PID, D1, SWITCH, "", "", "", ""); | 21 | + static final Device DEV1 = new DefaultDevice(PID, D1, SWITCH, "", "", "", "", null); |
22 | - static final Device DEV2 = new DefaultDevice(PID, D2, SWITCH, "", "", "", ""); | 22 | + static final Device DEV2 = new DefaultDevice(PID, D2, SWITCH, "", "", "", "", null); |
23 | - static final Device DEV3 = new DefaultDevice(PID, D3, SWITCH, "", "", "", ""); | 23 | + static final Device DEV3 = new DefaultDevice(PID, D3, SWITCH, "", "", "", "", null); |
24 | 24 | ||
25 | @Test | 25 | @Test |
26 | public void basics() { | 26 | public void basics() { | ... | ... |
... | @@ -6,15 +6,15 @@ | ... | @@ -6,15 +6,15 @@ |
6 | 6 | ||
7 | <parent> | 7 | <parent> |
8 | <groupId>org.onlab.onos</groupId> | 8 | <groupId>org.onlab.onos</groupId> |
9 | - <artifactId>onos-core-hz</artifactId> | 9 | + <artifactId>onos-core</artifactId> |
10 | <version>1.0.0-SNAPSHOT</version> | 10 | <version>1.0.0-SNAPSHOT</version> |
11 | <relativePath>../pom.xml</relativePath> | 11 | <relativePath>../pom.xml</relativePath> |
12 | </parent> | 12 | </parent> |
13 | 13 | ||
14 | - <artifactId>onos-core-hz-net</artifactId> | 14 | + <artifactId>onos-json</artifactId> |
15 | <packaging>bundle</packaging> | 15 | <packaging>bundle</packaging> |
16 | 16 | ||
17 | - <description>ONOS Hazelcast based distributed store subsystems</description> | 17 | + <description>ONOS JSON encode/decode facilities</description> |
18 | 18 | ||
19 | <dependencies> | 19 | <dependencies> |
20 | <dependency> | 20 | <dependency> |
... | @@ -23,24 +23,22 @@ | ... | @@ -23,24 +23,22 @@ |
23 | </dependency> | 23 | </dependency> |
24 | <dependency> | 24 | <dependency> |
25 | <groupId>org.onlab.onos</groupId> | 25 | <groupId>org.onlab.onos</groupId> |
26 | - <artifactId>onos-core-hz-common</artifactId> | 26 | + <artifactId>onos-api</artifactId> |
27 | - <version>${project.version}</version> | 27 | + <classifier>tests</classifier> |
28 | + <scope>test</scope> | ||
28 | </dependency> | 29 | </dependency> |
30 | + | ||
29 | <dependency> | 31 | <dependency> |
30 | <groupId>org.onlab.onos</groupId> | 32 | <groupId>org.onlab.onos</groupId> |
31 | - <artifactId>onos-core-hz-common</artifactId> | 33 | + <artifactId>onos-core-trivial</artifactId> |
32 | - <classifier>tests</classifier> | ||
33 | - <scope>test</scope> | ||
34 | <version>${project.version}</version> | 34 | <version>${project.version}</version> |
35 | + <scope>test</scope> | ||
35 | </dependency> | 36 | </dependency> |
37 | + | ||
36 | <dependency> | 38 | <dependency> |
37 | <groupId>org.apache.felix</groupId> | 39 | <groupId>org.apache.felix</groupId> |
38 | <artifactId>org.apache.felix.scr.annotations</artifactId> | 40 | <artifactId>org.apache.felix.scr.annotations</artifactId> |
39 | </dependency> | 41 | </dependency> |
40 | - <dependency> | ||
41 | - <groupId>com.hazelcast</groupId> | ||
42 | - <artifactId>hazelcast</artifactId> | ||
43 | - </dependency> | ||
44 | </dependencies> | 42 | </dependencies> |
45 | 43 | ||
46 | <build> | 44 | <build> | ... | ... |
... | @@ -36,26 +36,9 @@ | ... | @@ -36,26 +36,9 @@ |
36 | <scope>test</scope> | 36 | <scope>test</scope> |
37 | </dependency> | 37 | </dependency> |
38 | 38 | ||
39 | - <dependency> | ||
40 | - <groupId>org.easymock</groupId> | ||
41 | - <artifactId>easymock</artifactId> | ||
42 | - <scope>test</scope> | ||
43 | - </dependency> | ||
44 | - | ||
45 | - <!-- TODO Consider removing store dependency. | ||
46 | - Currently required for DistributedDeviceManagerTest. --> | ||
47 | <dependency> | 39 | <dependency> |
48 | - <groupId>org.onlab.onos</groupId> | 40 | + <groupId>org.easymock</groupId> |
49 | - <artifactId>onos-core-hz-net</artifactId> | 41 | + <artifactId>easymock</artifactId> |
50 | - <version>${project.version}</version> | ||
51 | - <scope>test</scope> | ||
52 | - </dependency> | ||
53 | - <dependency> | ||
54 | - <groupId>org.onlab.onos</groupId> | ||
55 | - <!-- FIXME: should be somewhere else --> | ||
56 | - <artifactId>onos-core-hz-common</artifactId> | ||
57 | - <version>${project.version}</version> | ||
58 | - <classifier>tests</classifier> | ||
59 | <scope>test</scope> | 42 | <scope>test</scope> |
60 | </dependency> | 43 | </dependency> |
61 | 44 | ... | ... |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/net/src/test/java/org/onlab/onos/net/intent/LinksHaveEntryWithSourceDestinationPairMatcher.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/net/src/test/java/org/onlab/onos/net/intent/impl/TestMultiPointToSinglePointIntentCompiler.java
0 → 100644
This diff is collapsed. Click to expand it.
core/net/src/test/java/org/onlab/onos/net/intent/impl/TestPointToPointIntentCompiler.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/dist/src/main/java/org/onlab/onos/store/device/impl/InitDeviceDescs.java
deleted
100644 → 0
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/FlowStoreMessageSubjects.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/dist/src/main/java/org/onlab/onos/store/host/impl/HostAntiEntropyAdvertisement.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/RoleValueSerializer.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/hz/cluster/src/test/java/org/onlab/onos/store/mastership/impl/RoleValueTest.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/hz/net/src/main/java/org/onlab/onos/store/device/impl/DistributedDeviceStore.java
deleted
100644 → 0
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
deleted
100644 → 0
This diff is collapsed. Click to expand it.
core/store/hz/net/src/main/java/org/onlab/onos/store/host/impl/DistributedHostStore.java
deleted
100644 → 0
This diff is collapsed. Click to expand it.
core/store/hz/net/src/main/java/org/onlab/onos/store/link/impl/DistributedLinkStore.java
deleted
100644 → 0
This diff is collapsed. Click to expand it.
core/store/hz/net/src/main/java/org/onlab/onos/store/topology/impl/DefaultTopology.java
deleted
100644 → 0
This diff is collapsed. Click to expand it.
core/store/hz/net/src/main/java/org/onlab/onos/store/topology/impl/DefaultTopologyGraph.java
deleted
100644 → 0
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/hz/net/src/test/java/org/onlab/onos/store/link/impl/DistributedLinkStoreTest.java
deleted
100644 → 0
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/serializers/src/main/java/org/onlab/onos/store/serializers/HostLocationSerializer.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
providers/host/bin/pom.xml
0 → 100644
This diff is collapsed. Click to expand it.
providers/host/pom.xml
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
providers/host/src/test/java/org/onlab/onos/provider/host/impl/HostLocationProviderTest.java
0 → 100644
This diff is collapsed. Click to expand it.
providers/lldp/pom.xml
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
This diff is collapsed. Click to expand it.
providers/openflow/host/src/main/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProvider.java
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
providers/openflow/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
tools/dev/onos.cshrc
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
tools/test/cells/single_optical
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
utils/thirdparty/pom.xml
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment