Ayaka Koshibe

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

Showing 162 changed files with 3767 additions and 185 deletions
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 +/**
2 + * Application providing integration between OSCARS and ONOS intent
3 + * framework via REST API.
4 + */
5 +package org.onlab.onos.calendar;
...\ No newline at end of file ...\ No newline at end of file
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
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>
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>
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 +}
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 }
......
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() {
......
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>
1 +package org.onlab.onos.json.impl;
2 +
3 +/**
4 + * Created by tom on 10/16/14.
5 + */
6 +public class DeleteMe {
7 +}
1 +/**
2 + * Implementation of JSON codec factory and of the builtin codecs.
3 + */
4 +package org.onlab.onos.json.impl;
...\ No newline at end of file ...\ No newline at end of file
...@@ -36,26 +36,9 @@ ...@@ -36,26 +36,9 @@
36 <scope>test</scope> 36 <scope>test</scope>
37 </dependency> 37 </dependency>
38 38
39 - <dependency>
40 - <groupId>org.easymock</groupId>
41 - <artifactId>easymock</artifactId>
42 - <scope>test</scope>
43 - </dependency>
44 -
45 - <!-- TODO Consider removing store dependency.
46 - Currently required for DistributedDeviceManagerTest. -->
47 <dependency> 39 <dependency>
48 - <groupId>org.onlab.onos</groupId> 40 + <groupId>org.easymock</groupId>
49 - <artifactId>onos-core-hz-net</artifactId> 41 + <artifactId>easymock</artifactId>
50 - <version>${project.version}</version>
51 - <scope>test</scope>
52 - </dependency>
53 - <dependency>
54 - <groupId>org.onlab.onos</groupId>
55 - <!-- FIXME: should be somewhere else -->
56 - <artifactId>onos-core-hz-common</artifactId>
57 - <version>${project.version}</version>
58 - <classifier>tests</classifier>
59 <scope>test</scope> 42 <scope>test</scope>
60 </dependency> 43 </dependency>
61 44
......
...@@ -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 +}
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 +
24 - } 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);
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 + */
31 - } 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)));
32 } 62 }
33 63
64 + /**
65 + * Tests the equals() method where two LinkCollectionIntents have references
66 + * to different Links. These should compare not equal.
67 + */
34 @Test 68 @Test
35 - public void testComparison() { 69 + public void testLinksDifferentEquals() {
36 - TrafficSelector selector = new MockSelector(); 70 + links1.add(link1);
37 - TrafficTreatment treatment = new MockTreatment(); 71 + links1.add(link2);
38 - Set<Link> links = new HashSet<>(); 72 +
39 - LinkCollectionIntent i1 = new LinkCollectionIntent(new IntentId(12), 73 + links2.add(link3);
40 - selector, treatment, links); 74 + links2.add(link1);
41 - LinkCollectionIntent i2 = new LinkCollectionIntent(new IntentId(12),
42 - selector, treatment, links);
43 75
44 - assertThat(i1.equals(i2), is(true)); 76 + LinkCollectionIntent i1 = makeLinkCollection(12, links1);
77 + LinkCollectionIntent i2 = makeLinkCollection(12, links2);
78 +
79 + assertThat(i1, is(not(equalTo(i2))));
45 } 80 }
46 81
82 + /**
83 + * Tests the equals() method where two LinkCollectionIntents have different
84 + * ids. These should compare not equal.
85 + */
86 + @Test
87 + public void testBaseDifferentEquals() {
88 + links1.add(link1);
89 + links1.add(link2);
90 +
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())));
118 + }
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 +}
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 +}
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 +}
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
20 <module>api</module> 20 <module>api</module>
21 <module>net</module> 21 <module>net</module>
22 <module>store</module> 22 <module>store</module>
23 + <module>json</module>
23 </modules> 24 </modules>
24 25
25 <dependencies> 26 <dependencies>
......
...@@ -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 }
......
1 -/**
2 - * Common abstractions and facilities for implementing distributed store
3 - * using gossip protocol.
4 - */
5 -package org.onlab.onos.store.common.impl;
...@@ -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) {
......
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 /** 1 /**
2 - * Implementation of device store using distributed distributed p2p synchronization protocol. 2 + * Implementation of distributed device store using p2p synchronization protocol.
3 */ 3 */
4 package org.onlab.onos.store.device.impl; 4 package org.onlab.onos.store.device.impl;
......
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.event.EventListener;
4 +
5 +/**
6 + * Entity capable of receiving Replica placement information-related events.
7 + */
8 +public interface ReplicaInfoEventListener extends EventListener<ReplicaInfoEvent> {
9 +
10 +}
11 +
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.
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.