Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
Showing
162 changed files
with
3762 additions
and
180 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 |
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> | ... | ... |
... | @@ -42,6 +42,30 @@ | ... | @@ -42,6 +42,30 @@ |
42 | <artifactId>onlab-thirdparty</artifactId> | 42 | <artifactId>onlab-thirdparty</artifactId> |
43 | </dependency> | 43 | </dependency> |
44 | 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> | ||
45 | </dependencies> | 69 | </dependencies> |
46 | 70 | ||
47 | </project> | 71 | </project> | ... | ... |
... | @@ -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; | ... | ... |
... | @@ -62,10 +62,8 @@ public class Router implements RouteListener { | ... | @@ -62,10 +62,8 @@ public class Router implements RouteListener { |
62 | 62 | ||
63 | private static final Logger log = LoggerFactory.getLogger(Router.class); | 63 | private static final Logger log = LoggerFactory.getLogger(Router.class); |
64 | 64 | ||
65 | - // Store all route updates in a InvertedRadixTree. | 65 | + // Store all route updates in a radix tree. |
66 | - // The key in this Tree is the binary sting of prefix of route. | 66 | + // The key in this tree is the binary string of prefix of the route. |
67 | - // The Ip4Address is the next hop address of route, and is also the value | ||
68 | - // of each entry. | ||
69 | private InvertedRadixTree<RouteEntry> bgpRoutes; | 67 | private InvertedRadixTree<RouteEntry> bgpRoutes; |
70 | 68 | ||
71 | // Stores all incoming route updates in a queue. | 69 | // Stores all incoming route updates in a queue. |
... | @@ -102,7 +100,7 @@ public class Router implements RouteListener { | ... | @@ -102,7 +100,7 @@ public class Router implements RouteListener { |
102 | * Class constructor. | 100 | * Class constructor. |
103 | * | 101 | * |
104 | * @param intentService the intent service | 102 | * @param intentService the intent service |
105 | - * @param proxyArp the proxy ARP service | 103 | + * @param hostService the host service |
106 | * @param configInfoService the configuration service | 104 | * @param configInfoService the configuration service |
107 | * @param interfaceService the interface service | 105 | * @param interfaceService the interface service |
108 | */ | 106 | */ |
... | @@ -135,6 +133,10 @@ public class Router implements RouteListener { | ... | @@ -135,6 +133,10 @@ public class Router implements RouteListener { |
135 | */ | 133 | */ |
136 | public void start() { | 134 | public void start() { |
137 | 135 | ||
136 | + // TODO hack to enable SDN-IP now for testing | ||
137 | + isElectedLeader = true; | ||
138 | + isActivatedLeader = true; | ||
139 | + | ||
138 | bgpUpdatesExecutor.execute(new Runnable() { | 140 | bgpUpdatesExecutor.execute(new Runnable() { |
139 | @Override | 141 | @Override |
140 | public void run() { | 142 | public void run() { |
... | @@ -441,8 +443,8 @@ public class Router implements RouteListener { | ... | @@ -441,8 +443,8 @@ public class Router implements RouteListener { |
441 | /** | 443 | /** |
442 | * Processes adding a route entry. | 444 | * Processes adding a route entry. |
443 | * <p/> | 445 | * <p/> |
444 | - * Put new route entry into InvertedRadixTree. If there was an existing | 446 | + * Put new route entry into the radix tree. If there was an existing |
445 | - * nexthop for this prefix, but the next hop was different, then execute | 447 | + * next hop for this prefix, but the next hop was different, then execute |
446 | * deleting old route entry. If the next hop is the SDN domain, we do not | 448 | * deleting old route entry. If the next hop is the SDN domain, we do not |
447 | * handle it at the moment. Otherwise, execute adding a route. | 449 | * handle it at the moment. Otherwise, execute adding a route. |
448 | * | 450 | * |
... | @@ -623,8 +625,8 @@ public class Router implements RouteListener { | ... | @@ -623,8 +625,8 @@ public class Router implements RouteListener { |
623 | /** | 625 | /** |
624 | * Executes deleting a route entry. | 626 | * Executes deleting a route entry. |
625 | * <p/> | 627 | * <p/> |
626 | - * Removes prefix from InvertedRadixTree, if success, then try to delete | 628 | + * Removes prefix from radix tree, and if successful, then try to delete |
627 | - * the relative intent. | 629 | + * the related intent. |
628 | * | 630 | * |
629 | * @param routeEntry the route entry to delete | 631 | * @param routeEntry the route entry to delete |
630 | */ | 632 | */ |
... | @@ -690,9 +692,9 @@ public class Router implements RouteListener { | ... | @@ -690,9 +692,9 @@ public class Router implements RouteListener { |
690 | public void arpResponse(IpAddress ipAddress, MacAddress macAddress) { | 692 | public void arpResponse(IpAddress ipAddress, MacAddress macAddress) { |
691 | log.debug("Received ARP response: {} => {}", ipAddress, macAddress); | 693 | log.debug("Received ARP response: {} => {}", ipAddress, macAddress); |
692 | 694 | ||
693 | - // We synchronize on this to prevent changes to the InvertedRadixTree | 695 | + // We synchronize on this to prevent changes to the radix tree |
694 | - // while we're pushing intent. If the InvertedRadixTree changes, the | 696 | + // while we're pushing intents. If the tree changes, the |
695 | - // InvertedRadixTree and intent could get out of sync. | 697 | + // tree and intents could get out of sync. |
696 | synchronized (this) { | 698 | synchronized (this) { |
697 | 699 | ||
698 | Set<RouteEntry> routesToPush = | 700 | Set<RouteEntry> routesToPush = |
... | @@ -709,14 +711,14 @@ public class Router implements RouteListener { | ... | @@ -709,14 +711,14 @@ public class Router implements RouteListener { |
709 | log.debug("Pushing prefix {} next hop {}", | 711 | log.debug("Pushing prefix {} next hop {}", |
710 | routeEntry.prefix(), routeEntry.nextHop()); | 712 | routeEntry.prefix(), routeEntry.nextHop()); |
711 | // We only push prefix flows if the prefix is still in the | 713 | // We only push prefix flows if the prefix is still in the |
712 | - // InvertedRadixTree and the next hop is the same as our | 714 | + // radix tree and the next hop is the same as our |
713 | // update. | 715 | // update. |
714 | // The prefix could have been removed while we were waiting | 716 | // The prefix could have been removed while we were waiting |
715 | // for the ARP, or the next hop could have changed. | 717 | // for the ARP, or the next hop could have changed. |
716 | addRouteIntentToNextHop(prefix, ipAddress, macAddress); | 718 | addRouteIntentToNextHop(prefix, ipAddress, macAddress); |
717 | } else { | 719 | } else { |
718 | log.debug("Received ARP response, but {}/{} is no longer in" | 720 | log.debug("Received ARP response, but {}/{} is no longer in" |
719 | - + " InvertedRadixTree", routeEntry.prefix(), | 721 | + + " the radix tree", routeEntry.prefix(), |
720 | routeEntry.nextHop()); | 722 | routeEntry.nextHop()); |
721 | } | 723 | } |
722 | } | 724 | } | ... | ... |
... | @@ -2,14 +2,18 @@ package org.onlab.onos.sdnip; | ... | @@ -2,14 +2,18 @@ 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; |
12 | import org.onlab.onos.sdnip.RouteUpdate.Type; | 15 | import org.onlab.onos.sdnip.RouteUpdate.Type; |
16 | +import org.onlab.onos.sdnip.bgp.BgpRouteEntry; | ||
13 | import org.onlab.onos.sdnip.bgp.BgpSessionManager; | 17 | import org.onlab.onos.sdnip.bgp.BgpSessionManager; |
14 | import org.onlab.onos.sdnip.config.SdnIpConfigReader; | 18 | import org.onlab.onos.sdnip.config.SdnIpConfigReader; |
15 | import org.onlab.packet.IpAddress; | 19 | import org.onlab.packet.IpAddress; |
... | @@ -17,10 +21,11 @@ import org.onlab.packet.IpPrefix; | ... | @@ -17,10 +21,11 @@ import org.onlab.packet.IpPrefix; |
17 | import org.slf4j.Logger; | 21 | import org.slf4j.Logger; |
18 | 22 | ||
19 | /** | 23 | /** |
20 | - * Placeholder SDN-IP component. | 24 | + * Component for the SDN-IP peering application. |
21 | */ | 25 | */ |
22 | @Component(immediate = true) | 26 | @Component(immediate = true) |
23 | -public class SdnIp { | 27 | +@Service |
28 | +public class SdnIp implements SdnIpService { | ||
24 | 29 | ||
25 | private final Logger log = getLogger(getClass()); | 30 | private final Logger log = getLogger(getClass()); |
26 | 31 | ||
... | @@ -31,7 +36,7 @@ public class SdnIp { | ... | @@ -31,7 +36,7 @@ public class SdnIp { |
31 | protected HostService hostService; | 36 | protected HostService hostService; |
32 | 37 | ||
33 | private SdnIpConfigReader config; | 38 | private SdnIpConfigReader config; |
34 | - private PeerConnectivity peerConnectivity; | 39 | + private PeerConnectivityManager peerConnectivity; |
35 | private Router router; | 40 | private Router router; |
36 | private BgpSessionManager bgpSessionManager; | 41 | private BgpSessionManager bgpSessionManager; |
37 | 42 | ||
... | @@ -44,7 +49,7 @@ public class SdnIp { | ... | @@ -44,7 +49,7 @@ public class SdnIp { |
44 | 49 | ||
45 | InterfaceService interfaceService = new HostServiceBasedInterfaceService(hostService); | 50 | InterfaceService interfaceService = new HostServiceBasedInterfaceService(hostService); |
46 | 51 | ||
47 | - peerConnectivity = new PeerConnectivity(config, interfaceService, intentService); | 52 | + peerConnectivity = new PeerConnectivityManager(config, interfaceService, intentService); |
48 | peerConnectivity.start(); | 53 | peerConnectivity.start(); |
49 | 54 | ||
50 | router = new Router(intentService, hostService, config, interfaceService); | 55 | router = new Router(intentService, hostService, config, interfaceService); |
... | @@ -64,4 +69,18 @@ public class SdnIp { | ... | @@ -64,4 +69,18 @@ public class SdnIp { |
64 | protected void deactivate() { | 69 | protected void deactivate() { |
65 | log.info("Stopped"); | 70 | log.info("Stopped"); |
66 | } | 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 | + } | ||
67 | } | 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 | +} |
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.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 | +} |
... | @@ -94,7 +94,7 @@ public class FlowsListCommand extends AbstractShellCommand { | ... | @@ -94,7 +94,7 @@ public class FlowsListCommand extends AbstractShellCommand { |
94 | 94 | ||
95 | result.put("device", device.id().toString()) | 95 | result.put("device", device.id().toString()) |
96 | .put("flowCount", flows.size()) | 96 | .put("flowCount", flows.size()) |
97 | - .put("flows", array); | 97 | + .set("flows", array); |
98 | return result; | 98 | return result; |
99 | } | 99 | } |
100 | 100 | ... | ... |
... | @@ -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.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 | } | ... | ... |
... | @@ -8,7 +8,7 @@ import org.slf4j.Logger; | ... | @@ -8,7 +8,7 @@ import org.slf4j.Logger; |
8 | 8 | ||
9 | public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { | 9 | public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { |
10 | 10 | ||
11 | - private final Logger log = getLogger(getClass()); | 11 | + private static final Logger log = getLogger(DefaultFlowEntry.class); |
12 | 12 | ||
13 | private long life; | 13 | private long life; |
14 | private long packets; | 14 | 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; | ... | ... |
... | @@ -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; | ... | ... |
... | @@ -14,7 +14,7 @@ import com.google.common.base.MoreObjects; | ... | @@ -14,7 +14,7 @@ import com.google.common.base.MoreObjects; |
14 | * Abstraction of a connectivity intent that is implemented by a set of path | 14 | * Abstraction of a connectivity intent that is implemented by a set of path |
15 | * segments. | 15 | * segments. |
16 | */ | 16 | */ |
17 | -public class LinkCollectionIntent extends ConnectivityIntent implements InstallableIntent { | 17 | +public final class LinkCollectionIntent extends ConnectivityIntent implements InstallableIntent { |
18 | 18 | ||
19 | private final Set<Link> links; | 19 | private final Set<Link> links; |
20 | 20 | ||
... | @@ -46,6 +46,12 @@ public class LinkCollectionIntent extends ConnectivityIntent implements Installa | ... | @@ -46,6 +46,12 @@ public class LinkCollectionIntent extends ConnectivityIntent implements Installa |
46 | return links; | 46 | return links; |
47 | } | 47 | } |
48 | 48 | ||
49 | + /** | ||
50 | + * Returns the set of links that represent the network connections needed | ||
51 | + * by this intent. | ||
52 | + * | ||
53 | + * @return Set of links for the network hops needed by this intent | ||
54 | + */ | ||
49 | public Set<Link> links() { | 55 | public Set<Link> links() { |
50 | return links; | 56 | return links; |
51 | } | 57 | } | ... | ... |
... | @@ -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; | ... | ... |
... | @@ -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 | +} |
... | @@ -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 | ... | ... |
... | @@ -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() { | ... | ... |
core/json/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-core</artifactId> | ||
10 | + <version>1.0.0-SNAPSHOT</version> | ||
11 | + <relativePath>../pom.xml</relativePath> | ||
12 | + </parent> | ||
13 | + | ||
14 | + <artifactId>onos-json</artifactId> | ||
15 | + <packaging>bundle</packaging> | ||
16 | + | ||
17 | + <description>ONOS JSON encode/decode facilities</description> | ||
18 | + | ||
19 | + <dependencies> | ||
20 | + <dependency> | ||
21 | + <groupId>org.onlab.onos</groupId> | ||
22 | + <artifactId>onos-api</artifactId> | ||
23 | + </dependency> | ||
24 | + <dependency> | ||
25 | + <groupId>org.onlab.onos</groupId> | ||
26 | + <artifactId>onos-api</artifactId> | ||
27 | + <classifier>tests</classifier> | ||
28 | + <scope>test</scope> | ||
29 | + </dependency> | ||
30 | + | ||
31 | + <dependency> | ||
32 | + <groupId>org.onlab.onos</groupId> | ||
33 | + <artifactId>onos-core-trivial</artifactId> | ||
34 | + <version>${project.version}</version> | ||
35 | + <scope>test</scope> | ||
36 | + </dependency> | ||
37 | + | ||
38 | + <dependency> | ||
39 | + <groupId>org.apache.felix</groupId> | ||
40 | + <artifactId>org.apache.felix.scr.annotations</artifactId> | ||
41 | + </dependency> | ||
42 | + </dependencies> | ||
43 | + | ||
44 | + <build> | ||
45 | + <plugins> | ||
46 | + <plugin> | ||
47 | + <groupId>org.apache.felix</groupId> | ||
48 | + <artifactId>maven-scr-plugin</artifactId> | ||
49 | + </plugin> | ||
50 | + </plugins> | ||
51 | + </build> | ||
52 | + | ||
53 | +</project> |
... | @@ -42,23 +42,6 @@ | ... | @@ -42,23 +42,6 @@ |
42 | <scope>test</scope> | 42 | <scope>test</scope> |
43 | </dependency> | 43 | </dependency> |
44 | 44 | ||
45 | - <!-- TODO Consider removing store dependency. | ||
46 | - Currently required for DistributedDeviceManagerTest. --> | ||
47 | - <dependency> | ||
48 | - <groupId>org.onlab.onos</groupId> | ||
49 | - <artifactId>onos-core-hz-net</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> | ||
60 | - </dependency> | ||
61 | - | ||
62 | <dependency> | 45 | <dependency> |
63 | <groupId>org.apache.felix</groupId> | 46 | <groupId>org.apache.felix</groupId> |
64 | <artifactId>org.apache.felix.scr.annotations</artifactId> | 47 | <artifactId>org.apache.felix.scr.annotations</artifactId> | ... | ... |
... | @@ -388,7 +388,7 @@ public class DeviceManager | ... | @@ -388,7 +388,7 @@ public class DeviceManager |
388 | new DefaultDeviceDescription( | 388 | new DefaultDeviceDescription( |
389 | did.uri(), device.type(), device.manufacturer(), | 389 | did.uri(), device.type(), device.manufacturer(), |
390 | device.hwVersion(), device.swVersion(), | 390 | device.hwVersion(), device.swVersion(), |
391 | - device.serialNumber())); | 391 | + device.serialNumber(), device.chassisId())); |
392 | } | 392 | } |
393 | //TODO re-collect device information to fix potential staleness | 393 | //TODO re-collect device information to fix potential staleness |
394 | applyRole(did, MastershipRole.MASTER); | 394 | applyRole(did, MastershipRole.MASTER); | ... | ... |
... | @@ -401,7 +401,7 @@ public class FlowRuleManager | ... | @@ -401,7 +401,7 @@ public class FlowRuleManager |
401 | CompletedBatchOperation completed; | 401 | CompletedBatchOperation completed; |
402 | for (Future<CompletedBatchOperation> future : futures) { | 402 | for (Future<CompletedBatchOperation> future : futures) { |
403 | completed = future.get(); | 403 | completed = future.get(); |
404 | - success = validateBatchOperation(failed, completed, future); | 404 | + success = validateBatchOperation(failed, completed); |
405 | } | 405 | } |
406 | 406 | ||
407 | return finalizeBatchOperation(success, failed); | 407 | return finalizeBatchOperation(success, failed); |
... | @@ -426,14 +426,13 @@ public class FlowRuleManager | ... | @@ -426,14 +426,13 @@ public class FlowRuleManager |
426 | long now = System.nanoTime(); | 426 | long now = System.nanoTime(); |
427 | long thisTimeout = end - now; | 427 | long thisTimeout = end - now; |
428 | completed = future.get(thisTimeout, TimeUnit.NANOSECONDS); | 428 | completed = future.get(thisTimeout, TimeUnit.NANOSECONDS); |
429 | - success = validateBatchOperation(failed, completed, future); | 429 | + success = validateBatchOperation(failed, completed); |
430 | } | 430 | } |
431 | return finalizeBatchOperation(success, failed); | 431 | return finalizeBatchOperation(success, failed); |
432 | } | 432 | } |
433 | 433 | ||
434 | private boolean validateBatchOperation(List<FlowEntry> failed, | 434 | private boolean validateBatchOperation(List<FlowEntry> failed, |
435 | - CompletedBatchOperation completed, | 435 | + CompletedBatchOperation completed) { |
436 | - Future<CompletedBatchOperation> future) { | ||
437 | 436 | ||
438 | if (isCancelled()) { | 437 | if (isCancelled()) { |
439 | throw new CancellationException(); | 438 | throw new CancellationException(); | ... | ... |
... | @@ -41,7 +41,7 @@ public class HostToHostIntentCompiler | ... | @@ -41,7 +41,7 @@ public class HostToHostIntentCompiler |
41 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 41 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
42 | protected HostService hostService; | 42 | protected HostService hostService; |
43 | 43 | ||
44 | - private IdGenerator<IntentId> intentIdGenerator; | 44 | + protected IdGenerator<IntentId> intentIdGenerator; |
45 | 45 | ||
46 | @Activate | 46 | @Activate |
47 | public void activate() { | 47 | public void activate() { | ... | ... |
... | @@ -37,7 +37,7 @@ public class MultiPointToSinglePointIntentCompiler | ... | @@ -37,7 +37,7 @@ public class MultiPointToSinglePointIntentCompiler |
37 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 37 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
38 | protected PathService pathService; | 38 | protected PathService pathService; |
39 | 39 | ||
40 | - private IdGenerator<IntentId> intentIdGenerator; | 40 | + protected IdGenerator<IntentId> intentIdGenerator; |
41 | 41 | ||
42 | @Activate | 42 | @Activate |
43 | public void activate() { | 43 | public void activate() { | ... | ... |
... | @@ -96,7 +96,7 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -96,7 +96,7 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
96 | 96 | ||
97 | FlowRule rule = new DefaultFlowRule(link.src().deviceId(), | 97 | FlowRule rule = new DefaultFlowRule(link.src().deviceId(), |
98 | builder.build(), treatment, | 98 | builder.build(), treatment, |
99 | - 123, appId, 600); | 99 | + 123, appId, 15); |
100 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)); | 100 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)); |
101 | prev = link.dst(); | 101 | prev = link.dst(); |
102 | } | 102 | } | ... | ... |
... | @@ -43,7 +43,7 @@ public class PointToPointIntentCompiler | ... | @@ -43,7 +43,7 @@ public class PointToPointIntentCompiler |
43 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 43 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
44 | protected HostService hostService; | 44 | protected HostService hostService; |
45 | 45 | ||
46 | - private IdGenerator<IntentId> intentIdGenerator; | 46 | + protected IdGenerator<IntentId> intentIdGenerator; |
47 | 47 | ||
48 | @Activate | 48 | @Activate |
49 | public void activate() { | 49 | public void activate() { | ... | ... |
... | @@ -244,6 +244,7 @@ public class LinkManager | ... | @@ -244,6 +244,7 @@ public class LinkManager |
244 | return; | 244 | return; |
245 | } | 245 | } |
246 | log.info("Links for connection point {} vanished", connectPoint); | 246 | log.info("Links for connection point {} vanished", connectPoint); |
247 | + // FIXME: This will remove links registered by other providers | ||
247 | removeLinks(getLinks(connectPoint)); | 248 | removeLinks(getLinks(connectPoint)); |
248 | } | 249 | } |
249 | 250 | ... | ... |
... | @@ -167,6 +167,7 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -167,6 +167,7 @@ public class ProxyArpManager implements ProxyArpService { |
167 | return; | 167 | return; |
168 | } | 168 | } |
169 | 169 | ||
170 | + // TODO find the correct IP address | ||
170 | Ethernet arpReply = buildArpReply(dst.ipAddresses().iterator().next(), | 171 | Ethernet arpReply = buildArpReply(dst.ipAddresses().iterator().next(), |
171 | dst.mac(), eth); | 172 | dst.mac(), eth); |
172 | // TODO: check send status with host service. | 173 | // TODO: check send status with host service. | ... | ... |
... | @@ -23,6 +23,7 @@ import org.onlab.onos.net.topology.TopologyProviderRegistry; | ... | @@ -23,6 +23,7 @@ import org.onlab.onos.net.topology.TopologyProviderRegistry; |
23 | import org.onlab.onos.net.topology.TopologyProviderService; | 23 | import org.onlab.onos.net.topology.TopologyProviderService; |
24 | import org.slf4j.Logger; | 24 | import org.slf4j.Logger; |
25 | 25 | ||
26 | +import java.util.Collections; | ||
26 | import java.util.List; | 27 | import java.util.List; |
27 | import java.util.Timer; | 28 | import java.util.Timer; |
28 | import java.util.concurrent.ExecutorService; | 29 | import java.util.concurrent.ExecutorService; |
... | @@ -88,7 +89,7 @@ public class DefaultTopologyProvider extends AbstractProvider | ... | @@ -88,7 +89,7 @@ public class DefaultTopologyProvider extends AbstractProvider |
88 | linkService.addListener(linkListener); | 89 | linkService.addListener(linkListener); |
89 | 90 | ||
90 | isStarted = true; | 91 | isStarted = true; |
91 | - triggerTopologyBuild(null); | 92 | + triggerTopologyBuild(Collections.<Event>emptyList()); |
92 | log.info("Started"); | 93 | log.info("Started"); |
93 | } | 94 | } |
94 | 95 | ... | ... |
... | @@ -37,6 +37,7 @@ import org.onlab.onos.net.device.PortDescription; | ... | @@ -37,6 +37,7 @@ import org.onlab.onos.net.device.PortDescription; |
37 | import org.onlab.onos.net.provider.AbstractProvider; | 37 | import org.onlab.onos.net.provider.AbstractProvider; |
38 | import org.onlab.onos.net.provider.ProviderId; | 38 | import org.onlab.onos.net.provider.ProviderId; |
39 | import org.onlab.onos.store.trivial.impl.SimpleDeviceStore; | 39 | import org.onlab.onos.store.trivial.impl.SimpleDeviceStore; |
40 | +import org.onlab.packet.ChassisId; | ||
40 | import org.onlab.packet.IpPrefix; | 41 | import org.onlab.packet.IpPrefix; |
41 | 42 | ||
42 | import java.util.ArrayList; | 43 | import java.util.ArrayList; |
... | @@ -62,6 +63,7 @@ public class DeviceManagerTest { | ... | @@ -62,6 +63,7 @@ public class DeviceManagerTest { |
62 | private static final String SW1 = "3.8.1"; | 63 | private static final String SW1 = "3.8.1"; |
63 | private static final String SW2 = "3.9.5"; | 64 | private static final String SW2 = "3.9.5"; |
64 | private static final String SN = "43311-12345"; | 65 | private static final String SN = "43311-12345"; |
66 | + private static final ChassisId CID = new ChassisId(); | ||
65 | 67 | ||
66 | private static final PortNumber P1 = PortNumber.portNumber(1); | 68 | private static final PortNumber P1 = PortNumber.portNumber(1); |
67 | private static final PortNumber P2 = PortNumber.portNumber(2); | 69 | private static final PortNumber P2 = PortNumber.portNumber(2); |
... | @@ -111,7 +113,7 @@ public class DeviceManagerTest { | ... | @@ -111,7 +113,7 @@ public class DeviceManagerTest { |
111 | private void connectDevice(DeviceId deviceId, String swVersion) { | 113 | private void connectDevice(DeviceId deviceId, String swVersion) { |
112 | DeviceDescription description = | 114 | DeviceDescription description = |
113 | new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR, | 115 | new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR, |
114 | - HW, swVersion, SN); | 116 | + HW, swVersion, SN, CID); |
115 | providerService.deviceConnected(deviceId, description); | 117 | providerService.deviceConnected(deviceId, description); |
116 | assertNotNull("device should be found", service.getDevice(DID1)); | 118 | assertNotNull("device should be found", service.getDevice(DID1)); |
117 | } | 119 | } | ... | ... |
... | @@ -8,7 +8,9 @@ import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED; | ... | @@ -8,7 +8,9 @@ import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED; |
8 | 8 | ||
9 | import java.util.ArrayList; | 9 | import java.util.ArrayList; |
10 | import java.util.Collections; | 10 | import java.util.Collections; |
11 | +import java.util.HashMap; | ||
11 | import java.util.List; | 12 | import java.util.List; |
13 | +import java.util.Map; | ||
12 | import java.util.Set; | 14 | import java.util.Set; |
13 | import java.util.concurrent.ExecutionException; | 15 | import java.util.concurrent.ExecutionException; |
14 | import java.util.concurrent.Future; | 16 | import java.util.concurrent.Future; |
... | @@ -54,6 +56,7 @@ import org.onlab.onos.net.provider.ProviderId; | ... | @@ -54,6 +56,7 @@ import org.onlab.onos.net.provider.ProviderId; |
54 | import org.onlab.onos.store.trivial.impl.SimpleFlowRuleStore; | 56 | import org.onlab.onos.store.trivial.impl.SimpleFlowRuleStore; |
55 | 57 | ||
56 | import com.google.common.collect.ImmutableList; | 58 | import com.google.common.collect.ImmutableList; |
59 | +import com.google.common.collect.ImmutableMap; | ||
57 | import com.google.common.collect.Lists; | 60 | import com.google.common.collect.Lists; |
58 | import com.google.common.collect.Sets; | 61 | import com.google.common.collect.Sets; |
59 | 62 | ||
... | @@ -68,7 +71,7 @@ public class FlowRuleManagerTest { | ... | @@ -68,7 +71,7 @@ public class FlowRuleManagerTest { |
68 | private static final DeviceId DID = DeviceId.deviceId("of:001"); | 71 | private static final DeviceId DID = DeviceId.deviceId("of:001"); |
69 | private static final int TIMEOUT = 10; | 72 | private static final int TIMEOUT = 10; |
70 | private static final Device DEV = new DefaultDevice( | 73 | private static final Device DEV = new DefaultDevice( |
71 | - PID, DID, Type.SWITCH, "", "", "", ""); | 74 | + PID, DID, Type.SWITCH, "", "", "", "", null); |
72 | 75 | ||
73 | private FlowRuleManager mgr; | 76 | private FlowRuleManager mgr; |
74 | 77 | ||
... | @@ -166,16 +169,17 @@ public class FlowRuleManagerTest { | ... | @@ -166,16 +169,17 @@ public class FlowRuleManagerTest { |
166 | } | 169 | } |
167 | 170 | ||
168 | 171 | ||
172 | + // TODO: If preserving iteration order is a requirement, redo FlowRuleStore. | ||
169 | //backing store is sensitive to the order of additions/removals | 173 | //backing store is sensitive to the order of additions/removals |
170 | - private boolean validateState(FlowEntryState... state) { | 174 | + private boolean validateState(Map<FlowRule, FlowEntryState> expected) { |
175 | + Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected); | ||
171 | Iterable<FlowEntry> rules = service.getFlowEntries(DID); | 176 | Iterable<FlowEntry> rules = service.getFlowEntries(DID); |
172 | - int i = 0; | ||
173 | for (FlowEntry f : rules) { | 177 | for (FlowEntry f : rules) { |
174 | - if (f.state() != state[i]) { | 178 | + assertTrue("Unexpected FlowRule " + f, expectedToCheck.containsKey(f)); |
175 | - return false; | 179 | + assertEquals("FlowEntry" + f, expectedToCheck.get(f), f.state()); |
176 | - } | 180 | + expectedToCheck.remove(f); |
177 | - i++; | ||
178 | } | 181 | } |
182 | + assertEquals(Collections.emptySet(), expectedToCheck.entrySet()); | ||
179 | return true; | 183 | return true; |
180 | } | 184 | } |
181 | 185 | ||
... | @@ -191,8 +195,10 @@ public class FlowRuleManagerTest { | ... | @@ -191,8 +195,10 @@ public class FlowRuleManagerTest { |
191 | mgr.applyFlowRules(r1, r2, r3); | 195 | mgr.applyFlowRules(r1, r2, r3); |
192 | assertEquals("3 rules should exist", 3, flowCount()); | 196 | assertEquals("3 rules should exist", 3, flowCount()); |
193 | assertTrue("Entries should be pending add.", | 197 | assertTrue("Entries should be pending add.", |
194 | - validateState(FlowEntryState.PENDING_ADD, FlowEntryState.PENDING_ADD, | 198 | + validateState(ImmutableMap.of( |
195 | - FlowEntryState.PENDING_ADD)); | 199 | + r1, FlowEntryState.PENDING_ADD, |
200 | + r2, FlowEntryState.PENDING_ADD, | ||
201 | + r3, FlowEntryState.PENDING_ADD))); | ||
196 | } | 202 | } |
197 | 203 | ||
198 | @Test | 204 | @Test |
... | @@ -213,8 +219,10 @@ public class FlowRuleManagerTest { | ... | @@ -213,8 +219,10 @@ public class FlowRuleManagerTest { |
213 | validateEvents(); | 219 | validateEvents(); |
214 | assertEquals("3 rule should exist", 3, flowCount()); | 220 | assertEquals("3 rule should exist", 3, flowCount()); |
215 | assertTrue("Entries should be pending remove.", | 221 | assertTrue("Entries should be pending remove.", |
216 | - validateState(FlowEntryState.PENDING_REMOVE, FlowEntryState.PENDING_REMOVE, | 222 | + validateState(ImmutableMap.of( |
217 | - FlowEntryState.ADDED)); | 223 | + f1, FlowEntryState.PENDING_REMOVE, |
224 | + f2, FlowEntryState.PENDING_REMOVE, | ||
225 | + f3, FlowEntryState.ADDED))); | ||
218 | 226 | ||
219 | mgr.removeFlowRules(f1); | 227 | mgr.removeFlowRules(f1); |
220 | assertEquals("3 rule should still exist", 3, flowCount()); | 228 | assertEquals("3 rule should still exist", 3, flowCount()); |
... | @@ -263,8 +271,10 @@ public class FlowRuleManagerTest { | ... | @@ -263,8 +271,10 @@ public class FlowRuleManagerTest { |
263 | providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2)); | 271 | providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2)); |
264 | 272 | ||
265 | assertTrue("Entries should be added.", | 273 | assertTrue("Entries should be added.", |
266 | - validateState(FlowEntryState.ADDED, FlowEntryState.ADDED, | 274 | + validateState(ImmutableMap.of( |
267 | - FlowEntryState.PENDING_ADD)); | 275 | + f1, FlowEntryState.ADDED, |
276 | + f2, FlowEntryState.ADDED, | ||
277 | + f3, FlowEntryState.PENDING_ADD))); | ||
268 | 278 | ||
269 | validateEvents(RULE_ADDED, RULE_ADDED); | 279 | validateEvents(RULE_ADDED, RULE_ADDED); |
270 | } | 280 | } |
... | @@ -336,7 +346,9 @@ public class FlowRuleManagerTest { | ... | @@ -336,7 +346,9 @@ public class FlowRuleManagerTest { |
336 | 346 | ||
337 | //only check that we are in pending remove. Events and actual remove state will | 347 | //only check that we are in pending remove. Events and actual remove state will |
338 | // be set by flowRemoved call. | 348 | // be set by flowRemoved call. |
339 | - validateState(FlowEntryState.PENDING_REMOVE, FlowEntryState.PENDING_REMOVE); | 349 | + validateState(ImmutableMap.of( |
350 | + f1, FlowEntryState.PENDING_REMOVE, | ||
351 | + f2, FlowEntryState.PENDING_REMOVE)); | ||
340 | } | 352 | } |
341 | 353 | ||
342 | @Test | 354 | @Test |
... | @@ -360,7 +372,9 @@ public class FlowRuleManagerTest { | ... | @@ -360,7 +372,9 @@ public class FlowRuleManagerTest { |
360 | Lists.newArrayList(fbe1, fbe2)); | 372 | Lists.newArrayList(fbe1, fbe2)); |
361 | Future<CompletedBatchOperation> future = mgr.applyBatch(fbo); | 373 | Future<CompletedBatchOperation> future = mgr.applyBatch(fbo); |
362 | assertTrue("Entries in wrong state", | 374 | assertTrue("Entries in wrong state", |
363 | - validateState(FlowEntryState.PENDING_REMOVE, FlowEntryState.PENDING_ADD)); | 375 | + validateState(ImmutableMap.of( |
376 | + f1, FlowEntryState.PENDING_REMOVE, | ||
377 | + f2, FlowEntryState.PENDING_ADD))); | ||
364 | CompletedBatchOperation completed = null; | 378 | CompletedBatchOperation completed = null; |
365 | try { | 379 | try { |
366 | completed = future.get(); | 380 | completed = future.get(); |
... | @@ -381,9 +395,18 @@ public class FlowRuleManagerTest { | ... | @@ -381,9 +395,18 @@ public class FlowRuleManagerTest { |
381 | 395 | ||
382 | mgr.applyFlowRules(f1); | 396 | mgr.applyFlowRules(f1); |
383 | 397 | ||
398 | + assertTrue("Entries in wrong state", | ||
399 | + validateState(ImmutableMap.of( | ||
400 | + f1, FlowEntryState.PENDING_ADD))); | ||
401 | + | ||
384 | FlowEntry fe1 = new DefaultFlowEntry(f1); | 402 | FlowEntry fe1 = new DefaultFlowEntry(f1); |
385 | providerService.pushFlowMetrics(DID, Collections.<FlowEntry>singletonList(fe1)); | 403 | providerService.pushFlowMetrics(DID, Collections.<FlowEntry>singletonList(fe1)); |
386 | 404 | ||
405 | + assertTrue("Entries in wrong state", | ||
406 | + validateState(ImmutableMap.of( | ||
407 | + f1, FlowEntryState.ADDED))); | ||
408 | + | ||
409 | + | ||
387 | FlowRuleBatchEntry fbe1 = new FlowRuleBatchEntry( | 410 | FlowRuleBatchEntry fbe1 = new FlowRuleBatchEntry( |
388 | FlowRuleBatchEntry.FlowRuleOperation.REMOVE, f1); | 411 | FlowRuleBatchEntry.FlowRuleOperation.REMOVE, f1); |
389 | 412 | ||
... | @@ -403,9 +426,9 @@ public class FlowRuleManagerTest { | ... | @@ -403,9 +426,9 @@ public class FlowRuleManagerTest { |
403 | * state. | 426 | * state. |
404 | */ | 427 | */ |
405 | assertTrue("Entries in wrong state", | 428 | assertTrue("Entries in wrong state", |
406 | - validateState(FlowEntryState.PENDING_REMOVE, | 429 | + validateState(ImmutableMap.of( |
407 | - FlowEntryState.PENDING_ADD)); | 430 | + f2, FlowEntryState.PENDING_REMOVE, |
408 | - | 431 | + f1, FlowEntryState.PENDING_ADD))); |
409 | 432 | ||
410 | 433 | ||
411 | } | 434 | } | ... | ... |
1 | +package org.onlab.onos.net.intent; | ||
2 | + | ||
3 | +import java.util.ArrayList; | ||
4 | +import java.util.Arrays; | ||
5 | +import java.util.Collections; | ||
6 | +import java.util.HashSet; | ||
7 | +import java.util.List; | ||
8 | +import java.util.Set; | ||
9 | + | ||
10 | +import org.onlab.onos.net.ElementId; | ||
11 | +import org.onlab.onos.net.Path; | ||
12 | +import org.onlab.onos.net.flow.TrafficSelector; | ||
13 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
14 | +import org.onlab.onos.net.flow.criteria.Criterion; | ||
15 | +import org.onlab.onos.net.flow.instructions.Instruction; | ||
16 | +import org.onlab.onos.net.topology.LinkWeight; | ||
17 | +import org.onlab.onos.net.topology.PathService; | ||
18 | + | ||
19 | +import static org.onlab.onos.net.NetTestTools.createPath; | ||
20 | + | ||
21 | +/** | ||
22 | + * Common mocks used by the intent framework tests. | ||
23 | + */ | ||
24 | +public class IntentTestsMocks { | ||
25 | + /** | ||
26 | + * Mock traffic selector class used for satisfying API requirements. | ||
27 | + */ | ||
28 | + public static class MockSelector implements TrafficSelector { | ||
29 | + @Override | ||
30 | + public Set<Criterion> criteria() { | ||
31 | + return new HashSet<>(); | ||
32 | + } | ||
33 | + } | ||
34 | + | ||
35 | + /** | ||
36 | + * Mock traffic treatment class used for satisfying API requirements. | ||
37 | + */ | ||
38 | + public static class MockTreatment implements TrafficTreatment { | ||
39 | + @Override | ||
40 | + public List<Instruction> instructions() { | ||
41 | + return new ArrayList<>(); | ||
42 | + } | ||
43 | + } | ||
44 | + | ||
45 | + /** | ||
46 | + * Mock path service for creating paths within the test. | ||
47 | + */ | ||
48 | + public static class MockPathService implements PathService { | ||
49 | + | ||
50 | + final String[] pathHops; | ||
51 | + final String[] reversePathHops; | ||
52 | + | ||
53 | + /** | ||
54 | + * Constructor that provides a set of hops to mock. | ||
55 | + * | ||
56 | + * @param pathHops path hops to mock | ||
57 | + */ | ||
58 | + public MockPathService(String[] pathHops) { | ||
59 | + this.pathHops = pathHops; | ||
60 | + String[] reversed = pathHops.clone(); | ||
61 | + Collections.reverse(Arrays.asList(reversed)); | ||
62 | + reversePathHops = reversed; | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
66 | + public Set<Path> getPaths(ElementId src, ElementId dst) { | ||
67 | + Set<Path> result = new HashSet<>(); | ||
68 | + | ||
69 | + String[] allHops = new String[pathHops.length]; | ||
70 | + | ||
71 | + if (src.toString().endsWith(pathHops[0])) { | ||
72 | + System.arraycopy(pathHops, 0, allHops, 0, pathHops.length); | ||
73 | + } else { | ||
74 | + System.arraycopy(reversePathHops, 0, allHops, 0, pathHops.length); | ||
75 | + } | ||
76 | + | ||
77 | + result.add(createPath(allHops)); | ||
78 | + return result; | ||
79 | + } | ||
80 | + | ||
81 | + @Override | ||
82 | + public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) { | ||
83 | + return getPaths(src, dst); | ||
84 | + } | ||
85 | + } | ||
86 | +} |
core/net/src/test/java/org/onlab/onos/net/intent/LinksHaveEntryWithSourceDestinationPairMatcher.java
0 → 100644
1 | +package org.onlab.onos.net.intent; | ||
2 | + | ||
3 | +import java.util.Collection; | ||
4 | + | ||
5 | +import org.hamcrest.Description; | ||
6 | +import org.hamcrest.TypeSafeMatcher; | ||
7 | +import org.onlab.onos.net.Link; | ||
8 | + | ||
9 | +/** | ||
10 | + * Matcher to determine if a Collection of Links contains a path between a source | ||
11 | + * and a destination. | ||
12 | + */ | ||
13 | +public class LinksHaveEntryWithSourceDestinationPairMatcher extends | ||
14 | + TypeSafeMatcher<Collection<Link>> { | ||
15 | + private final String source; | ||
16 | + private final String destination; | ||
17 | + | ||
18 | + /** | ||
19 | + * Creates a matcher for a given path represented by a source and | ||
20 | + * a destination. | ||
21 | + * | ||
22 | + * @param source string identifier for the source of the path | ||
23 | + * @param destination string identifier for the destination of the path | ||
24 | + */ | ||
25 | + LinksHaveEntryWithSourceDestinationPairMatcher(String source, | ||
26 | + String destination) { | ||
27 | + this.source = source; | ||
28 | + this.destination = destination; | ||
29 | + } | ||
30 | + | ||
31 | + @Override | ||
32 | + public boolean matchesSafely(Collection<Link> links) { | ||
33 | + for (Link link : links) { | ||
34 | + if (link.src().elementId().toString().endsWith(source) && | ||
35 | + link.dst().elementId().toString().endsWith(destination)) { | ||
36 | + return true; | ||
37 | + } | ||
38 | + } | ||
39 | + | ||
40 | + return false; | ||
41 | + } | ||
42 | + | ||
43 | + @Override | ||
44 | + public void describeTo(Description description) { | ||
45 | + description.appendText("link lookup for source \""); | ||
46 | + description.appendText(source); | ||
47 | + description.appendText(" and destination "); | ||
48 | + description.appendText(destination); | ||
49 | + description.appendText("\""); | ||
50 | + } | ||
51 | + | ||
52 | + @Override | ||
53 | + public void describeMismatchSafely(Collection<Link> links, | ||
54 | + Description mismatchDescription) { | ||
55 | + mismatchDescription.appendText("was "). | ||
56 | + appendText(links.toString()); | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * Creates a link has path matcher. | ||
61 | + * | ||
62 | + * @param source string identifier for the source of the path | ||
63 | + * @param destination string identifier for the destination of the path | ||
64 | + * @return matcher to match the path | ||
65 | + */ | ||
66 | + public static LinksHaveEntryWithSourceDestinationPairMatcher linksHasPath( | ||
67 | + String source, | ||
68 | + String destination) { | ||
69 | + return new LinksHaveEntryWithSourceDestinationPairMatcher(source, | ||
70 | + destination); | ||
71 | + } | ||
72 | +} | ||
73 | + |
1 | +package org.onlab.onos.net.intent; | ||
2 | + | ||
3 | +import org.junit.Test; | ||
4 | +import org.onlab.onos.net.HostId; | ||
5 | +import org.onlab.onos.net.flow.TrafficSelector; | ||
6 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
7 | + | ||
8 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
9 | +import static org.hamcrest.Matchers.equalTo; | ||
10 | +import static org.hamcrest.Matchers.is; | ||
11 | +import static org.hamcrest.Matchers.not; | ||
12 | +import static org.onlab.onos.net.NetTestTools.hid; | ||
13 | + | ||
14 | +/** | ||
15 | + * Unit tests for the HostToHostIntent class. | ||
16 | + */ | ||
17 | +public class TestHostToHostIntent { | ||
18 | + | ||
19 | + private TrafficSelector selector = new IntentTestsMocks.MockSelector(); | ||
20 | + private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment(); | ||
21 | + | ||
22 | + private HostToHostIntent makeHostToHost(long id, HostId one, HostId two) { | ||
23 | + return new HostToHostIntent(new IntentId(id), | ||
24 | + one, | ||
25 | + two, | ||
26 | + selector, | ||
27 | + treatment); | ||
28 | + } | ||
29 | + | ||
30 | + /** | ||
31 | + * Tests the equals() method where two HostToHostIntents have references | ||
32 | + * to the same hosts. These should compare equal. | ||
33 | + */ | ||
34 | + @Test | ||
35 | + public void testSameEquals() { | ||
36 | + | ||
37 | + HostId one = hid("00:00:00:00:00:01/-1"); | ||
38 | + HostId two = hid("00:00:00:00:00:02/-1"); | ||
39 | + HostToHostIntent i1 = makeHostToHost(12, one, two); | ||
40 | + HostToHostIntent i2 = makeHostToHost(12, one, two); | ||
41 | + | ||
42 | + assertThat(i1, is(equalTo(i2))); | ||
43 | + } | ||
44 | + | ||
45 | + /** | ||
46 | + * Tests the equals() method where two HostToHostIntents have references | ||
47 | + * to different Hosts. These should compare not equal. | ||
48 | + */ | ||
49 | + @Test | ||
50 | + public void testLinksDifferentEquals() { | ||
51 | + | ||
52 | + HostId one = hid("00:00:00:00:00:01/-1"); | ||
53 | + HostId two = hid("00:00:00:00:00:02/-1"); | ||
54 | + HostToHostIntent i1 = makeHostToHost(12, one, two); | ||
55 | + HostToHostIntent i2 = makeHostToHost(12, two, one); | ||
56 | + | ||
57 | + assertThat(i1, is(not(equalTo(i2)))); | ||
58 | + } | ||
59 | + | ||
60 | + /** | ||
61 | + * Tests the equals() method where two HostToHostIntents have different | ||
62 | + * ids. These should compare not equal. | ||
63 | + */ | ||
64 | + | ||
65 | + @Test | ||
66 | + public void testBaseDifferentEquals() { | ||
67 | + HostId one = hid("00:00:00:00:00:01/-1"); | ||
68 | + HostId two = hid("00:00:00:00:00:02/-1"); | ||
69 | + HostToHostIntent i1 = makeHostToHost(12, one, two); | ||
70 | + HostToHostIntent i2 = makeHostToHost(11, one, two); | ||
71 | + | ||
72 | + assertThat(i1, is(not(equalTo(i2)))); | ||
73 | + } | ||
74 | + | ||
75 | + /** | ||
76 | + * Tests that the hashCode() values for two equivalent HostToHostIntent | ||
77 | + * objects are the same. | ||
78 | + */ | ||
79 | + | ||
80 | + @Test | ||
81 | + public void testHashCodeEquals() { | ||
82 | + HostId one = hid("00:00:00:00:00:01/-1"); | ||
83 | + HostId two = hid("00:00:00:00:00:02/-1"); | ||
84 | + HostToHostIntent i1 = makeHostToHost(12, one, two); | ||
85 | + HostToHostIntent i2 = makeHostToHost(12, one, two); | ||
86 | + | ||
87 | + assertThat(i1.hashCode(), is(equalTo(i2.hashCode()))); | ||
88 | + } | ||
89 | + | ||
90 | + /** | ||
91 | + * Tests that the hashCode() values for two distinct LinkCollectionIntent | ||
92 | + * objects are different. | ||
93 | + */ | ||
94 | + | ||
95 | + @Test | ||
96 | + public void testHashCodeDifferent() { | ||
97 | + HostId one = hid("00:00:00:00:00:01/-1"); | ||
98 | + HostId two = hid("00:00:00:00:00:02/-1"); | ||
99 | + HostToHostIntent i1 = makeHostToHost(12, one, two); | ||
100 | + HostToHostIntent i2 = makeHostToHost(112, one, two); | ||
101 | + | ||
102 | + assertThat(i1.hashCode(), is(not(equalTo(i2.hashCode())))); | ||
103 | + } | ||
104 | + | ||
105 | + /** | ||
106 | + * Checks that the HostToHostIntent class is immutable. | ||
107 | + */ | ||
108 | + @Test | ||
109 | + public void checkImmutability() { | ||
110 | + ImmutableClassChecker.assertThatClassIsImmutable(HostToHostIntent.class); | ||
111 | + } | ||
112 | +} |
1 | package org.onlab.onos.net.intent; | 1 | package org.onlab.onos.net.intent; |
2 | 2 | ||
3 | -import java.util.ArrayList; | ||
4 | import java.util.HashSet; | 3 | import java.util.HashSet; |
5 | -import java.util.List; | ||
6 | import java.util.Set; | 4 | import java.util.Set; |
7 | 5 | ||
6 | +import org.junit.Before; | ||
8 | import org.junit.Test; | 7 | import org.junit.Test; |
9 | import org.onlab.onos.net.Link; | 8 | import org.onlab.onos.net.Link; |
10 | import org.onlab.onos.net.flow.TrafficSelector; | 9 | import org.onlab.onos.net.flow.TrafficSelector; |
11 | import org.onlab.onos.net.flow.TrafficTreatment; | 10 | import org.onlab.onos.net.flow.TrafficTreatment; |
12 | -import org.onlab.onos.net.flow.criteria.Criterion; | ||
13 | -import org.onlab.onos.net.flow.instructions.Instruction; | ||
14 | 11 | ||
12 | +import static org.hamcrest.CoreMatchers.not; | ||
15 | import static org.hamcrest.MatcherAssert.assertThat; | 13 | import static org.hamcrest.MatcherAssert.assertThat; |
14 | +import static org.hamcrest.Matchers.equalTo; | ||
16 | import static org.hamcrest.Matchers.is; | 15 | import static org.hamcrest.Matchers.is; |
16 | +import static org.onlab.onos.net.NetTestTools.link; | ||
17 | 17 | ||
18 | +/** | ||
19 | + * Unit tests for the LinkCollectionIntent class. | ||
20 | + */ | ||
18 | public class TestLinkCollectionIntent { | 21 | public class TestLinkCollectionIntent { |
19 | 22 | ||
20 | - private static class MockSelector implements TrafficSelector { | 23 | + private Link link1 = link("dev1", 1, "dev2", 2); |
21 | - @Override | 24 | + private Link link2 = link("dev1", 1, "dev3", 2); |
22 | - public Set<Criterion> criteria() { | 25 | + private Link link3 = link("dev2", 1, "dev3", 2); |
23 | - return new HashSet<Criterion>(); | 26 | + |
27 | + private Set<Link> links1; | ||
28 | + private Set<Link> links2; | ||
29 | + | ||
30 | + private TrafficSelector selector = new IntentTestsMocks.MockSelector(); | ||
31 | + private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment(); | ||
32 | + | ||
33 | + private LinkCollectionIntent makeLinkCollection(long id, Set<Link> links) { | ||
34 | + return new LinkCollectionIntent(new IntentId(id), | ||
35 | + selector, treatment, links); | ||
24 | } | 36 | } |
37 | + | ||
38 | + @Before | ||
39 | + public void setup() { | ||
40 | + links1 = new HashSet<>(); | ||
41 | + links2 = new HashSet<>(); | ||
25 | } | 42 | } |
26 | 43 | ||
27 | - private static class MockTreatment implements TrafficTreatment { | 44 | + /** |
28 | - @Override | 45 | + * Tests the equals() method where two LinkCollectionIntents have references |
29 | - public List<Instruction> instructions() { | 46 | + * to the same Links in different orders. These should compare equal. |
30 | - return new ArrayList<>(); | 47 | + */ |
48 | + @Test | ||
49 | + public void testSameEquals() { | ||
50 | + links1.add(link1); | ||
51 | + links1.add(link2); | ||
52 | + links1.add(link3); | ||
53 | + | ||
54 | + links2.add(link3); | ||
55 | + links2.add(link2); | ||
56 | + links2.add(link1); | ||
57 | + | ||
58 | + LinkCollectionIntent i1 = makeLinkCollection(12, links1); | ||
59 | + LinkCollectionIntent i2 = makeLinkCollection(12, links2); | ||
60 | + | ||
61 | + assertThat(i1, is(equalTo(i2))); | ||
31 | } | 62 | } |
63 | + | ||
64 | + /** | ||
65 | + * Tests the equals() method where two LinkCollectionIntents have references | ||
66 | + * to different Links. These should compare not equal. | ||
67 | + */ | ||
68 | + @Test | ||
69 | + public void testLinksDifferentEquals() { | ||
70 | + links1.add(link1); | ||
71 | + links1.add(link2); | ||
72 | + | ||
73 | + links2.add(link3); | ||
74 | + links2.add(link1); | ||
75 | + | ||
76 | + LinkCollectionIntent i1 = makeLinkCollection(12, links1); | ||
77 | + LinkCollectionIntent i2 = makeLinkCollection(12, links2); | ||
78 | + | ||
79 | + assertThat(i1, is(not(equalTo(i2)))); | ||
32 | } | 80 | } |
33 | 81 | ||
82 | + /** | ||
83 | + * Tests the equals() method where two LinkCollectionIntents have different | ||
84 | + * ids. These should compare not equal. | ||
85 | + */ | ||
34 | @Test | 86 | @Test |
35 | - public void testComparison() { | 87 | + public void testBaseDifferentEquals() { |
36 | - TrafficSelector selector = new MockSelector(); | 88 | + links1.add(link1); |
37 | - TrafficTreatment treatment = new MockTreatment(); | 89 | + links1.add(link2); |
38 | - Set<Link> links = new HashSet<>(); | ||
39 | - LinkCollectionIntent i1 = new LinkCollectionIntent(new IntentId(12), | ||
40 | - selector, treatment, links); | ||
41 | - LinkCollectionIntent i2 = new LinkCollectionIntent(new IntentId(12), | ||
42 | - selector, treatment, links); | ||
43 | 90 | ||
44 | - assertThat(i1.equals(i2), is(true)); | 91 | + links2.add(link2); |
92 | + links2.add(link1); | ||
93 | + | ||
94 | + LinkCollectionIntent i1 = makeLinkCollection(1, links1); | ||
95 | + LinkCollectionIntent i2 = makeLinkCollection(2, links2); | ||
96 | + | ||
97 | + assertThat(i1, is(not(equalTo(i2)))); | ||
98 | + } | ||
99 | + | ||
100 | + /** | ||
101 | + * Tests that the hashCode() values for two equivalent LinkCollectionIntent | ||
102 | + * objects are the same. | ||
103 | + */ | ||
104 | + @Test | ||
105 | + public void testHashCodeEquals() { | ||
106 | + links1.add(link1); | ||
107 | + links1.add(link2); | ||
108 | + links1.add(link3); | ||
109 | + | ||
110 | + links2.add(link3); | ||
111 | + links2.add(link2); | ||
112 | + links2.add(link1); | ||
113 | + | ||
114 | + LinkCollectionIntent i1 = makeLinkCollection(1, links1); | ||
115 | + LinkCollectionIntent i2 = makeLinkCollection(1, links2); | ||
116 | + | ||
117 | + assertThat(i1.hashCode(), is(equalTo(i2.hashCode()))); | ||
45 | } | 118 | } |
46 | 119 | ||
120 | + /** | ||
121 | + * Tests that the hashCode() values for two distinct LinkCollectionIntent | ||
122 | + * objects are different. | ||
123 | + */ | ||
124 | + @Test | ||
125 | + public void testHashCodeDifferent() { | ||
126 | + links1.add(link1); | ||
127 | + links1.add(link2); | ||
128 | + | ||
129 | + links2.add(link1); | ||
130 | + links2.add(link3); | ||
131 | + | ||
132 | + LinkCollectionIntent i1 = makeLinkCollection(1, links1); | ||
133 | + LinkCollectionIntent i2 = makeLinkCollection(1, links2); | ||
134 | + | ||
135 | + assertThat(i1.hashCode(), is(not(equalTo(i2.hashCode())))); | ||
136 | + } | ||
137 | + | ||
138 | + /** | ||
139 | + * Checks that the HostToHostIntent class is immutable. | ||
140 | + */ | ||
141 | + @Test | ||
142 | + public void checkImmutability() { | ||
143 | + ImmutableClassChecker.assertThatClassIsImmutable(LinkCollectionIntent.class); | ||
144 | + } | ||
47 | } | 145 | } | ... | ... |
1 | +package org.onlab.onos.net.intent; | ||
2 | + | ||
3 | +import java.util.HashSet; | ||
4 | +import java.util.Set; | ||
5 | + | ||
6 | +import org.junit.Before; | ||
7 | +import org.junit.Test; | ||
8 | +import org.onlab.onos.net.ConnectPoint; | ||
9 | +import org.onlab.onos.net.flow.TrafficSelector; | ||
10 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
11 | + | ||
12 | +import static org.hamcrest.CoreMatchers.not; | ||
13 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
14 | +import static org.hamcrest.Matchers.equalTo; | ||
15 | +import static org.hamcrest.Matchers.is; | ||
16 | +import static org.onlab.onos.net.NetTestTools.connectPoint; | ||
17 | + | ||
18 | +/** | ||
19 | + * Unit tests for the MultiPointToSinglePointIntent class. | ||
20 | + */ | ||
21 | +public class TestMultiPointToSinglePointIntent { | ||
22 | + | ||
23 | + private ConnectPoint point1 = connectPoint("dev1", 1); | ||
24 | + private ConnectPoint point2 = connectPoint("dev2", 1); | ||
25 | + private ConnectPoint point3 = connectPoint("dev3", 1); | ||
26 | + | ||
27 | + private TrafficSelector selector = new IntentTestsMocks.MockSelector(); | ||
28 | + private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment(); | ||
29 | + | ||
30 | + Set<ConnectPoint> ingress1; | ||
31 | + Set<ConnectPoint> ingress2; | ||
32 | + | ||
33 | + /** | ||
34 | + * Creates a MultiPointToSinglePointIntent object. | ||
35 | + * | ||
36 | + * @param id identifier to use for the new intent | ||
37 | + * @param ingress set of ingress points | ||
38 | + * @param egress egress point | ||
39 | + * @return MultiPointToSinglePoint intent | ||
40 | + */ | ||
41 | + private MultiPointToSinglePointIntent makeIntent(long id, | ||
42 | + Set<ConnectPoint> ingress, | ||
43 | + ConnectPoint egress) { | ||
44 | + return new MultiPointToSinglePointIntent(new IntentId(id), | ||
45 | + selector, | ||
46 | + treatment, | ||
47 | + ingress, | ||
48 | + egress); | ||
49 | + } | ||
50 | + | ||
51 | + /** | ||
52 | + * Initializes the ingress sets. | ||
53 | + */ | ||
54 | + @Before | ||
55 | + public void setup() { | ||
56 | + ingress1 = new HashSet<>(); | ||
57 | + ingress2 = new HashSet<>(); | ||
58 | + } | ||
59 | + | ||
60 | + /** | ||
61 | + * Tests the equals() method where two MultiPointToSinglePoint have references | ||
62 | + * to the same Links in different orders. These should compare equal. | ||
63 | + */ | ||
64 | + @Test | ||
65 | + public void testSameEquals() { | ||
66 | + | ||
67 | + Set<ConnectPoint> ingress1 = new HashSet<>(); | ||
68 | + ingress1.add(point2); | ||
69 | + ingress1.add(point3); | ||
70 | + | ||
71 | + Set<ConnectPoint> ingress2 = new HashSet<>(); | ||
72 | + ingress2.add(point3); | ||
73 | + ingress2.add(point2); | ||
74 | + | ||
75 | + Intent i1 = makeIntent(12, ingress1, point1); | ||
76 | + Intent i2 = makeIntent(12, ingress2, point1); | ||
77 | + | ||
78 | + assertThat(i1, is(equalTo(i2))); | ||
79 | + } | ||
80 | + | ||
81 | + /** | ||
82 | + * Tests the equals() method where two MultiPointToSinglePoint have references | ||
83 | + * to different Links. These should compare not equal. | ||
84 | + */ | ||
85 | + @Test | ||
86 | + public void testLinksDifferentEquals() { | ||
87 | + ingress1.add(point3); | ||
88 | + | ||
89 | + ingress2.add(point3); | ||
90 | + ingress2.add(point2); | ||
91 | + | ||
92 | + Intent i1 = makeIntent(12, ingress1, point1); | ||
93 | + Intent i2 = makeIntent(12, ingress2, point1); | ||
94 | + | ||
95 | + assertThat(i1, is(not(equalTo(i2)))); | ||
96 | + } | ||
97 | + | ||
98 | + /** | ||
99 | + * Tests the equals() method where two MultiPointToSinglePoint have different | ||
100 | + * ids. These should compare not equal. | ||
101 | + */ | ||
102 | + @Test | ||
103 | + public void testBaseDifferentEquals() { | ||
104 | + ingress1.add(point3); | ||
105 | + ingress2.add(point3); | ||
106 | + | ||
107 | + Intent i1 = makeIntent(12, ingress1, point1); | ||
108 | + Intent i2 = makeIntent(11, ingress2, point1); | ||
109 | + | ||
110 | + assertThat(i1, is(not(equalTo(i2)))); | ||
111 | + } | ||
112 | + | ||
113 | + /** | ||
114 | + * Tests that the hashCode() values for two equivalent MultiPointToSinglePoint | ||
115 | + * objects are the same. | ||
116 | + */ | ||
117 | + @Test | ||
118 | + public void testHashCodeEquals() { | ||
119 | + ingress1.add(point2); | ||
120 | + ingress1.add(point3); | ||
121 | + | ||
122 | + ingress2.add(point3); | ||
123 | + ingress2.add(point2); | ||
124 | + | ||
125 | + Intent i1 = makeIntent(12, ingress1, point1); | ||
126 | + Intent i2 = makeIntent(12, ingress2, point1); | ||
127 | + | ||
128 | + assertThat(i1.hashCode(), is(equalTo(i2.hashCode()))); | ||
129 | + } | ||
130 | + | ||
131 | + /** | ||
132 | + * Tests that the hashCode() values for two distinct MultiPointToSinglePoint | ||
133 | + * objects are different. | ||
134 | + */ | ||
135 | + @Test | ||
136 | + public void testHashCodeDifferent() { | ||
137 | + ingress1.add(point2); | ||
138 | + | ||
139 | + ingress2.add(point3); | ||
140 | + ingress2.add(point2); | ||
141 | + | ||
142 | + Intent i1 = makeIntent(12, ingress1, point1); | ||
143 | + Intent i2 = makeIntent(12, ingress2, point1); | ||
144 | + | ||
145 | + | ||
146 | + assertThat(i1.hashCode(), is(not(equalTo(i2.hashCode())))); | ||
147 | + } | ||
148 | + | ||
149 | + /** | ||
150 | + * Checks that the MultiPointToSinglePointIntent class is immutable. | ||
151 | + */ | ||
152 | + @Test | ||
153 | + public void checkImmutability() { | ||
154 | + ImmutableClassChecker. | ||
155 | + assertThatClassIsImmutable(MultiPointToSinglePointIntent.class); | ||
156 | + } | ||
157 | +} |
1 | +package org.onlab.onos.net.intent; | ||
2 | + | ||
3 | +import org.junit.Test; | ||
4 | +import org.onlab.onos.net.ConnectPoint; | ||
5 | +import org.onlab.onos.net.flow.TrafficSelector; | ||
6 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
7 | + | ||
8 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
9 | +import static org.hamcrest.Matchers.equalTo; | ||
10 | +import static org.hamcrest.Matchers.is; | ||
11 | +import static org.hamcrest.Matchers.not; | ||
12 | +import static org.onlab.onos.net.NetTestTools.connectPoint; | ||
13 | + | ||
14 | +/** | ||
15 | + * Unit tests for the HostToHostIntent class. | ||
16 | + */ | ||
17 | +public class TestPointToPointIntent { | ||
18 | + | ||
19 | + private TrafficSelector selector = new IntentTestsMocks.MockSelector(); | ||
20 | + private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment(); | ||
21 | + | ||
22 | + private ConnectPoint point1 = connectPoint("dev1", 1); | ||
23 | + private ConnectPoint point2 = connectPoint("dev2", 1); | ||
24 | + | ||
25 | + private PointToPointIntent makePointToPoint(long id, | ||
26 | + ConnectPoint ingress, | ||
27 | + ConnectPoint egress) { | ||
28 | + return new PointToPointIntent(new IntentId(id), | ||
29 | + selector, | ||
30 | + treatment, | ||
31 | + ingress, | ||
32 | + egress); | ||
33 | + } | ||
34 | + | ||
35 | + /** | ||
36 | + * Tests the equals() method where two PointToPointIntents have references | ||
37 | + * to the same ingress and egress points. These should compare equal. | ||
38 | + */ | ||
39 | + @Test | ||
40 | + public void testSameEquals() { | ||
41 | + PointToPointIntent i1 = makePointToPoint(12, point1, point2); | ||
42 | + PointToPointIntent i2 = makePointToPoint(12, point1, point2); | ||
43 | + | ||
44 | + assertThat(i1, is(equalTo(i2))); | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Tests the equals() method where two HostToHostIntents have references | ||
49 | + * to different Hosts. These should compare not equal. | ||
50 | + */ | ||
51 | + @Test | ||
52 | + public void testLinksDifferentEquals() { | ||
53 | + | ||
54 | + PointToPointIntent i1 = makePointToPoint(12, point1, point2); | ||
55 | + PointToPointIntent i2 = makePointToPoint(12, point2, point1); | ||
56 | + | ||
57 | + assertThat(i1, is(not(equalTo(i2)))); | ||
58 | + } | ||
59 | + | ||
60 | + /** | ||
61 | + * Tests the equals() method where two HostToHostIntents have different | ||
62 | + * ids. These should compare not equal. | ||
63 | + */ | ||
64 | + @Test | ||
65 | + public void testBaseDifferentEquals() { | ||
66 | + PointToPointIntent i1 = makePointToPoint(12, point1, point2); | ||
67 | + PointToPointIntent i2 = makePointToPoint(11, point1, point2); | ||
68 | + | ||
69 | + | ||
70 | + assertThat(i1, is(not(equalTo(i2)))); | ||
71 | + } | ||
72 | + | ||
73 | + /** | ||
74 | + * Tests that the hashCode() values for two equivalent HostToHostIntent | ||
75 | + * objects are the same. | ||
76 | + */ | ||
77 | + @Test | ||
78 | + public void testHashCodeEquals() { | ||
79 | + PointToPointIntent i1 = makePointToPoint(12, point1, point2); | ||
80 | + PointToPointIntent i2 = makePointToPoint(12, point1, point2); | ||
81 | + | ||
82 | + assertThat(i1.hashCode(), is(equalTo(i2.hashCode()))); | ||
83 | + } | ||
84 | + | ||
85 | + /** | ||
86 | + * Tests that the hashCode() values for two distinct LinkCollectionIntent | ||
87 | + * objects are different. | ||
88 | + */ | ||
89 | + @Test | ||
90 | + public void testHashCodeDifferent() { | ||
91 | + PointToPointIntent i1 = makePointToPoint(12, point1, point2); | ||
92 | + PointToPointIntent i2 = makePointToPoint(22, point1, point2); | ||
93 | + | ||
94 | + assertThat(i1.hashCode(), is(not(equalTo(i2.hashCode())))); | ||
95 | + } | ||
96 | +} |
1 | +package org.onlab.onos.net.intent.impl; | ||
2 | + | ||
3 | +import java.util.List; | ||
4 | + | ||
5 | +import org.hamcrest.Matchers; | ||
6 | +import org.junit.Before; | ||
7 | +import org.junit.Test; | ||
8 | +import org.onlab.onos.net.Host; | ||
9 | +import org.onlab.onos.net.HostId; | ||
10 | +import org.onlab.onos.net.flow.TrafficSelector; | ||
11 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
12 | +import org.onlab.onos.net.host.HostService; | ||
13 | +import org.onlab.onos.net.intent.HostToHostIntent; | ||
14 | +import org.onlab.onos.net.intent.Intent; | ||
15 | +import org.onlab.onos.net.intent.IntentId; | ||
16 | +import org.onlab.onos.net.intent.IntentTestsMocks; | ||
17 | +import org.onlab.onos.net.intent.PathIntent; | ||
18 | +import org.onlab.packet.MacAddress; | ||
19 | +import org.onlab.packet.VlanId; | ||
20 | + | ||
21 | +import static org.easymock.EasyMock.createMock; | ||
22 | +import static org.easymock.EasyMock.eq; | ||
23 | +import static org.easymock.EasyMock.expect; | ||
24 | +import static org.easymock.EasyMock.replay; | ||
25 | +import static org.hamcrest.CoreMatchers.notNullValue; | ||
26 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
27 | +import static org.hamcrest.Matchers.hasSize; | ||
28 | +import static org.hamcrest.Matchers.is; | ||
29 | +import static org.onlab.onos.net.NetTestTools.hid; | ||
30 | +import static org.onlab.onos.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath; | ||
31 | + | ||
32 | +/** | ||
33 | + * Unit tests for the HostToHost intent compiler. | ||
34 | + */ | ||
35 | +public class TestHostToHostIntentCompiler { | ||
36 | + private static final String HOST_ONE_MAC = "00:00:00:00:00:01"; | ||
37 | + private static final String HOST_TWO_MAC = "00:00:00:00:00:02"; | ||
38 | + private static final String HOST_ONE_VLAN = "-1"; | ||
39 | + private static final String HOST_TWO_VLAN = "-1"; | ||
40 | + private static final String HOST_ONE = HOST_ONE_MAC + "/" + HOST_ONE_VLAN; | ||
41 | + private static final String HOST_TWO = HOST_TWO_MAC + "/" + HOST_TWO_VLAN; | ||
42 | + | ||
43 | + private TrafficSelector selector = new IntentTestsMocks.MockSelector(); | ||
44 | + private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment(); | ||
45 | + | ||
46 | + private HostId hostOneId = HostId.hostId(HOST_ONE); | ||
47 | + private HostId hostTwoId = HostId.hostId(HOST_TWO); | ||
48 | + private HostService mockHostService; | ||
49 | + | ||
50 | + @Before | ||
51 | + public void setup() { | ||
52 | + Host hostOne = createMock(Host.class); | ||
53 | + expect(hostOne.mac()).andReturn(new MacAddress(HOST_ONE_MAC.getBytes())).anyTimes(); | ||
54 | + expect(hostOne.vlan()).andReturn(VlanId.vlanId()).anyTimes(); | ||
55 | + replay(hostOne); | ||
56 | + | ||
57 | + Host hostTwo = createMock(Host.class); | ||
58 | + expect(hostTwo.mac()).andReturn(new MacAddress(HOST_TWO_MAC.getBytes())).anyTimes(); | ||
59 | + expect(hostTwo.vlan()).andReturn(VlanId.vlanId()).anyTimes(); | ||
60 | + replay(hostTwo); | ||
61 | + | ||
62 | + mockHostService = createMock(HostService.class); | ||
63 | + expect(mockHostService.getHost(eq(hostOneId))).andReturn(hostOne).anyTimes(); | ||
64 | + expect(mockHostService.getHost(eq(hostTwoId))).andReturn(hostTwo).anyTimes(); | ||
65 | + replay(mockHostService); | ||
66 | + } | ||
67 | + | ||
68 | + /** | ||
69 | + * Creates a HostToHost intent based on two host Ids. | ||
70 | + * | ||
71 | + * @param oneIdString string for host one id | ||
72 | + * @param twoIdString string for host two id | ||
73 | + * @return HostToHostIntent for the two hosts | ||
74 | + */ | ||
75 | + private HostToHostIntent makeIntent(String oneIdString, String twoIdString) { | ||
76 | + return new HostToHostIntent(new IntentId(12), | ||
77 | + hid(oneIdString), | ||
78 | + hid(twoIdString), | ||
79 | + selector, | ||
80 | + treatment); | ||
81 | + } | ||
82 | + | ||
83 | + /** | ||
84 | + * Creates a compiler for HostToHost intents. | ||
85 | + * | ||
86 | + * @param hops string array describing the path hops to use when compiling | ||
87 | + * @return HostToHost intent compiler | ||
88 | + */ | ||
89 | + private HostToHostIntentCompiler makeCompiler(String[] hops) { | ||
90 | + HostToHostIntentCompiler compiler = | ||
91 | + new HostToHostIntentCompiler(); | ||
92 | + compiler.pathService = new IntentTestsMocks.MockPathService(hops); | ||
93 | + compiler.hostService = mockHostService; | ||
94 | + IdBlockAllocator idBlockAllocator = new DummyIdBlockAllocator(); | ||
95 | + compiler.intentIdGenerator = | ||
96 | + new IdBlockAllocatorBasedIntentIdGenerator(idBlockAllocator); | ||
97 | + return compiler; | ||
98 | + } | ||
99 | + | ||
100 | + | ||
101 | + /** | ||
102 | + * Tests a pair of hosts with 8 hops between them. | ||
103 | + */ | ||
104 | + @Test | ||
105 | + public void testSingleLongPathCompilation() { | ||
106 | + | ||
107 | + HostToHostIntent intent = makeIntent(HOST_ONE, | ||
108 | + HOST_TWO); | ||
109 | + assertThat(intent, is(notNullValue())); | ||
110 | + | ||
111 | + String[] hops = {HOST_ONE, "h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8", HOST_TWO}; | ||
112 | + HostToHostIntentCompiler compiler = makeCompiler(hops); | ||
113 | + assertThat(compiler, is(notNullValue())); | ||
114 | + | ||
115 | + List<Intent> result = compiler.compile(intent); | ||
116 | + assertThat(result, is(Matchers.notNullValue())); | ||
117 | + assertThat(result, hasSize(2)); | ||
118 | + Intent forwardResultIntent = result.get(0); | ||
119 | + assertThat(forwardResultIntent instanceof PathIntent, is(true)); | ||
120 | + Intent reverseResultIntent = result.get(1); | ||
121 | + assertThat(reverseResultIntent instanceof PathIntent, is(true)); | ||
122 | + | ||
123 | + if (forwardResultIntent instanceof PathIntent) { | ||
124 | + PathIntent forwardPathIntent = (PathIntent) forwardResultIntent; | ||
125 | + assertThat(forwardPathIntent.path().links(), hasSize(9)); | ||
126 | + assertThat(forwardPathIntent.path().links(), linksHasPath(HOST_ONE, "h1")); | ||
127 | + assertThat(forwardPathIntent.path().links(), linksHasPath("h1", "h2")); | ||
128 | + assertThat(forwardPathIntent.path().links(), linksHasPath("h2", "h3")); | ||
129 | + assertThat(forwardPathIntent.path().links(), linksHasPath("h3", "h4")); | ||
130 | + assertThat(forwardPathIntent.path().links(), linksHasPath("h4", "h5")); | ||
131 | + assertThat(forwardPathIntent.path().links(), linksHasPath("h5", "h6")); | ||
132 | + assertThat(forwardPathIntent.path().links(), linksHasPath("h6", "h7")); | ||
133 | + assertThat(forwardPathIntent.path().links(), linksHasPath("h7", "h8")); | ||
134 | + assertThat(forwardPathIntent.path().links(), linksHasPath("h8", HOST_TWO)); | ||
135 | + } | ||
136 | + | ||
137 | + if (reverseResultIntent instanceof PathIntent) { | ||
138 | + PathIntent reversePathIntent = (PathIntent) reverseResultIntent; | ||
139 | + assertThat(reversePathIntent.path().links(), hasSize(9)); | ||
140 | + assertThat(reversePathIntent.path().links(), linksHasPath("h1", HOST_ONE)); | ||
141 | + assertThat(reversePathIntent.path().links(), linksHasPath("h2", "h1")); | ||
142 | + assertThat(reversePathIntent.path().links(), linksHasPath("h3", "h2")); | ||
143 | + assertThat(reversePathIntent.path().links(), linksHasPath("h4", "h3")); | ||
144 | + assertThat(reversePathIntent.path().links(), linksHasPath("h5", "h4")); | ||
145 | + assertThat(reversePathIntent.path().links(), linksHasPath("h6", "h5")); | ||
146 | + assertThat(reversePathIntent.path().links(), linksHasPath("h7", "h6")); | ||
147 | + assertThat(reversePathIntent.path().links(), linksHasPath("h8", "h7")); | ||
148 | + assertThat(reversePathIntent.path().links(), linksHasPath(HOST_TWO, "h8")); | ||
149 | + } | ||
150 | + } | ||
151 | +} |
core/net/src/test/java/org/onlab/onos/net/intent/impl/TestMultiPointToSinglePointIntentCompiler.java
0 → 100644
1 | +package org.onlab.onos.net.intent.impl; | ||
2 | + | ||
3 | +import java.util.HashSet; | ||
4 | +import java.util.List; | ||
5 | +import java.util.Set; | ||
6 | + | ||
7 | +import org.hamcrest.Matchers; | ||
8 | +import org.junit.Test; | ||
9 | +import org.onlab.onos.net.ConnectPoint; | ||
10 | +import org.onlab.onos.net.ElementId; | ||
11 | +import org.onlab.onos.net.Path; | ||
12 | +import org.onlab.onos.net.flow.TrafficSelector; | ||
13 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
14 | +import org.onlab.onos.net.intent.Intent; | ||
15 | +import org.onlab.onos.net.intent.IntentId; | ||
16 | +import org.onlab.onos.net.intent.IntentTestsMocks; | ||
17 | +import org.onlab.onos.net.intent.LinkCollectionIntent; | ||
18 | +import org.onlab.onos.net.intent.MultiPointToSinglePointIntent; | ||
19 | +import org.onlab.onos.net.topology.LinkWeight; | ||
20 | +import org.onlab.onos.net.topology.PathService; | ||
21 | + | ||
22 | +import static org.hamcrest.CoreMatchers.notNullValue; | ||
23 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
24 | +import static org.hamcrest.Matchers.hasSize; | ||
25 | +import static org.hamcrest.Matchers.is; | ||
26 | +import static org.onlab.onos.net.NetTestTools.connectPoint; | ||
27 | +import static org.onlab.onos.net.NetTestTools.createPath; | ||
28 | +import static org.onlab.onos.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath; | ||
29 | + | ||
30 | +/** | ||
31 | + * Unit tests for the MultiPointToSinglePoint intent compiler. | ||
32 | + */ | ||
33 | +public class TestMultiPointToSinglePointIntentCompiler { | ||
34 | + | ||
35 | + private TrafficSelector selector = new IntentTestsMocks.MockSelector(); | ||
36 | + private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment(); | ||
37 | + | ||
38 | + /** | ||
39 | + * Mock path service for creating paths within the test. | ||
40 | + */ | ||
41 | + private static class MockPathService implements PathService { | ||
42 | + | ||
43 | + final String[] pathHops; | ||
44 | + | ||
45 | + /** | ||
46 | + * Constructor that provides a set of hops to mock. | ||
47 | + * | ||
48 | + * @param pathHops path hops to mock | ||
49 | + */ | ||
50 | + MockPathService(String[] pathHops) { | ||
51 | + this.pathHops = pathHops; | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
55 | + public Set<Path> getPaths(ElementId src, ElementId dst) { | ||
56 | + Set<Path> result = new HashSet<>(); | ||
57 | + | ||
58 | + String[] allHops = new String[pathHops.length + 1]; | ||
59 | + allHops[0] = src.toString(); | ||
60 | + System.arraycopy(pathHops, 0, allHops, 1, pathHops.length); | ||
61 | + | ||
62 | + result.add(createPath(allHops)); | ||
63 | + return result; | ||
64 | + } | ||
65 | + | ||
66 | + @Override | ||
67 | + public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) { | ||
68 | + return null; | ||
69 | + } | ||
70 | + } | ||
71 | + | ||
72 | + /** | ||
73 | + * Creates a MultiPointToSinglePoint intent for a group of ingress points | ||
74 | + * and an egress point. | ||
75 | + * | ||
76 | + * @param ingressIds array of ingress device ids | ||
77 | + * @param egressId device id of the egress point | ||
78 | + * @return MultiPointToSinglePoint intent | ||
79 | + */ | ||
80 | + private MultiPointToSinglePointIntent makeIntent(String[] ingressIds, String egressId) { | ||
81 | + Set<ConnectPoint> ingressPoints = new HashSet<>(); | ||
82 | + ConnectPoint egressPoint = connectPoint(egressId, 1); | ||
83 | + | ||
84 | + for (String ingressId : ingressIds) { | ||
85 | + ingressPoints.add(connectPoint(ingressId, 1)); | ||
86 | + } | ||
87 | + | ||
88 | + return new MultiPointToSinglePointIntent( | ||
89 | + new IntentId(12), | ||
90 | + selector, | ||
91 | + treatment, | ||
92 | + ingressPoints, | ||
93 | + egressPoint); | ||
94 | + } | ||
95 | + | ||
96 | + /** | ||
97 | + * Creates a compiler for MultiPointToSinglePoint intents. | ||
98 | + * | ||
99 | + * @param hops hops to use while computing paths for this intent | ||
100 | + * @return MultiPointToSinglePoint intent | ||
101 | + */ | ||
102 | + private MultiPointToSinglePointIntentCompiler makeCompiler(String[] hops) { | ||
103 | + MultiPointToSinglePointIntentCompiler compiler = | ||
104 | + new MultiPointToSinglePointIntentCompiler(); | ||
105 | + compiler.pathService = new MockPathService(hops); | ||
106 | + IdBlockAllocator idBlockAllocator = new DummyIdBlockAllocator(); | ||
107 | + compiler.intentIdGenerator = | ||
108 | + new IdBlockAllocatorBasedIntentIdGenerator(idBlockAllocator); | ||
109 | + return compiler; | ||
110 | + } | ||
111 | + | ||
112 | + /** | ||
113 | + * Tests a single ingress point with 8 hops to its egress point. | ||
114 | + */ | ||
115 | + @Test | ||
116 | + public void testSingleLongPathCompilation() { | ||
117 | + | ||
118 | + String[] ingress = {"ingress"}; | ||
119 | + String egress = "egress"; | ||
120 | + | ||
121 | + MultiPointToSinglePointIntent intent = makeIntent(ingress, egress); | ||
122 | + assertThat(intent, is(notNullValue())); | ||
123 | + | ||
124 | + String[] hops = {"h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8", | ||
125 | + egress}; | ||
126 | + MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops); | ||
127 | + assertThat(compiler, is(notNullValue())); | ||
128 | + | ||
129 | + List<Intent> result = compiler.compile(intent); | ||
130 | + assertThat(result, is(Matchers.notNullValue())); | ||
131 | + assertThat(result, hasSize(1)); | ||
132 | + Intent resultIntent = result.get(0); | ||
133 | + assertThat(resultIntent instanceof LinkCollectionIntent, is(true)); | ||
134 | + | ||
135 | + if (resultIntent instanceof LinkCollectionIntent) { | ||
136 | + LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent; | ||
137 | + assertThat(linkIntent.links(), hasSize(9)); | ||
138 | + assertThat(linkIntent.links(), linksHasPath("ingress", "h1")); | ||
139 | + assertThat(linkIntent.links(), linksHasPath("h1", "h2")); | ||
140 | + assertThat(linkIntent.links(), linksHasPath("h2", "h3")); | ||
141 | + assertThat(linkIntent.links(), linksHasPath("h4", "h5")); | ||
142 | + assertThat(linkIntent.links(), linksHasPath("h5", "h6")); | ||
143 | + assertThat(linkIntent.links(), linksHasPath("h7", "h8")); | ||
144 | + assertThat(linkIntent.links(), linksHasPath("h8", "egress")); | ||
145 | + } | ||
146 | + } | ||
147 | + | ||
148 | + /** | ||
149 | + * Tests a simple topology where two ingress points share some path segments | ||
150 | + * and some path segments are not shared. | ||
151 | + */ | ||
152 | + @Test | ||
153 | + public void testTwoIngressCompilation() { | ||
154 | + String[] ingress = {"ingress1", "ingress2"}; | ||
155 | + String egress = "egress"; | ||
156 | + | ||
157 | + MultiPointToSinglePointIntent intent = makeIntent(ingress, egress); | ||
158 | + assertThat(intent, is(notNullValue())); | ||
159 | + | ||
160 | + final String[] hops = {"inner1", "inner2", egress}; | ||
161 | + MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops); | ||
162 | + assertThat(compiler, is(notNullValue())); | ||
163 | + | ||
164 | + List<Intent> result = compiler.compile(intent); | ||
165 | + assertThat(result, is(notNullValue())); | ||
166 | + assertThat(result, hasSize(1)); | ||
167 | + Intent resultIntent = result.get(0); | ||
168 | + assertThat(resultIntent instanceof LinkCollectionIntent, is(true)); | ||
169 | + | ||
170 | + if (resultIntent instanceof LinkCollectionIntent) { | ||
171 | + LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent; | ||
172 | + assertThat(linkIntent.links(), hasSize(4)); | ||
173 | + assertThat(linkIntent.links(), linksHasPath("ingress1", "inner1")); | ||
174 | + assertThat(linkIntent.links(), linksHasPath("ingress2", "inner1")); | ||
175 | + assertThat(linkIntent.links(), linksHasPath("inner1", "inner2")); | ||
176 | + assertThat(linkIntent.links(), linksHasPath("inner2", "egress")); | ||
177 | + } | ||
178 | + } | ||
179 | + | ||
180 | + /** | ||
181 | + * Tests a large number of ingress points that share a common path to the | ||
182 | + * egress point. | ||
183 | + */ | ||
184 | + @Test | ||
185 | + public void testMultiIngressCompilation() { | ||
186 | + String[] ingress = {"i1", "i2", "i3", "i4", "i5", | ||
187 | + "i6", "i7", "i8", "i9", "i10"}; | ||
188 | + String egress = "e"; | ||
189 | + | ||
190 | + MultiPointToSinglePointIntent intent = makeIntent(ingress, egress); | ||
191 | + assertThat(intent, is(notNullValue())); | ||
192 | + | ||
193 | + final String[] hops = {"n1", egress}; | ||
194 | + MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops); | ||
195 | + assertThat(compiler, is(notNullValue())); | ||
196 | + | ||
197 | + List<Intent> result = compiler.compile(intent); | ||
198 | + assertThat(result, is(notNullValue())); | ||
199 | + assertThat(result, hasSize(1)); | ||
200 | + Intent resultIntent = result.get(0); | ||
201 | + assertThat(resultIntent instanceof LinkCollectionIntent, is(true)); | ||
202 | + | ||
203 | + if (resultIntent instanceof LinkCollectionIntent) { | ||
204 | + LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent; | ||
205 | + assertThat(linkIntent.links(), hasSize(ingress.length + 1)); | ||
206 | + for (String ingressToCheck : ingress) { | ||
207 | + assertThat(linkIntent.links(), | ||
208 | + linksHasPath(ingressToCheck, | ||
209 | + "n1")); | ||
210 | + } | ||
211 | + assertThat(linkIntent.links(), linksHasPath("n1", egress)); | ||
212 | + } | ||
213 | + } | ||
214 | +} |
core/net/src/test/java/org/onlab/onos/net/intent/impl/TestPointToPointIntentCompiler.java
0 → 100644
1 | +package org.onlab.onos.net.intent.impl; | ||
2 | + | ||
3 | +import java.util.List; | ||
4 | + | ||
5 | +import org.hamcrest.Matchers; | ||
6 | +import org.junit.Test; | ||
7 | +import org.onlab.onos.net.flow.TrafficSelector; | ||
8 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
9 | +import org.onlab.onos.net.intent.Intent; | ||
10 | +import org.onlab.onos.net.intent.IntentId; | ||
11 | +import org.onlab.onos.net.intent.IntentTestsMocks; | ||
12 | +import org.onlab.onos.net.intent.PathIntent; | ||
13 | +import org.onlab.onos.net.intent.PointToPointIntent; | ||
14 | + | ||
15 | +import static org.hamcrest.CoreMatchers.notNullValue; | ||
16 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
17 | +import static org.hamcrest.Matchers.hasSize; | ||
18 | +import static org.hamcrest.Matchers.is; | ||
19 | +import static org.onlab.onos.net.NetTestTools.connectPoint; | ||
20 | +import static org.onlab.onos.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath; | ||
21 | + | ||
22 | +/** | ||
23 | + * Unit tests for the HostToHost intent compiler. | ||
24 | + */ | ||
25 | +public class TestPointToPointIntentCompiler { | ||
26 | + | ||
27 | + private TrafficSelector selector = new IntentTestsMocks.MockSelector(); | ||
28 | + private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment(); | ||
29 | + | ||
30 | + /** | ||
31 | + * Creates a PointToPoint intent based on ingress and egress device Ids. | ||
32 | + * | ||
33 | + * @param ingressIdString string for id of ingress device | ||
34 | + * @param egressIdString string for id of egress device | ||
35 | + * @return PointToPointIntent for the two devices | ||
36 | + */ | ||
37 | + private PointToPointIntent makeIntent(String ingressIdString, | ||
38 | + String egressIdString) { | ||
39 | + return new PointToPointIntent(new IntentId(12), | ||
40 | + selector, | ||
41 | + treatment, | ||
42 | + connectPoint(ingressIdString, 1), | ||
43 | + connectPoint(egressIdString, 1)); | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * Creates a compiler for HostToHost intents. | ||
48 | + * | ||
49 | + * @param hops string array describing the path hops to use when compiling | ||
50 | + * @return HostToHost intent compiler | ||
51 | + */ | ||
52 | + private PointToPointIntentCompiler makeCompiler(String[] hops) { | ||
53 | + PointToPointIntentCompiler compiler = | ||
54 | + new PointToPointIntentCompiler(); | ||
55 | + compiler.pathService = new IntentTestsMocks.MockPathService(hops); | ||
56 | + IdBlockAllocator idBlockAllocator = new DummyIdBlockAllocator(); | ||
57 | + compiler.intentIdGenerator = | ||
58 | + new IdBlockAllocatorBasedIntentIdGenerator(idBlockAllocator); | ||
59 | + return compiler; | ||
60 | + } | ||
61 | + | ||
62 | + | ||
63 | + /** | ||
64 | + * Tests a pair of devices in an 8 hop path, forward direction. | ||
65 | + */ | ||
66 | + @Test | ||
67 | + public void testForwardPathCompilation() { | ||
68 | + | ||
69 | + PointToPointIntent intent = makeIntent("d1", "d8"); | ||
70 | + assertThat(intent, is(notNullValue())); | ||
71 | + | ||
72 | + String[] hops = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8"}; | ||
73 | + PointToPointIntentCompiler compiler = makeCompiler(hops); | ||
74 | + assertThat(compiler, is(notNullValue())); | ||
75 | + | ||
76 | + List<Intent> result = compiler.compile(intent); | ||
77 | + assertThat(result, is(Matchers.notNullValue())); | ||
78 | + assertThat(result, hasSize(1)); | ||
79 | + Intent forwardResultIntent = result.get(0); | ||
80 | + assertThat(forwardResultIntent instanceof PathIntent, is(true)); | ||
81 | + | ||
82 | + if (forwardResultIntent instanceof PathIntent) { | ||
83 | + PathIntent forwardPathIntent = (PathIntent) forwardResultIntent; | ||
84 | + // 7 links for the hops, plus one default lnk on ingress and egress | ||
85 | + assertThat(forwardPathIntent.path().links(), hasSize(hops.length + 1)); | ||
86 | + assertThat(forwardPathIntent.path().links(), linksHasPath("d1", "d2")); | ||
87 | + assertThat(forwardPathIntent.path().links(), linksHasPath("d2", "d3")); | ||
88 | + assertThat(forwardPathIntent.path().links(), linksHasPath("d3", "d4")); | ||
89 | + assertThat(forwardPathIntent.path().links(), linksHasPath("d4", "d5")); | ||
90 | + assertThat(forwardPathIntent.path().links(), linksHasPath("d5", "d6")); | ||
91 | + assertThat(forwardPathIntent.path().links(), linksHasPath("d6", "d7")); | ||
92 | + assertThat(forwardPathIntent.path().links(), linksHasPath("d7", "d8")); | ||
93 | + } | ||
94 | + } | ||
95 | + | ||
96 | + /** | ||
97 | + * Tests a pair of devices in an 8 hop path, forward direction. | ||
98 | + */ | ||
99 | + @Test | ||
100 | + public void testReversePathCompilation() { | ||
101 | + | ||
102 | + PointToPointIntent intent = makeIntent("d8", "d1"); | ||
103 | + assertThat(intent, is(notNullValue())); | ||
104 | + | ||
105 | + String[] hops = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8"}; | ||
106 | + PointToPointIntentCompiler compiler = makeCompiler(hops); | ||
107 | + assertThat(compiler, is(notNullValue())); | ||
108 | + | ||
109 | + List<Intent> result = compiler.compile(intent); | ||
110 | + assertThat(result, is(Matchers.notNullValue())); | ||
111 | + assertThat(result, hasSize(1)); | ||
112 | + Intent reverseResultIntent = result.get(0); | ||
113 | + assertThat(reverseResultIntent instanceof PathIntent, is(true)); | ||
114 | + | ||
115 | + if (reverseResultIntent instanceof PathIntent) { | ||
116 | + PathIntent reversePathIntent = (PathIntent) reverseResultIntent; | ||
117 | + assertThat(reversePathIntent.path().links(), hasSize(hops.length + 1)); | ||
118 | + assertThat(reversePathIntent.path().links(), linksHasPath("d2", "d1")); | ||
119 | + assertThat(reversePathIntent.path().links(), linksHasPath("d3", "d2")); | ||
120 | + assertThat(reversePathIntent.path().links(), linksHasPath("d4", "d3")); | ||
121 | + assertThat(reversePathIntent.path().links(), linksHasPath("d5", "d4")); | ||
122 | + assertThat(reversePathIntent.path().links(), linksHasPath("d6", "d5")); | ||
123 | + assertThat(reversePathIntent.path().links(), linksHasPath("d7", "d6")); | ||
124 | + assertThat(reversePathIntent.path().links(), linksHasPath("d8", "d7")); | ||
125 | + } | ||
126 | + } | ||
127 | +} |
... | @@ -19,21 +19,10 @@ | ... | @@ -19,21 +19,10 @@ |
19 | <dependencies> | 19 | <dependencies> |
20 | <dependency> | 20 | <dependency> |
21 | <groupId>org.onlab.onos</groupId> | 21 | <groupId>org.onlab.onos</groupId> |
22 | - <artifactId>onos-api</artifactId> | ||
23 | - </dependency> | ||
24 | - <dependency> | ||
25 | - <groupId>org.onlab.onos</groupId> | ||
26 | <artifactId>onos-core-serializers</artifactId> | 22 | <artifactId>onos-core-serializers</artifactId> |
27 | <version>${project.version}</version> | 23 | <version>${project.version}</version> |
28 | </dependency> | 24 | </dependency> |
29 | 25 | ||
30 | - | ||
31 | - <dependency> | ||
32 | - <groupId>org.onlab.onos</groupId> | ||
33 | - <artifactId>onlab-nio</artifactId> | ||
34 | - <version>${project.version}</version> | ||
35 | - </dependency> | ||
36 | - | ||
37 | <dependency> | 26 | <dependency> |
38 | <groupId>org.onlab.onos</groupId> | 27 | <groupId>org.onlab.onos</groupId> |
39 | <artifactId>onlab-netty</artifactId> | 28 | <artifactId>onlab-netty</artifactId> |
... | @@ -50,10 +39,6 @@ | ... | @@ -50,10 +39,6 @@ |
50 | </dependency> | 39 | </dependency> |
51 | 40 | ||
52 | <dependency> | 41 | <dependency> |
53 | - <groupId>org.apache.felix</groupId> | ||
54 | - <artifactId>org.apache.felix.scr.annotations</artifactId> | ||
55 | - </dependency> | ||
56 | - <dependency> | ||
57 | <groupId>com.google.guava</groupId> | 42 | <groupId>com.google.guava</groupId> |
58 | <artifactId>guava-testlib</artifactId> | 43 | <artifactId>guava-testlib</artifactId> |
59 | <scope>test</scope> | 44 | <scope>test</scope> |
... | @@ -67,15 +52,12 @@ | ... | @@ -67,15 +52,12 @@ |
67 | <artifactId>easymock</artifactId> | 52 | <artifactId>easymock</artifactId> |
68 | <scope>test</scope> | 53 | <scope>test</scope> |
69 | </dependency> | 54 | </dependency> |
55 | + <dependency> | ||
56 | + <groupId>org.onlab.onos</groupId> | ||
57 | + <artifactId>onos-api</artifactId> | ||
58 | + <classifier>tests</classifier> | ||
59 | + <scope>test</scope> | ||
60 | + </dependency> | ||
70 | </dependencies> | 61 | </dependencies> |
71 | 62 | ||
72 | - <build> | ||
73 | - <plugins> | ||
74 | - <plugin> | ||
75 | - <groupId>org.apache.felix</groupId> | ||
76 | - <artifactId>maven-scr-plugin</artifactId> | ||
77 | - </plugin> | ||
78 | - </plugins> | ||
79 | - </build> | ||
80 | - | ||
81 | </project> | 63 | </project> | ... | ... |
... | @@ -4,6 +4,9 @@ import static com.google.common.base.Preconditions.checkArgument; | ... | @@ -4,6 +4,9 @@ import static com.google.common.base.Preconditions.checkArgument; |
4 | 4 | ||
5 | import java.io.IOException; | 5 | import java.io.IOException; |
6 | import java.util.Set; | 6 | import java.util.Set; |
7 | +import java.util.concurrent.TimeUnit; | ||
8 | +import java.util.concurrent.TimeoutException; | ||
9 | + | ||
7 | import org.apache.felix.scr.annotations.Activate; | 10 | import org.apache.felix.scr.annotations.Activate; |
8 | import org.apache.felix.scr.annotations.Component; | 11 | import org.apache.felix.scr.annotations.Component; |
9 | import org.apache.felix.scr.annotations.Deactivate; | 12 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -17,6 +20,7 @@ import org.onlab.onos.store.cluster.impl.ClusterMembershipEvent; | ... | @@ -17,6 +20,7 @@ import org.onlab.onos.store.cluster.impl.ClusterMembershipEvent; |
17 | import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; | 20 | import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; |
18 | import org.onlab.onos.store.cluster.messaging.ClusterMessage; | 21 | import org.onlab.onos.store.cluster.messaging.ClusterMessage; |
19 | import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; | 22 | import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; |
23 | +import org.onlab.onos.store.cluster.messaging.ClusterMessageResponse; | ||
20 | import org.onlab.onos.store.cluster.messaging.MessageSubject; | 24 | import org.onlab.onos.store.cluster.messaging.MessageSubject; |
21 | import org.onlab.onos.store.serializers.ClusterMessageSerializer; | 25 | import org.onlab.onos.store.serializers.ClusterMessageSerializer; |
22 | import org.onlab.onos.store.serializers.KryoPoolUtil; | 26 | import org.onlab.onos.store.serializers.KryoPoolUtil; |
... | @@ -28,6 +32,7 @@ import org.onlab.netty.Message; | ... | @@ -28,6 +32,7 @@ import org.onlab.netty.Message; |
28 | import org.onlab.netty.MessageHandler; | 32 | import org.onlab.netty.MessageHandler; |
29 | import org.onlab.netty.MessagingService; | 33 | import org.onlab.netty.MessagingService; |
30 | import org.onlab.netty.NettyMessagingService; | 34 | import org.onlab.netty.NettyMessagingService; |
35 | +import org.onlab.netty.Response; | ||
31 | import org.slf4j.Logger; | 36 | import org.slf4j.Logger; |
32 | import org.slf4j.LoggerFactory; | 37 | import org.slf4j.LoggerFactory; |
33 | 38 | ||
... | @@ -114,7 +119,23 @@ public class ClusterCommunicationManager | ... | @@ -114,7 +119,23 @@ public class ClusterCommunicationManager |
114 | message.subject().value(), SERIALIZER.encode(message)); | 119 | message.subject().value(), SERIALIZER.encode(message)); |
115 | return true; | 120 | return true; |
116 | } catch (IOException e) { | 121 | } catch (IOException e) { |
117 | - log.error("Failed to send cluster message to nodeId: " + toNodeId, e); | 122 | + log.trace("Failed to send cluster message to nodeId: " + toNodeId, e); |
123 | + throw e; | ||
124 | + } | ||
125 | + } | ||
126 | + | ||
127 | + @Override | ||
128 | + public ClusterMessageResponse sendAndReceive(ClusterMessage message, NodeId toNodeId) throws IOException { | ||
129 | + ControllerNode node = clusterService.getNode(toNodeId); | ||
130 | + checkArgument(node != null, "Unknown nodeId: %s", toNodeId); | ||
131 | + Endpoint nodeEp = new Endpoint(node.ip().toString(), node.tcpPort()); | ||
132 | + try { | ||
133 | + Response responseFuture = | ||
134 | + messagingService.sendAndReceive(nodeEp, message.subject().value(), SERIALIZER.encode(message)); | ||
135 | + return new InternalClusterMessageResponse(toNodeId, responseFuture); | ||
136 | + | ||
137 | + } catch (IOException e) { | ||
138 | + log.error("Failed interaction with remote nodeId: " + toNodeId, e); | ||
118 | throw e; | 139 | throw e; |
119 | } | 140 | } |
120 | } | 141 | } |
... | @@ -137,11 +158,52 @@ public class ClusterCommunicationManager | ... | @@ -137,11 +158,52 @@ public class ClusterCommunicationManager |
137 | public void handle(Message message) { | 158 | public void handle(Message message) { |
138 | try { | 159 | try { |
139 | ClusterMessage clusterMessage = SERIALIZER.decode(message.payload()); | 160 | ClusterMessage clusterMessage = SERIALIZER.decode(message.payload()); |
140 | - handler.handle(clusterMessage); | 161 | + handler.handle(new InternalClusterMessage(clusterMessage, message)); |
141 | } catch (Exception e) { | 162 | } catch (Exception e) { |
142 | log.error("Exception caught during ClusterMessageHandler", e); | 163 | log.error("Exception caught during ClusterMessageHandler", e); |
143 | throw e; | 164 | throw e; |
144 | } | 165 | } |
145 | } | 166 | } |
146 | } | 167 | } |
168 | + | ||
169 | + public static final class InternalClusterMessage extends ClusterMessage { | ||
170 | + | ||
171 | + private final Message rawMessage; | ||
172 | + | ||
173 | + public InternalClusterMessage(ClusterMessage clusterMessage, Message rawMessage) { | ||
174 | + super(clusterMessage.sender(), clusterMessage.subject(), clusterMessage.payload()); | ||
175 | + this.rawMessage = rawMessage; | ||
176 | + } | ||
177 | + | ||
178 | + @Override | ||
179 | + public void respond(byte[] response) throws IOException { | ||
180 | + rawMessage.respond(response); | ||
181 | + } | ||
182 | + } | ||
183 | + | ||
184 | + private static final class InternalClusterMessageResponse implements ClusterMessageResponse { | ||
185 | + | ||
186 | + private final NodeId sender; | ||
187 | + private final Response responseFuture; | ||
188 | + | ||
189 | + public InternalClusterMessageResponse(NodeId sender, Response responseFuture) { | ||
190 | + this.sender = sender; | ||
191 | + this.responseFuture = responseFuture; | ||
192 | + } | ||
193 | + @Override | ||
194 | + public NodeId sender() { | ||
195 | + return sender; | ||
196 | + } | ||
197 | + | ||
198 | + @Override | ||
199 | + public byte[] get(long timeout, TimeUnit timeunit) | ||
200 | + throws TimeoutException { | ||
201 | + return responseFuture.get(timeout, timeunit); | ||
202 | + } | ||
203 | + | ||
204 | + @Override | ||
205 | + public byte[] get(long timeout) throws InterruptedException { | ||
206 | + return responseFuture.get(); | ||
207 | + } | ||
208 | + } | ||
147 | } | 209 | } | ... | ... |
... | @@ -15,7 +15,7 @@ import org.onlab.onos.net.device.DefaultPortDescription; | ... | @@ -15,7 +15,7 @@ import org.onlab.onos.net.device.DefaultPortDescription; |
15 | import org.onlab.onos.net.device.DeviceDescription; | 15 | import org.onlab.onos.net.device.DeviceDescription; |
16 | import org.onlab.onos.net.device.PortDescription; | 16 | import org.onlab.onos.net.device.PortDescription; |
17 | import org.onlab.onos.store.Timestamp; | 17 | import org.onlab.onos.store.Timestamp; |
18 | -import org.onlab.onos.store.common.impl.Timestamped; | 18 | +import org.onlab.onos.store.impl.Timestamped; |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * Collection of Description of a Device and Ports, given from a Provider. | 21 | * Collection of Description of a Device and Ports, given from a Provider. | ... | ... |
... | @@ -38,9 +38,10 @@ import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; | ... | @@ -38,9 +38,10 @@ import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; |
38 | import org.onlab.onos.store.cluster.messaging.ClusterMessage; | 38 | import org.onlab.onos.store.cluster.messaging.ClusterMessage; |
39 | import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; | 39 | import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; |
40 | import org.onlab.onos.store.cluster.messaging.MessageSubject; | 40 | import org.onlab.onos.store.cluster.messaging.MessageSubject; |
41 | -import org.onlab.onos.store.common.impl.Timestamped; | 41 | +import org.onlab.onos.store.impl.Timestamped; |
42 | import org.onlab.onos.store.serializers.KryoSerializer; | 42 | import org.onlab.onos.store.serializers.KryoSerializer; |
43 | import org.onlab.onos.store.serializers.DistributedStoreSerializers; | 43 | import org.onlab.onos.store.serializers.DistributedStoreSerializers; |
44 | +import org.onlab.packet.ChassisId; | ||
44 | import org.onlab.util.KryoPool; | 45 | import org.onlab.util.KryoPool; |
45 | import org.onlab.util.NewConcurrentHashMap; | 46 | import org.onlab.util.NewConcurrentHashMap; |
46 | import org.slf4j.Logger; | 47 | import org.slf4j.Logger; |
... | @@ -746,6 +747,7 @@ public class GossipDeviceStore | ... | @@ -746,6 +747,7 @@ public class GossipDeviceStore |
746 | String hwVersion = base.hwVersion(); | 747 | String hwVersion = base.hwVersion(); |
747 | String swVersion = base.swVersion(); | 748 | String swVersion = base.swVersion(); |
748 | String serialNumber = base.serialNumber(); | 749 | String serialNumber = base.serialNumber(); |
750 | + ChassisId chassisId = base.chassisId(); | ||
749 | DefaultAnnotations annotations = DefaultAnnotations.builder().build(); | 751 | DefaultAnnotations annotations = DefaultAnnotations.builder().build(); |
750 | annotations = merge(annotations, base.annotations()); | 752 | annotations = merge(annotations, base.annotations()); |
751 | 753 | ||
... | @@ -763,7 +765,8 @@ public class GossipDeviceStore | ... | @@ -763,7 +765,8 @@ public class GossipDeviceStore |
763 | } | 765 | } |
764 | 766 | ||
765 | return new DefaultDevice(primary, deviceId , type, manufacturer, | 767 | return new DefaultDevice(primary, deviceId , type, manufacturer, |
766 | - hwVersion, swVersion, serialNumber, annotations); | 768 | + hwVersion, swVersion, serialNumber, |
769 | + chassisId, annotations); | ||
767 | } | 770 | } |
768 | 771 | ||
769 | /** | 772 | /** |
... | @@ -1137,7 +1140,7 @@ public class GossipDeviceStore | ... | @@ -1137,7 +1140,7 @@ public class GossipDeviceStore |
1137 | try { | 1140 | try { |
1138 | unicastMessage(peer, DEVICE_ADVERTISE, ad); | 1141 | unicastMessage(peer, DEVICE_ADVERTISE, ad); |
1139 | } catch (IOException e) { | 1142 | } catch (IOException e) { |
1140 | - log.error("Failed to send anti-entropy advertisement", e); | 1143 | + log.debug("Failed to send anti-entropy advertisement to {}", peer); |
1141 | return; | 1144 | return; |
1142 | } | 1145 | } |
1143 | } catch (Exception e) { | 1146 | } catch (Exception e) { | ... | ... |
core/store/dist/src/main/java/org/onlab/onos/store/device/impl/InitDeviceDescs.java
deleted
100644 → 0
1 | -package org.onlab.onos.store.device.impl; | ||
2 | - | ||
3 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
4 | - | ||
5 | -import org.apache.commons.lang3.concurrent.ConcurrentException; | ||
6 | -import org.apache.commons.lang3.concurrent.ConcurrentInitializer; | ||
7 | -import org.onlab.onos.net.device.DeviceDescription; | ||
8 | -import org.onlab.onos.store.common.impl.Timestamped; | ||
9 | - | ||
10 | -// FIXME: consider removing this class | ||
11 | -public final class InitDeviceDescs | ||
12 | - implements ConcurrentInitializer<DeviceDescriptions> { | ||
13 | - | ||
14 | - private final Timestamped<DeviceDescription> deviceDesc; | ||
15 | - | ||
16 | - public InitDeviceDescs(Timestamped<DeviceDescription> deviceDesc) { | ||
17 | - this.deviceDesc = checkNotNull(deviceDesc); | ||
18 | - } | ||
19 | - @Override | ||
20 | - public DeviceDescriptions get() throws ConcurrentException { | ||
21 | - return new DeviceDescriptions(deviceDesc); | ||
22 | - } | ||
23 | -} |
... | @@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl; | ... | @@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl; |
3 | import org.onlab.onos.net.DeviceId; | 3 | import org.onlab.onos.net.DeviceId; |
4 | import org.onlab.onos.net.device.DeviceDescription; | 4 | import org.onlab.onos.net.device.DeviceDescription; |
5 | import org.onlab.onos.net.provider.ProviderId; | 5 | import org.onlab.onos.net.provider.ProviderId; |
6 | -import org.onlab.onos.store.common.impl.Timestamped; | 6 | +import org.onlab.onos.store.impl.Timestamped; |
7 | 7 | ||
8 | import com.google.common.base.MoreObjects; | 8 | import com.google.common.base.MoreObjects; |
9 | 9 | ... | ... |
... | @@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl; | ... | @@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl; |
3 | import org.onlab.onos.net.DeviceId; | 3 | import org.onlab.onos.net.DeviceId; |
4 | import org.onlab.onos.net.device.DeviceDescription; | 4 | import org.onlab.onos.net.device.DeviceDescription; |
5 | import org.onlab.onos.net.provider.ProviderId; | 5 | import org.onlab.onos.net.provider.ProviderId; |
6 | -import org.onlab.onos.store.common.impl.Timestamped; | 6 | +import org.onlab.onos.store.impl.Timestamped; |
7 | 7 | ||
8 | import com.esotericsoftware.kryo.Kryo; | 8 | import com.esotericsoftware.kryo.Kryo; |
9 | import com.esotericsoftware.kryo.Serializer; | 9 | import com.esotericsoftware.kryo.Serializer; | ... | ... |
... | @@ -5,7 +5,7 @@ import java.util.List; | ... | @@ -5,7 +5,7 @@ import java.util.List; |
5 | import org.onlab.onos.net.DeviceId; | 5 | import org.onlab.onos.net.DeviceId; |
6 | import org.onlab.onos.net.device.PortDescription; | 6 | import org.onlab.onos.net.device.PortDescription; |
7 | import org.onlab.onos.net.provider.ProviderId; | 7 | import org.onlab.onos.net.provider.ProviderId; |
8 | -import org.onlab.onos.store.common.impl.Timestamped; | 8 | +import org.onlab.onos.store.impl.Timestamped; |
9 | 9 | ||
10 | import com.google.common.base.MoreObjects; | 10 | import com.google.common.base.MoreObjects; |
11 | 11 | ... | ... |
... | @@ -5,7 +5,7 @@ import java.util.List; | ... | @@ -5,7 +5,7 @@ import java.util.List; |
5 | import org.onlab.onos.net.DeviceId; | 5 | import org.onlab.onos.net.DeviceId; |
6 | import org.onlab.onos.net.device.PortDescription; | 6 | import org.onlab.onos.net.device.PortDescription; |
7 | import org.onlab.onos.net.provider.ProviderId; | 7 | import org.onlab.onos.net.provider.ProviderId; |
8 | -import org.onlab.onos.store.common.impl.Timestamped; | 8 | +import org.onlab.onos.store.impl.Timestamped; |
9 | 9 | ||
10 | import com.esotericsoftware.kryo.Kryo; | 10 | import com.esotericsoftware.kryo.Kryo; |
11 | import com.esotericsoftware.kryo.Serializer; | 11 | import com.esotericsoftware.kryo.Serializer; | ... | ... |
... | @@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl; | ... | @@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl; |
3 | import org.onlab.onos.net.DeviceId; | 3 | import org.onlab.onos.net.DeviceId; |
4 | import org.onlab.onos.net.device.PortDescription; | 4 | import org.onlab.onos.net.device.PortDescription; |
5 | import org.onlab.onos.net.provider.ProviderId; | 5 | import org.onlab.onos.net.provider.ProviderId; |
6 | -import org.onlab.onos.store.common.impl.Timestamped; | 6 | +import org.onlab.onos.store.impl.Timestamped; |
7 | 7 | ||
8 | import com.google.common.base.MoreObjects; | 8 | import com.google.common.base.MoreObjects; |
9 | 9 | ... | ... |
... | @@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl; | ... | @@ -3,7 +3,7 @@ package org.onlab.onos.store.device.impl; |
3 | import org.onlab.onos.net.DeviceId; | 3 | import org.onlab.onos.net.DeviceId; |
4 | import org.onlab.onos.net.device.PortDescription; | 4 | import org.onlab.onos.net.device.PortDescription; |
5 | import org.onlab.onos.net.provider.ProviderId; | 5 | import org.onlab.onos.net.provider.ProviderId; |
6 | -import org.onlab.onos.store.common.impl.Timestamped; | 6 | +import org.onlab.onos.store.impl.Timestamped; |
7 | 7 | ||
8 | import com.esotericsoftware.kryo.Kryo; | 8 | import com.esotericsoftware.kryo.Kryo; |
9 | import com.esotericsoftware.kryo.Serializer; | 9 | import com.esotericsoftware.kryo.Serializer; | ... | ... |
1 | +package org.onlab.onos.store.flow; | ||
2 | + | ||
3 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
4 | + | ||
5 | +import java.util.Collection; | ||
6 | +import java.util.Collections; | ||
7 | + | ||
8 | +import org.onlab.onos.cluster.NodeId; | ||
9 | + | ||
10 | +import com.google.common.base.Optional; | ||
11 | + | ||
12 | +/** | ||
13 | + * Class to represent placement information about Master/Backup copy. | ||
14 | + */ | ||
15 | +public final class ReplicaInfo { | ||
16 | + | ||
17 | + private final Optional<NodeId> master; | ||
18 | + private final Collection<NodeId> backups; | ||
19 | + | ||
20 | + /** | ||
21 | + * Creates a ReplicaInfo instance. | ||
22 | + * | ||
23 | + * @param master NodeId of the node where the master copy should be | ||
24 | + * @param backups collection of NodeId, where backup copies should be placed | ||
25 | + */ | ||
26 | + public ReplicaInfo(NodeId master, Collection<NodeId> backups) { | ||
27 | + this.master = Optional.fromNullable(master); | ||
28 | + this.backups = checkNotNull(backups); | ||
29 | + } | ||
30 | + | ||
31 | + /** | ||
32 | + * Returns the NodeId, if there is a Node where the master copy should be. | ||
33 | + * | ||
34 | + * @return NodeId, where the master copy should be placed | ||
35 | + */ | ||
36 | + public Optional<NodeId> master() { | ||
37 | + return master; | ||
38 | + } | ||
39 | + | ||
40 | + /** | ||
41 | + * Returns the collection of NodeId, where backup copies should be placed. | ||
42 | + * | ||
43 | + * @return collection of NodeId, where backup copies should be placed | ||
44 | + */ | ||
45 | + public Collection<NodeId> backups() { | ||
46 | + return backups; | ||
47 | + } | ||
48 | + | ||
49 | + // for Serializer | ||
50 | + private ReplicaInfo() { | ||
51 | + this.master = Optional.absent(); | ||
52 | + this.backups = Collections.emptyList(); | ||
53 | + } | ||
54 | +} |
1 | +package org.onlab.onos.store.flow; | ||
2 | + | ||
3 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
4 | + | ||
5 | +import org.onlab.onos.event.AbstractEvent; | ||
6 | +import org.onlab.onos.net.DeviceId; | ||
7 | + | ||
8 | +/** | ||
9 | + * Describes a device replicainfo event. | ||
10 | + */ | ||
11 | +public class ReplicaInfoEvent extends AbstractEvent<ReplicaInfoEvent.Type, DeviceId> { | ||
12 | + | ||
13 | + private final ReplicaInfo replicaInfo; | ||
14 | + | ||
15 | + /** | ||
16 | + * Types of Replica info event. | ||
17 | + */ | ||
18 | + public enum Type { | ||
19 | + /** | ||
20 | + * Event to notify that master placement should be changed. | ||
21 | + */ | ||
22 | + MASTER_CHANGED, | ||
23 | + // | ||
24 | + // BACKUPS_CHANGED? | ||
25 | + } | ||
26 | + | ||
27 | + | ||
28 | + /** | ||
29 | + * Creates an event of a given type and for the specified device, | ||
30 | + * and replica info. | ||
31 | + * | ||
32 | + * @param type replicainfo event type | ||
33 | + * @param device event device subject | ||
34 | + * @param replicaInfo replicainfo | ||
35 | + */ | ||
36 | + public ReplicaInfoEvent(Type type, DeviceId device, ReplicaInfo replicaInfo) { | ||
37 | + super(type, device); | ||
38 | + this.replicaInfo = checkNotNull(replicaInfo); | ||
39 | + } | ||
40 | + | ||
41 | + /** | ||
42 | + * Returns the current replica information for the subject. | ||
43 | + * | ||
44 | + * @return replica information for the subject | ||
45 | + */ | ||
46 | + public ReplicaInfo replicaInfo() { | ||
47 | + return replicaInfo; | ||
48 | + }; | ||
49 | +} |
1 | +package org.onlab.onos.store.flow; | ||
2 | + | ||
3 | +import org.onlab.onos.net.DeviceId; | ||
4 | + | ||
5 | +/** | ||
6 | + * Service to return where the replica should be placed. | ||
7 | + */ | ||
8 | +public interface ReplicaInfoService { | ||
9 | + | ||
10 | + // returns where it should be. | ||
11 | + /** | ||
12 | + * Returns the placement information for given Device. | ||
13 | + * | ||
14 | + * @param deviceId identifier of the device | ||
15 | + * @return placement information | ||
16 | + */ | ||
17 | + ReplicaInfo getReplicaInfoFor(DeviceId deviceId); | ||
18 | + | ||
19 | + /** | ||
20 | + * Adds the specified replica placement info change listener. | ||
21 | + * | ||
22 | + * @param listener the replica placement info change listener | ||
23 | + */ | ||
24 | + void addListener(ReplicaInfoEventListener listener); | ||
25 | + | ||
26 | + /** | ||
27 | + * Removes the specified replica placement info change listener. | ||
28 | + * | ||
29 | + * @param listener the replica placement info change listener | ||
30 | + */ | ||
31 | + void removeListener(ReplicaInfoEventListener listener); | ||
32 | + | ||
33 | +} |
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.
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.
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.
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.
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.
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.
-
Please register or login to post a comment