Ayaka Koshibe

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

Showing 147 changed files with 1934 additions and 825 deletions
...@@ -18,18 +18,20 @@ ...@@ -18,18 +18,20 @@
18 18
19 <dependencies> 19 <dependencies>
20 <dependency> 20 <dependency>
21 - <groupId>org.codehaus.jackson</groupId> 21 + <groupId>org.codehaus.jackson</groupId>
22 - <artifactId>jackson-core-asl</artifactId> 22 + <artifactId>jackson-core-asl</artifactId>
23 </dependency> 23 </dependency>
24 <dependency> 24 <dependency>
25 - <groupId>org.codehaus.jackson</groupId> 25 + <groupId>org.codehaus.jackson</groupId>
26 - <artifactId>jackson-mapper-asl</artifactId> 26 + <artifactId>jackson-mapper-asl</artifactId>
27 </dependency> 27 </dependency>
28 <dependency> 28 <dependency>
29 <groupId>com.fasterxml.jackson.core</groupId> 29 <groupId>com.fasterxml.jackson.core</groupId>
30 <artifactId>jackson-annotations</artifactId> 30 <artifactId>jackson-annotations</artifactId>
31 - <version>2.4.2</version> 31 + </dependency>
32 - <scope>provided</scope> 32 + <dependency>
33 + <groupId>org.onlab.onos</groupId>
34 + <artifactId>onlab-misc</artifactId>
33 </dependency> 35 </dependency>
34 </dependencies> 36 </dependencies>
35 37
......
...@@ -41,5 +41,17 @@ ...@@ -41,5 +41,17 @@
41 <groupId>org.apache.karaf.shell</groupId> 41 <groupId>org.apache.karaf.shell</groupId>
42 <artifactId>org.apache.karaf.shell.console</artifactId> 42 <artifactId>org.apache.karaf.shell.console</artifactId>
43 </dependency> 43 </dependency>
44 + <dependency>
45 + <groupId>org.onlab.onos</groupId>
46 + <artifactId>onlab-misc</artifactId>
47 + </dependency>
48 + <dependency>
49 + <groupId>com.google.guava</groupId>
50 + <artifactId>guava</artifactId>
51 + </dependency>
52 + <dependency>
53 + <groupId>org.osgi</groupId>
54 + <artifactId>org.osgi.core</artifactId>
55 + </dependency>
44 </dependencies> 56 </dependencies>
45 </project> 57 </project>
......
...@@ -4,8 +4,6 @@ import java.io.IOException; ...@@ -4,8 +4,6 @@ import java.io.IOException;
4 4
5 import org.onlab.netty.Message; 5 import org.onlab.netty.Message;
6 import org.onlab.netty.MessageHandler; 6 import org.onlab.netty.MessageHandler;
7 -import org.slf4j.Logger;
8 -import org.slf4j.LoggerFactory;
9 7
10 8
11 /** 9 /**
...@@ -13,11 +11,8 @@ import org.slf4j.LoggerFactory; ...@@ -13,11 +11,8 @@ import org.slf4j.LoggerFactory;
13 */ 11 */
14 public class NettyEchoHandler implements MessageHandler { 12 public class NettyEchoHandler implements MessageHandler {
15 13
16 - private final Logger log = LoggerFactory.getLogger(getClass());
17 -
18 @Override 14 @Override
19 public void handle(Message message) throws IOException { 15 public void handle(Message message) throws IOException {
20 - //log.info("Received message. Echoing it back to the sender.");
21 message.respond(message.payload()); 16 message.respond(message.payload());
22 } 17 }
23 } 18 }
......
...@@ -8,12 +8,12 @@ import org.slf4j.LoggerFactory; ...@@ -8,12 +8,12 @@ import org.slf4j.LoggerFactory;
8 /** 8 /**
9 * A MessageHandler that simply logs the information. 9 * A MessageHandler that simply logs the information.
10 */ 10 */
11 -public class NettyLoggingHandler implements MessageHandler { 11 +public class NettyNothingHandler implements MessageHandler {
12 12
13 private final Logger log = LoggerFactory.getLogger(getClass()); 13 private final Logger log = LoggerFactory.getLogger(getClass());
14 14
15 @Override 15 @Override
16 public void handle(Message message) { 16 public void handle(Message message) {
17 - //log.info("Received message. Payload has {} bytes", message.payload().length); 17 + // Do nothing
18 } 18 }
19 } 19 }
......
1 package org.onlab.onos.foo; 1 package org.onlab.onos.foo;
2 2
3 +import static java.lang.Thread.sleep;
4 +
3 import java.io.IOException; 5 import java.io.IOException;
4 import java.util.concurrent.ExecutionException; 6 import java.util.concurrent.ExecutionException;
7 +import java.util.concurrent.TimeUnit;
5 import java.util.concurrent.TimeoutException; 8 import java.util.concurrent.TimeoutException;
6 9
7 import org.onlab.metrics.MetricsComponent; 10 import org.onlab.metrics.MetricsComponent;
...@@ -15,14 +18,29 @@ import org.slf4j.LoggerFactory; ...@@ -15,14 +18,29 @@ import org.slf4j.LoggerFactory;
15 18
16 import com.codahale.metrics.Timer; 19 import com.codahale.metrics.Timer;
17 20
21 +/**
22 + * The Simple netty client test.
23 + */
18 // FIXME: Should be move out to test or app 24 // FIXME: Should be move out to test or app
19 public final class SimpleNettyClient { 25 public final class SimpleNettyClient {
20 26
21 private static Logger log = LoggerFactory.getLogger(SimpleNettyClient.class); 27 private static Logger log = LoggerFactory.getLogger(SimpleNettyClient.class);
22 28
29 + static NettyMessagingService messaging;
30 + static MetricsManager metrics;
31 +
23 private SimpleNettyClient() { 32 private SimpleNettyClient() {
24 } 33 }
25 34
35 + /**
36 + * The entry point of application.
37 + *
38 + * @param args the input arguments
39 + * @throws IOException the iO exception
40 + * @throws InterruptedException the interrupted exception
41 + * @throws ExecutionException the execution exception
42 + * @throws TimeoutException the timeout exception
43 + */
26 public static void main(String[] args) 44 public static void main(String[] args)
27 throws IOException, InterruptedException, ExecutionException, 45 throws IOException, InterruptedException, ExecutionException,
28 TimeoutException { 46 TimeoutException {
...@@ -34,48 +52,87 @@ private static Logger log = LoggerFactory.getLogger(SimpleNettyClient.class); ...@@ -34,48 +52,87 @@ private static Logger log = LoggerFactory.getLogger(SimpleNettyClient.class);
34 52
35 System.exit(0); 53 System.exit(0);
36 } 54 }
37 - public static void startStandalone(String... args) throws Exception { 55 +
56 + /**
57 + * Start standalone.
58 + *
59 + * @param args the args
60 + * @throws Exception the exception
61 + */
62 + public static void startStandalone(String[] args) throws Exception {
38 String host = args.length > 0 ? args[0] : "localhost"; 63 String host = args.length > 0 ? args[0] : "localhost";
39 int port = args.length > 1 ? Integer.parseInt(args[1]) : 8081; 64 int port = args.length > 1 ? Integer.parseInt(args[1]) : 8081;
40 int warmup = args.length > 2 ? Integer.parseInt(args[2]) : 1000; 65 int warmup = args.length > 2 ? Integer.parseInt(args[2]) : 1000;
41 int iterations = args.length > 3 ? Integer.parseInt(args[3]) : 50 * 100000; 66 int iterations = args.length > 3 ? Integer.parseInt(args[3]) : 50 * 100000;
42 - NettyMessagingService messaging = new TestNettyMessagingService(9081); 67 + messaging = new TestNettyMessagingService(9081);
43 - MetricsManager metrics = new MetricsManager(); 68 + metrics = new MetricsManager();
44 Endpoint endpoint = new Endpoint(host, port); 69 Endpoint endpoint = new Endpoint(host, port);
45 messaging.activate(); 70 messaging.activate();
46 metrics.activate(); 71 metrics.activate();
47 MetricsFeature feature = new MetricsFeature("latency"); 72 MetricsFeature feature = new MetricsFeature("latency");
48 MetricsComponent component = metrics.registerComponent("NettyMessaging"); 73 MetricsComponent component = metrics.registerComponent("NettyMessaging");
49 - log.info("warmup...."); 74 + log.info("connecting " + host + ":" + port + " warmup:" + warmup + " iterations:" + iterations);
50 75
51 for (int i = 0; i < warmup; i++) { 76 for (int i = 0; i < warmup; i++) {
52 messaging.sendAsync(endpoint, "simple", "Hello World".getBytes()); 77 messaging.sendAsync(endpoint, "simple", "Hello World".getBytes());
53 Response response = messaging 78 Response response = messaging
54 .sendAndReceive(endpoint, "echo", 79 .sendAndReceive(endpoint, "echo",
55 "Hello World".getBytes()); 80 "Hello World".getBytes());
81 + response.get(100000, TimeUnit.MILLISECONDS);
82 + }
83 +
84 + log.info("measuring round-trip send & receive");
85 + Timer sendAndReceiveTimer = metrics.createTimer(component, feature, "SendAndReceive");
86 + int timeouts = 0;
87 +
88 + for (int i = 0; i < iterations; i++) {
89 + Response response;
90 + Timer.Context context = sendAndReceiveTimer.time();
91 + try {
92 + response = messaging
93 + .sendAndReceive(endpoint, "echo",
94 + "Hello World".getBytes());
95 + response.get(10000, TimeUnit.MILLISECONDS);
96 + } catch (TimeoutException e) {
97 + timeouts++;
98 + log.info("timeout:" + timeouts + " at iteration:" + i);
99 + } finally {
100 + context.stop();
101 + }
102 + // System.out.println("Got back:" + new String(response.get(2, TimeUnit.SECONDS)));
56 } 103 }
57 104
105 + //sleep(1000);
58 log.info("measuring async sender"); 106 log.info("measuring async sender");
59 Timer sendAsyncTimer = metrics.createTimer(component, feature, "AsyncSender"); 107 Timer sendAsyncTimer = metrics.createTimer(component, feature, "AsyncSender");
60 108
61 for (int i = 0; i < iterations; i++) { 109 for (int i = 0; i < iterations; i++) {
62 - Timer.Context context = sendAsyncTimer.time(); 110 + Timer.Context context = sendAsyncTimer.time();
63 - messaging.sendAsync(endpoint, "simple", "Hello World".getBytes()); 111 + messaging.sendAsync(endpoint, "simple", "Hello World".getBytes());
64 - context.stop(); 112 + context.stop();
65 } 113 }
114 + sleep(10000);
115 + }
66 116
67 - Timer sendAndReceiveTimer = metrics.createTimer(component, feature, "SendAndReceive"); 117 + public static void stop() {
68 - for (int i = 0; i < iterations; i++) { 118 + try {
69 - Timer.Context context = sendAndReceiveTimer.time(); 119 + messaging.deactivate();
70 - Response response = messaging 120 + metrics.deactivate();
71 - .sendAndReceive(endpoint, "echo", 121 + } catch (Exception e) {
72 - "Hello World".getBytes()); 122 + log.info("Unable to stop client %s", e);
73 - // System.out.println("Got back:" + new String(response.get(2, TimeUnit.SECONDS)));
74 - context.stop();
75 } 123 }
76 } 124 }
77 125
126 + /**
127 + * The type Test netty messaging service.
128 + */
78 public static class TestNettyMessagingService extends NettyMessagingService { 129 public static class TestNettyMessagingService extends NettyMessagingService {
130 + /**
131 + * Instantiates a new Test netty messaging service.
132 + *
133 + * @param port the port
134 + * @throws Exception the exception
135 + */
79 public TestNettyMessagingService(int port) throws Exception { 136 public TestNettyMessagingService(int port) throws Exception {
80 super(port); 137 super(port);
81 } 138 }
......
1 package org.onlab.onos.foo; 1 package org.onlab.onos.foo;
2 2
3 import static org.onlab.onos.foo.SimpleNettyClient.startStandalone; 3 import static org.onlab.onos.foo.SimpleNettyClient.startStandalone;
4 +import static org.onlab.onos.foo.SimpleNettyClient.stop;
4 5
5 import org.apache.karaf.shell.commands.Argument; 6 import org.apache.karaf.shell.commands.Argument;
6 import org.apache.karaf.shell.commands.Command; 7 import org.apache.karaf.shell.commands.Command;
...@@ -10,7 +11,7 @@ import org.onlab.onos.cli.AbstractShellCommand; ...@@ -10,7 +11,7 @@ import org.onlab.onos.cli.AbstractShellCommand;
10 * Test Netty client performance. 11 * Test Netty client performance.
11 */ 12 */
12 @Command(scope = "onos", name = "simple-netty-client", 13 @Command(scope = "onos", name = "simple-netty-client",
13 - description = "Starts the simple Netty client") 14 + description = "Starts simple Netty client")
14 public class SimpleNettyClientCommand extends AbstractShellCommand { 15 public class SimpleNettyClientCommand extends AbstractShellCommand {
15 16
16 //FIXME: replace these arguments with proper ones needed for the test. 17 //FIXME: replace these arguments with proper ones needed for the test.
...@@ -18,17 +19,17 @@ public class SimpleNettyClientCommand extends AbstractShellCommand { ...@@ -18,17 +19,17 @@ public class SimpleNettyClientCommand extends AbstractShellCommand {
18 required = false, multiValued = false) 19 required = false, multiValued = false)
19 String hostname = "localhost"; 20 String hostname = "localhost";
20 21
21 - @Argument(index = 3, name = "port", description = "Port", 22 + @Argument(index = 1, name = "port", description = "Port",
22 required = false, multiValued = false) 23 required = false, multiValued = false)
23 String port = "8081"; 24 String port = "8081";
24 25
25 - @Argument(index = 1, name = "warmupCount", description = "Warm-up count", 26 + @Argument(index = 2, name = "warmupCount", description = "Warm-up count",
26 required = false, multiValued = false) 27 required = false, multiValued = false)
27 String warmupCount = "1000"; 28 String warmupCount = "1000";
28 29
29 - @Argument(index = 2, name = "messageCount", description = "Message count", 30 + @Argument(index = 3, name = "messageCount", description = "Message count",
30 required = false, multiValued = false) 31 required = false, multiValued = false)
31 - String messageCount = "100000"; 32 + String messageCount = "1000000";
32 33
33 @Override 34 @Override
34 protected void execute() { 35 protected void execute() {
...@@ -37,5 +38,6 @@ public class SimpleNettyClientCommand extends AbstractShellCommand { ...@@ -37,5 +38,6 @@ public class SimpleNettyClientCommand extends AbstractShellCommand {
37 } catch (Exception e) { 38 } catch (Exception e) {
38 error("Unable to start client %s", e); 39 error("Unable to start client %s", e);
39 } 40 }
41 + stop();
40 } 42 }
41 } 43 }
......
...@@ -12,16 +12,30 @@ import org.slf4j.LoggerFactory; ...@@ -12,16 +12,30 @@ import org.slf4j.LoggerFactory;
12 12
13 private SimpleNettyServer() {} 13 private SimpleNettyServer() {}
14 14
15 - public static void main(String... args) throws Exception { 15 + /**
16 + * The entry point of application.
17 + *
18 + * @param args the input arguments
19 + * @throws Exception the exception
20 + */
21 + public static void main(String... args) throws Exception {
16 startStandalone(args); 22 startStandalone(args);
17 System.exit(0); 23 System.exit(0);
18 } 24 }
19 25
20 - public static void startStandalone(String[] args) throws Exception { 26 + /**
21 - NettyMessagingService server = new NettyMessagingService(8081); 27 + * Start standalone server.
28 + *
29 + * @param args the args
30 + * @throws Exception the exception
31 + */
32 + public static void startStandalone(String[] args) throws Exception {
33 + int port = args.length > 0 ? Integer.parseInt(args[0]) : 8081;
34 + NettyMessagingService server = new NettyMessagingService(port);
22 server.activate(); 35 server.activate();
23 - server.registerHandler("simple", new NettyLoggingHandler()); 36 + server.registerHandler("simple", new NettyNothingHandler());
24 server.registerHandler("echo", new NettyEchoHandler()); 37 server.registerHandler("echo", new NettyEchoHandler());
38 + log.info("Netty Server server on port " + port);
25 } 39 }
26 } 40 }
27 41
......
...@@ -10,26 +10,18 @@ import org.onlab.onos.cli.AbstractShellCommand; ...@@ -10,26 +10,18 @@ import org.onlab.onos.cli.AbstractShellCommand;
10 * Starts the Simple Netty server. 10 * Starts the Simple Netty server.
11 */ 11 */
12 @Command(scope = "onos", name = "simple-netty-server", 12 @Command(scope = "onos", name = "simple-netty-server",
13 - description = "Starts the simple netty server") 13 + description = "Starts simple Netty server")
14 public class SimpleNettyServerCommand extends AbstractShellCommand { 14 public class SimpleNettyServerCommand extends AbstractShellCommand {
15 15
16 //FIXME: Replace these with parameters for 16 //FIXME: Replace these with parameters for
17 - @Argument(index = 0, name = "serverIp", description = "Server IP address", 17 + @Argument(index = 0, name = "port", description = "listen port",
18 required = false, multiValued = false) 18 required = false, multiValued = false)
19 - String serverIp = "127.0.0.1"; 19 + String port = "8081";
20 -
21 - @Argument(index = 1, name = "workers", description = "IO workers",
22 - required = false, multiValued = false)
23 - String workers = "6";
24 -
25 - @Argument(index = 2, name = "messageLength", description = "Message length (bytes)",
26 - required = false, multiValued = false)
27 - String messageLength = "128";
28 20
29 @Override 21 @Override
30 protected void execute() { 22 protected void execute() {
31 try { 23 try {
32 - startStandalone(new String[]{serverIp, workers, messageLength}); 24 + startStandalone(new String[]{port});
33 } catch (Exception e) { 25 } catch (Exception e) {
34 error("Unable to start server %s", e); 26 error("Unable to start server %s", e);
35 } 27 }
......
...@@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.Deactivate;
10 import org.apache.felix.scr.annotations.Reference; 10 import org.apache.felix.scr.annotations.Reference;
11 import org.apache.felix.scr.annotations.ReferenceCardinality; 11 import org.apache.felix.scr.annotations.ReferenceCardinality;
12 import org.onlab.onos.ApplicationId; 12 import org.onlab.onos.ApplicationId;
13 +import org.onlab.onos.CoreService;
13 import org.onlab.onos.net.Host; 14 import org.onlab.onos.net.Host;
14 import org.onlab.onos.net.HostId; 15 import org.onlab.onos.net.HostId;
15 import org.onlab.onos.net.Path; 16 import org.onlab.onos.net.Path;
...@@ -53,13 +54,16 @@ public class ReactiveForwarding { ...@@ -53,13 +54,16 @@ public class ReactiveForwarding {
53 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 54 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 protected FlowRuleService flowRuleService; 55 protected FlowRuleService flowRuleService;
55 56
57 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 + protected CoreService coreService;
59 +
56 private ReactivePacketProcessor processor = new ReactivePacketProcessor(); 60 private ReactivePacketProcessor processor = new ReactivePacketProcessor();
57 61
58 private ApplicationId appId; 62 private ApplicationId appId;
59 63
60 @Activate 64 @Activate
61 public void activate() { 65 public void activate() {
62 - appId = ApplicationId.getAppId(); 66 + appId = coreService.registerApplication("org.onlab.onos.fwd");
63 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); 67 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
64 log.info("Started with Application ID {}", appId.id()); 68 log.info("Started with Application ID {}", appId.id());
65 } 69 }
...@@ -166,8 +170,6 @@ public class ReactiveForwarding { ...@@ -166,8 +170,6 @@ public class ReactiveForwarding {
166 // We don't yet support bufferids in the flowservice so packet out first. 170 // We don't yet support bufferids in the flowservice so packet out first.
167 packetOut(context, portNumber); 171 packetOut(context, portNumber);
168 172
169 -
170 -
171 // Install the flow rule to handle this type of message from now on. 173 // Install the flow rule to handle this type of message from now on.
172 Ethernet inPkt = context.inPacket().parsed(); 174 Ethernet inPkt = context.inPacket().parsed();
173 TrafficSelector.Builder builder = DefaultTrafficSelector.builder(); 175 TrafficSelector.Builder builder = DefaultTrafficSelector.builder();
......
...@@ -16,4 +16,14 @@ ...@@ -16,4 +16,14 @@
16 16
17 <description>ONOS simple Mobility app</description> 17 <description>ONOS simple Mobility app</description>
18 18
19 + <dependencies>
20 + <dependency>
21 + <groupId>com.google.guava</groupId>
22 + <artifactId>guava</artifactId>
23 + </dependency>
24 + <dependency>
25 + <groupId>org.onlab.onos</groupId>
26 + <artifactId>onlab-misc</artifactId>
27 + </dependency>
28 + </dependencies>
19 </project> 29 </project>
......
...@@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.Deactivate;
10 import org.apache.felix.scr.annotations.Reference; 10 import org.apache.felix.scr.annotations.Reference;
11 import org.apache.felix.scr.annotations.ReferenceCardinality; 11 import org.apache.felix.scr.annotations.ReferenceCardinality;
12 import org.onlab.onos.ApplicationId; 12 import org.onlab.onos.ApplicationId;
13 +import org.onlab.onos.CoreService;
13 import org.onlab.onos.net.Device; 14 import org.onlab.onos.net.Device;
14 import org.onlab.onos.net.Host; 15 import org.onlab.onos.net.Host;
15 import org.onlab.onos.net.device.DeviceService; 16 import org.onlab.onos.net.device.DeviceService;
...@@ -44,11 +45,14 @@ public class HostMobility { ...@@ -44,11 +45,14 @@ public class HostMobility {
44 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 45 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
45 protected DeviceService deviceService; 46 protected DeviceService deviceService;
46 47
48 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
49 + protected CoreService coreService;
50 +
47 private ApplicationId appId; 51 private ApplicationId appId;
48 52
49 @Activate 53 @Activate
50 public void activate() { 54 public void activate() {
51 - appId = ApplicationId.getAppId(); 55 + appId = coreService.registerApplication("org.onlab.onos.mobility");
52 hostService.addListener(new InternalHostListener()); 56 hostService.addListener(new InternalHostListener());
53 log.info("Started with Application ID {}", appId.id()); 57 log.info("Started with Application ID {}", appId.id());
54 } 58 }
......
...@@ -23,7 +23,8 @@ ...@@ -23,7 +23,8 @@
23 <module>foo</module> 23 <module>foo</module>
24 <module>mobility</module> 24 <module>mobility</module>
25 <module>proxyarp</module> 25 <module>proxyarp</module>
26 - <module>config</module> 26 + <module>config</module>
27 + <module>sdnip</module>
27 </modules> 28 </modules>
28 29
29 <properties> 30 <properties>
......
...@@ -8,6 +8,7 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -8,6 +8,7 @@ import org.apache.felix.scr.annotations.Deactivate;
8 import org.apache.felix.scr.annotations.Reference; 8 import org.apache.felix.scr.annotations.Reference;
9 import org.apache.felix.scr.annotations.ReferenceCardinality; 9 import org.apache.felix.scr.annotations.ReferenceCardinality;
10 import org.onlab.onos.ApplicationId; 10 import org.onlab.onos.ApplicationId;
11 +import org.onlab.onos.CoreService;
11 import org.onlab.onos.net.packet.PacketContext; 12 import org.onlab.onos.net.packet.PacketContext;
12 import org.onlab.onos.net.packet.PacketProcessor; 13 import org.onlab.onos.net.packet.PacketProcessor;
13 import org.onlab.onos.net.packet.PacketService; 14 import org.onlab.onos.net.packet.PacketService;
...@@ -31,11 +32,14 @@ public class ProxyArp { ...@@ -31,11 +32,14 @@ public class ProxyArp {
31 32
32 private ProxyArpProcessor processor = new ProxyArpProcessor(); 33 private ProxyArpProcessor processor = new ProxyArpProcessor();
33 34
35 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
36 + protected CoreService coreService;
37 +
34 private ApplicationId appId; 38 private ApplicationId appId;
35 39
36 @Activate 40 @Activate
37 public void activate() { 41 public void activate() {
38 - appId = ApplicationId.getAppId(); 42 + appId = coreService.registerApplication("org.onlab.onos.proxyarp");
39 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1); 43 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1);
40 log.info("Started with Application ID {}", appId.id()); 44 log.info("Started with Application ID {}", appId.id());
41 } 45 }
......
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-sdnip</artifactId>
15 + <packaging>bundle</packaging>
16 +
17 + <description>SDN-IP peering application</description>
18 +
19 + <dependencies>
20 + <dependency>
21 + <groupId>org.codehaus.jackson</groupId>
22 + <artifactId>jackson-core-asl</artifactId>
23 + </dependency>
24 + <dependency>
25 + <groupId>org.codehaus.jackson</groupId>
26 + <artifactId>jackson-mapper-asl</artifactId>
27 + </dependency>
28 + <dependency>
29 + <groupId>com.fasterxml.jackson.core</groupId>
30 + <artifactId>jackson-annotations</artifactId>
31 + <version>2.4.2</version>
32 + <scope>provided</scope>
33 + </dependency>
34 + </dependencies>
35 +
36 +</project>
1 +package org.onlab.onos.sdnip;
2 +
3 +import static org.slf4j.LoggerFactory.getLogger;
4 +
5 +import org.apache.felix.scr.annotations.Activate;
6 +import org.apache.felix.scr.annotations.Component;
7 +import org.apache.felix.scr.annotations.Deactivate;
8 +import org.slf4j.Logger;
9 +
10 +/**
11 + * Placeholder SDN-IP component.
12 + */
13 +@Component(immediate = true)
14 +public class SdnIp {
15 +
16 + private final Logger log = getLogger(getClass());
17 +
18 + @Activate
19 + protected void activate() {
20 + log.debug("SDN-IP started");
21 + }
22 +
23 + @Deactivate
24 + protected void deactivate() {
25 + log.info("Stopped");
26 + }
27 +}
1 +/**
2 + * SDN-IP peering application.
3 + */
4 +package org.onlab.onos.sdnip;
...\ No newline at end of file ...\ No newline at end of file
...@@ -141,7 +141,7 @@ public class TopologyResource extends BaseResource { ...@@ -141,7 +141,7 @@ public class TopologyResource extends BaseResource {
141 private ObjectNode json(ObjectMapper mapper, ElementId id, int group, 141 private ObjectNode json(ObjectMapper mapper, ElementId id, int group,
142 String label, boolean isOnline) { 142 String label, boolean isOnline) {
143 return mapper.createObjectNode() 143 return mapper.createObjectNode()
144 - .put("name", id.uri().toString()) 144 + .put("name", id.toString())
145 .put("label", label) 145 .put("label", label)
146 .put("group", group) 146 .put("group", group)
147 .put("online", isOnline); 147 .put("online", isOnline);
...@@ -202,7 +202,7 @@ public class TopologyResource extends BaseResource { ...@@ -202,7 +202,7 @@ public class TopologyResource extends BaseResource {
202 // Returns a formatted string for the element associated with the given 202 // Returns a formatted string for the element associated with the given
203 // connection point. 203 // connection point.
204 private static String id(ConnectPoint cp) { 204 private static String id(ConnectPoint cp) {
205 - return cp.elementId().uri().toString(); 205 + return cp.elementId().toString();
206 } 206 }
207 207
208 } 208 }
......
1 /** 1 /**
2 - * REST resources for the sample topology viewer application. 2 + * Sample topology viewer application.
3 */ 3 */
4 package org.onlab.onos.tvue; 4 package org.onlab.onos.tvue;
......
...@@ -21,14 +21,14 @@ public final class Comparators { ...@@ -21,14 +21,14 @@ public final class Comparators {
21 public static final Comparator<ElementId> ELEMENT_ID_COMPARATOR = new Comparator<ElementId>() { 21 public static final Comparator<ElementId> ELEMENT_ID_COMPARATOR = new Comparator<ElementId>() {
22 @Override 22 @Override
23 public int compare(ElementId id1, ElementId id2) { 23 public int compare(ElementId id1, ElementId id2) {
24 - return id1.uri().toString().compareTo(id2.uri().toString()); 24 + return id1.toString().compareTo(id2.toString());
25 } 25 }
26 }; 26 };
27 27
28 public static final Comparator<Element> ELEMENT_COMPARATOR = new Comparator<Element>() { 28 public static final Comparator<Element> ELEMENT_COMPARATOR = new Comparator<Element>() {
29 @Override 29 @Override
30 public int compare(Element e1, Element e2) { 30 public int compare(Element e1, Element e2) {
31 - return e1.id().uri().toString().compareTo(e2.id().uri().toString()); 31 + return e1.id().toString().compareTo(e2.id().toString());
32 } 32 }
33 }; 33 };
34 34
......
...@@ -22,8 +22,10 @@ public class SummaryCommand extends AbstractShellCommand { ...@@ -22,8 +22,10 @@ public class SummaryCommand extends AbstractShellCommand {
22 protected void execute() { 22 protected void execute() {
23 TopologyService topologyService = get(TopologyService.class); 23 TopologyService topologyService = get(TopologyService.class);
24 Topology topology = topologyService.currentTopology(); 24 Topology topology = topologyService.currentTopology();
25 - print("version=%s, nodes=%d, devices=%d, links=%d, hosts=%d, clusters=%s, paths=%d, flows=%d, intents=%d", 25 + print("node=%s, version=%s",
26 - get(CoreService.class).version().toString(), 26 + get(ClusterService.class).getLocalNode().ip(),
27 + get(CoreService.class).version().toString());
28 + print("nodes=%d, devices=%d, links=%d, hosts=%d, clusters=%s, paths=%d, flows=%d, intents=%d",
27 get(ClusterService.class).getNodes().size(), 29 get(ClusterService.class).getNodes().size(),
28 get(DeviceService.class).getDeviceCount(), 30 get(DeviceService.class).getDeviceCount(),
29 get(LinkService.class).getLinkCount(), 31 get(LinkService.class).getLinkCount(),
......
1 package org.onlab.onos.cli.net; 1 package org.onlab.onos.cli.net;
2 2
3 -import static com.google.common.collect.Lists.newArrayList; 3 +import com.google.common.collect.Maps;
4 -import static org.onlab.onos.cli.net.DevicesListCommand.getSortedDevices;
5 -
6 -import java.util.Collections;
7 -import java.util.List;
8 -import java.util.Map;
9 -
10 import org.apache.karaf.shell.commands.Argument; 4 import org.apache.karaf.shell.commands.Argument;
11 import org.apache.karaf.shell.commands.Command; 5 import org.apache.karaf.shell.commands.Command;
6 +import org.onlab.onos.CoreService;
12 import org.onlab.onos.cli.AbstractShellCommand; 7 import org.onlab.onos.cli.AbstractShellCommand;
13 import org.onlab.onos.cli.Comparators; 8 import org.onlab.onos.cli.Comparators;
14 import org.onlab.onos.net.Device; 9 import org.onlab.onos.net.Device;
...@@ -18,37 +13,43 @@ import org.onlab.onos.net.flow.FlowEntry; ...@@ -18,37 +13,43 @@ import org.onlab.onos.net.flow.FlowEntry;
18 import org.onlab.onos.net.flow.FlowEntry.FlowEntryState; 13 import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
19 import org.onlab.onos.net.flow.FlowRuleService; 14 import org.onlab.onos.net.flow.FlowRuleService;
20 15
21 -import com.google.common.collect.Maps; 16 +import java.util.Collections;
17 +import java.util.List;
18 +import java.util.Map;
19 +
20 +import static com.google.common.collect.Lists.newArrayList;
21 +import static org.onlab.onos.cli.net.DevicesListCommand.getSortedDevices;
22 22
23 /** 23 /**
24 * Lists all currently-known hosts. 24 * Lists all currently-known hosts.
25 */ 25 */
26 @Command(scope = "onos", name = "flows", 26 @Command(scope = "onos", name = "flows",
27 -description = "Lists all currently-known flows.") 27 + description = "Lists all currently-known flows.")
28 public class FlowsListCommand extends AbstractShellCommand { 28 public class FlowsListCommand extends AbstractShellCommand {
29 29
30 public static final String ANY = "any"; 30 public static final String ANY = "any";
31 31
32 private static final String FMT = 32 private static final String FMT =
33 - " id=%s, state=%s, bytes=%s, packets=%s, duration=%s, priority=%s"; 33 + " id=%s, state=%s, bytes=%s, packets=%s, duration=%s, priority=%s, appId=%s";
34 private static final String TFMT = " treatment=%s"; 34 private static final String TFMT = " treatment=%s";
35 private static final String SFMT = " selector=%s"; 35 private static final String SFMT = " selector=%s";
36 36
37 @Argument(index = 1, name = "uri", description = "Device ID", 37 @Argument(index = 1, name = "uri", description = "Device ID",
38 - required = false, multiValued = false) 38 + required = false, multiValued = false)
39 String uri = null; 39 String uri = null;
40 40
41 @Argument(index = 0, name = "state", description = "Flow Rule state", 41 @Argument(index = 0, name = "state", description = "Flow Rule state",
42 - required = false, multiValued = false) 42 + required = false, multiValued = false)
43 String state = null; 43 String state = null;
44 44
45 @Override 45 @Override
46 protected void execute() { 46 protected void execute() {
47 + CoreService coreService = get(CoreService.class);
47 DeviceService deviceService = get(DeviceService.class); 48 DeviceService deviceService = get(DeviceService.class);
48 FlowRuleService service = get(FlowRuleService.class); 49 FlowRuleService service = get(FlowRuleService.class);
49 Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service); 50 Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service);
50 for (Device d : getSortedDevices(deviceService)) { 51 for (Device d : getSortedDevices(deviceService)) {
51 - printFlows(d, flows.get(d)); 52 + printFlows(d, flows.get(d), coreService);
52 } 53 }
53 } 54 }
54 55
...@@ -67,7 +68,7 @@ public class FlowsListCommand extends AbstractShellCommand { ...@@ -67,7 +68,7 @@ public class FlowsListCommand extends AbstractShellCommand {
67 s = FlowEntryState.valueOf(state.toUpperCase()); 68 s = FlowEntryState.valueOf(state.toUpperCase());
68 } 69 }
69 Iterable<Device> devices = uri == null ? deviceService.getDevices() : 70 Iterable<Device> devices = uri == null ? deviceService.getDevices() :
70 - Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri))); 71 + Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri)));
71 for (Device d : devices) { 72 for (Device d : devices) {
72 if (s == null) { 73 if (s == null) {
73 rules = newArrayList(service.getFlowEntries(d.id())); 74 rules = newArrayList(service.getFlowEntries(d.id()));
...@@ -87,16 +88,19 @@ public class FlowsListCommand extends AbstractShellCommand { ...@@ -87,16 +88,19 @@ public class FlowsListCommand extends AbstractShellCommand {
87 88
88 /** 89 /**
89 * Prints flows. 90 * Prints flows.
90 - * @param d the device 91 + *
92 + * @param d the device
91 * @param flows the set of flows for that device. 93 * @param flows the set of flows for that device.
92 */ 94 */
93 - protected void printFlows(Device d, List<FlowEntry> flows) { 95 + protected void printFlows(Device d, List<FlowEntry> flows,
96 + CoreService coreService) {
94 boolean empty = flows == null || flows.isEmpty(); 97 boolean empty = flows == null || flows.isEmpty();
95 print("deviceId=%s, flowRuleCount=%d", d.id(), empty ? 0 : flows.size()); 98 print("deviceId=%s, flowRuleCount=%d", d.id(), empty ? 0 : flows.size());
96 if (!empty) { 99 if (!empty) {
97 for (FlowEntry f : flows) { 100 for (FlowEntry f : flows) {
98 - print(FMT, Long.toHexString(f.id().value()), f.state(), f.bytes(), 101 + print(FMT, Long.toHexString(f.id().value()), f.state(),
99 - f.packets(), f.life(), f.priority()); 102 + f.bytes(), f.packets(), f.life(), f.priority(),
103 + coreService.getAppId(f.appId()).name());
100 print(SFMT, f.selector().criteria()); 104 print(SFMT, f.selector().criteria());
101 print(TFMT, f.treatment().instructions()); 105 print(TFMT, f.treatment().instructions());
102 } 106 }
......
1 +package org.onlab.onos.cli.net;
2 +
3 +import java.util.concurrent.CountDownLatch;
4 +import java.util.concurrent.TimeUnit;
5 +
6 +import org.apache.karaf.shell.commands.Argument;
7 +import org.apache.karaf.shell.commands.Command;
8 +import org.onlab.onos.cli.AbstractShellCommand;
9 +import org.onlab.onos.net.ConnectPoint;
10 +import org.onlab.onos.net.DeviceId;
11 +import org.onlab.onos.net.PortNumber;
12 +import org.onlab.onos.net.flow.DefaultTrafficSelector;
13 +import org.onlab.onos.net.flow.DefaultTrafficTreatment;
14 +import org.onlab.onos.net.flow.TrafficSelector;
15 +import org.onlab.onos.net.flow.TrafficTreatment;
16 +import org.onlab.onos.net.intent.Intent;
17 +import org.onlab.onos.net.intent.IntentEvent;
18 +import org.onlab.onos.net.intent.IntentEvent.Type;
19 +import org.onlab.onos.net.intent.IntentId;
20 +import org.onlab.onos.net.intent.IntentListener;
21 +import org.onlab.onos.net.intent.IntentService;
22 +import org.onlab.onos.net.intent.PointToPointIntent;
23 +import org.onlab.packet.Ethernet;
24 +import org.onlab.packet.MacAddress;
25 +
26 +/**
27 + * Installs point-to-point connectivity intents.
28 + */
29 +@Command(scope = "onos", name = "push-test-intents",
30 + description = "Installs random intents to test throughput")
31 +public class IntentPushTestCommand extends AbstractShellCommand
32 + implements IntentListener {
33 +
34 + @Argument(index = 0, name = "ingressDevice",
35 + description = "Ingress Device/Port Description",
36 + required = true, multiValued = false)
37 + String ingressDeviceString = null;
38 +
39 + @Argument(index = 1, name = "egressDevice",
40 + description = "Egress Device/Port Description",
41 + required = true, multiValued = false)
42 + String egressDeviceString = null;
43 +
44 + @Argument(index = 2, name = "count",
45 + description = "Number of intents to push",
46 + required = true, multiValued = false)
47 + String countString = null;
48 +
49 +
50 + private static long id = 0x7870001;
51 +
52 + private IntentService service;
53 + private CountDownLatch latch;
54 + private long start, end;
55 +
56 + @Override
57 + protected void execute() {
58 + service = get(IntentService.class);
59 +
60 + DeviceId ingressDeviceId = DeviceId.deviceId(getDeviceId(ingressDeviceString));
61 + PortNumber ingressPortNumber =
62 + PortNumber.portNumber(getPortNumber(ingressDeviceString));
63 + ConnectPoint ingress = new ConnectPoint(ingressDeviceId, ingressPortNumber);
64 +
65 + DeviceId egressDeviceId = DeviceId.deviceId(getDeviceId(egressDeviceString));
66 + PortNumber egressPortNumber =
67 + PortNumber.portNumber(getPortNumber(egressDeviceString));
68 + ConnectPoint egress = new ConnectPoint(egressDeviceId, egressPortNumber);
69 +
70 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
71 + .matchEthType(Ethernet.TYPE_IPV4);
72 + TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
73 +
74 + int count = Integer.parseInt(countString);
75 +
76 + service.addListener(this);
77 + latch = new CountDownLatch(count);
78 +
79 + start = System.currentTimeMillis();
80 + for (int i = 0; i < count; i++) {
81 + TrafficSelector s = selector
82 + .matchEthSrc(MacAddress.valueOf(i))
83 + .build();
84 + Intent intent =
85 + new PointToPointIntent(new IntentId(id++),
86 + s,
87 + treatment,
88 + ingress,
89 + egress);
90 + service.submit(intent);
91 + }
92 + try {
93 + latch.await(5, TimeUnit.SECONDS);
94 + printResults(count);
95 + } catch (InterruptedException e) {
96 + print(e.toString());
97 + }
98 + service.removeListener(this);
99 + }
100 +
101 + private void printResults(int count) {
102 + long delta = end - start;
103 + print("Time to install %d intents: %d ms", count, delta);
104 + }
105 +
106 + /**
107 + * Extracts the port number portion of the ConnectPoint.
108 + *
109 + * @param deviceString string representing the device/port
110 + * @return port number as a string, empty string if the port is not found
111 + */
112 + private String getPortNumber(String deviceString) {
113 + int slash = deviceString.indexOf('/');
114 + if (slash <= 0) {
115 + return "";
116 + }
117 + return deviceString.substring(slash + 1, deviceString.length());
118 + }
119 +
120 + /**
121 + * Extracts the device ID portion of the ConnectPoint.
122 + *
123 + * @param deviceString string representing the device/port
124 + * @return device ID string
125 + */
126 + private String getDeviceId(String deviceString) {
127 + int slash = deviceString.indexOf('/');
128 + if (slash <= 0) {
129 + return "";
130 + }
131 + return deviceString.substring(0, slash);
132 + }
133 +
134 + @Override
135 + public void event(IntentEvent event) {
136 + if (event.type() == Type.INSTALLED) {
137 + end = event.time();
138 + if (latch != null) {
139 + latch.countDown();
140 + } else {
141 + log.warn("install event latch is null");
142 + }
143 + }
144 + }
145 +}
...@@ -19,17 +19,16 @@ import org.onlab.onos.net.intent.IntentState; ...@@ -19,17 +19,16 @@ import org.onlab.onos.net.intent.IntentState;
19 description = "Wipes-out the entire network information base, i.e. devices, links, hosts") 19 description = "Wipes-out the entire network information base, i.e. devices, links, hosts")
20 public class WipeOutCommand extends ClustersListCommand { 20 public class WipeOutCommand extends ClustersListCommand {
21 21
22 - private static final String DISCLAIMER = "Delete everything please."; 22 + private static final String PLEASE = "please";
23 23
24 - @Argument(index = 0, name = "disclaimer", description = "Device ID", 24 + @Argument(index = 0, name = "please", description = "Confirmation phrase",
25 required = false, multiValued = false) 25 required = false, multiValued = false)
26 - String disclaimer = null; 26 + String please = null;
27 27
28 @Override 28 @Override
29 protected void execute() { 29 protected void execute() {
30 - if (disclaimer == null || !disclaimer.equals(DISCLAIMER)) { 30 + if (please == null || !please.equals(PLEASE)) {
31 - print("I'm afraid I can't do that!\nPlease acknowledge with phrase: '%s'", 31 + print("I'm afraid I can't do that!\nSay: %s", PLEASE);
32 - DISCLAIMER);
33 return; 32 return;
34 } 33 }
35 34
......
...@@ -82,6 +82,13 @@ ...@@ -82,6 +82,13 @@
82 <ref component-id="connectPointCompleter"/> 82 <ref component-id="connectPointCompleter"/>
83 </completers> 83 </completers>
84 </command> 84 </command>
85 + <command>
86 + <action class="org.onlab.onos.cli.net.IntentPushTestCommand"/>
87 + <completers>
88 + <ref component-id="connectPointCompleter"/>
89 + <ref component-id="connectPointCompleter"/>
90 + </completers>
91 + </command>
85 92
86 <command> 93 <command>
87 <action class="org.onlab.onos.cli.net.ClustersListCommand"/> 94 <action class="org.onlab.onos.cli.net.ClustersListCommand"/>
......
1 package org.onlab.onos; 1 package org.onlab.onos;
2 2
3 -import java.util.Objects;
4 -import java.util.concurrent.atomic.AtomicInteger;
5 3
6 /** 4 /**
7 - * Application id generator class. 5 + * Application identifier.
8 */ 6 */
9 -public final class ApplicationId { 7 +public interface ApplicationId {
10 8
11 - private static final AtomicInteger ID_DISPENCER = new AtomicInteger(1); 9 + /**
12 - private final Integer id; 10 + * Returns the application id.
13 - 11 + * @return a short value
14 - // Ban public construction 12 + */
15 - private ApplicationId(Integer id) { 13 + short id();
16 - this.id = id;
17 - }
18 -
19 - public Integer id() {
20 - return id;
21 - }
22 -
23 - public static ApplicationId valueOf(Integer id) {
24 - return new ApplicationId(id);
25 - }
26 -
27 - @Override
28 - public int hashCode() {
29 - return Objects.hash(id);
30 - }
31 -
32 - @Override
33 - public boolean equals(Object obj) {
34 - if (this == obj) {
35 - return true;
36 - }
37 - if (obj == null) {
38 - return false;
39 - }
40 - if (!(obj instanceof ApplicationId)) {
41 - return false;
42 - }
43 - ApplicationId other = (ApplicationId) obj;
44 - return Objects.equals(this.id, other.id);
45 - }
46 14
47 /** 15 /**
48 - * Returns a new application id. 16 + * Returns the applications supplied identifier.
49 - * 17 + * @return a string identifier
50 - * @return app id
51 */ 18 */
52 - public static ApplicationId getAppId() { 19 + String name();
53 - return new ApplicationId(ApplicationId.ID_DISPENCER.getAndIncrement());
54 - }
55 20
56 } 21 }
......
...@@ -12,4 +12,21 @@ public interface CoreService { ...@@ -12,4 +12,21 @@ public interface CoreService {
12 */ 12 */
13 Version version(); 13 Version version();
14 14
15 + /**
16 + * Registers a new application by its name, which is expected
17 + * to follow the reverse DNS convention, e.g.
18 + * {@code org.flying.circus.app}
19 + *
20 + * @param identifier string identifier
21 + * @return the application id
22 + */
23 + ApplicationId registerApplication(String identifier);
24 +
25 + /**
26 + * Returns an existing application id from a given id.
27 + * @param id the short value of the id
28 + * @return an application id
29 + */
30 + ApplicationId getAppId(Short id);
31 +
15 } 32 }
......
1 +package org.onlab.onos.cluster;
2 +
3 +import com.google.common.base.Function;
4 +
5 +/**
6 + * Function to convert ControllerNode to NodeId.
7 + */
8 +public final class ControllerNodeToNodeId
9 + implements Function<ControllerNode, NodeId> {
10 +
11 + private static final ControllerNodeToNodeId INSTANCE = new ControllerNodeToNodeId();
12 +
13 + @Override
14 + public NodeId apply(ControllerNode input) {
15 + return input.id();
16 + }
17 +
18 + /**
19 + * Returns a Function to convert ControllerNode to NodeId.
20 + *
21 + * @return ControllerNodeToNodeId instance.
22 + */
23 + public static ControllerNodeToNodeId toNodeId() {
24 + return INSTANCE;
25 + }
26 +}
1 package org.onlab.onos.net; 1 package org.onlab.onos.net;
2 2
3 import java.net.URI; 3 import java.net.URI;
4 +import java.util.Objects;
4 5
5 /** 6 /**
6 * Immutable representation of a device identity. 7 * Immutable representation of a device identity.
7 */ 8 */
8 public final class DeviceId extends ElementId { 9 public final class DeviceId extends ElementId {
9 10
11 + /**
12 + * Represents either no device, or an unspecified device.
13 + */
14 + public static final DeviceId NONE = deviceId("none:none");
15 +
16 + private final URI uri;
17 + private final String str;
18 +
10 // Public construction is prohibited 19 // Public construction is prohibited
11 private DeviceId(URI uri) { 20 private DeviceId(URI uri) {
12 - super(uri); 21 + this.uri = uri;
22 + this.str = uri.toString();
23 + }
24 +
25 +
26 + // Default constructor for serialization
27 + protected DeviceId() {
28 + this.uri = null;
29 + this.str = null;
13 } 30 }
14 31
15 /** 32 /**
...@@ -30,4 +47,36 @@ public final class DeviceId extends ElementId { ...@@ -30,4 +47,36 @@ public final class DeviceId extends ElementId {
30 return deviceId(URI.create(string)); 47 return deviceId(URI.create(string));
31 } 48 }
32 49
50 + /**
51 + * Returns the backing URI.
52 + *
53 + * @return backing URI
54 + */
55 + public URI uri() {
56 + return uri;
57 + }
58 +
59 + @Override
60 + public int hashCode() {
61 + return Objects.hash(str);
62 + }
63 +
64 + @Override
65 + public boolean equals(Object obj) {
66 + if (this == obj) {
67 + return true;
68 + }
69 + if (obj instanceof DeviceId) {
70 + final DeviceId that = (DeviceId) obj;
71 + return this.getClass() == that.getClass() &&
72 + Objects.equals(this.str, that.str);
73 + }
74 + return false;
75 + }
76 +
77 + @Override
78 + public String toString() {
79 + return str;
80 + }
81 +
33 } 82 }
......
1 package org.onlab.onos.net; 1 package org.onlab.onos.net;
2 2
3 -import java.net.URI;
4 -import java.util.Objects;
5 -
6 /** 3 /**
7 * Immutable representation of a network element identity. 4 * Immutable representation of a network element identity.
8 */ 5 */
9 public abstract class ElementId { 6 public abstract class ElementId {
10 -
11 - private final URI uri;
12 -
13 - // Default constructor for serialization
14 - protected ElementId() {
15 - this.uri = null;
16 - }
17 -
18 - /**
19 - * Creates an element identifier using the supplied URI.
20 - *
21 - * @param uri backing URI
22 - */
23 - protected ElementId(URI uri) {
24 - this.uri = uri;
25 - }
26 -
27 - /**
28 - * Returns the backing URI.
29 - *
30 - * @return backing URI
31 - */
32 - public URI uri() {
33 - return uri;
34 - }
35 -
36 - @Override
37 - public int hashCode() {
38 - return Objects.hash(uri);
39 - }
40 -
41 - @Override
42 - public boolean equals(Object obj) {
43 - if (this == obj) {
44 - return true;
45 - }
46 - if (obj instanceof ElementId) {
47 - final ElementId that = (ElementId) obj;
48 - return this.getClass() == that.getClass() &&
49 - Objects.equals(this.uri, that.uri);
50 - }
51 - return false;
52 - }
53 -
54 - @Override
55 - public String toString() {
56 - return uri.toString();
57 - }
58 -
59 } 7 }
......
...@@ -3,44 +3,69 @@ package org.onlab.onos.net; ...@@ -3,44 +3,69 @@ package org.onlab.onos.net;
3 import org.onlab.packet.MacAddress; 3 import org.onlab.packet.MacAddress;
4 import org.onlab.packet.VlanId; 4 import org.onlab.packet.VlanId;
5 5
6 -import java.net.URI; 6 +import java.util.Objects;
7 +
8 +import static com.google.common.base.Preconditions.checkArgument;
7 9
8 /** 10 /**
9 * Immutable representation of a host identity. 11 * Immutable representation of a host identity.
10 */ 12 */
11 public final class HostId extends ElementId { 13 public final class HostId extends ElementId {
12 14
13 - private static final String NIC = "nic";
14 -
15 /** 15 /**
16 * Represents either no host, or an unspecified host; used for creating 16 * Represents either no host, or an unspecified host; used for creating
17 * open ingress/egress edge links. 17 * open ingress/egress edge links.
18 */ 18 */
19 - public static final HostId NONE = hostId(NIC + ":none-0"); 19 + public static final HostId NONE = new HostId(MacAddress.ZERO, VlanId.NONE);
20 +
21 + private static final int MAC_LENGTH = 17;
22 + private static final int MIN_ID_LENGTH = 19;
23 +
24 + private final MacAddress mac;
25 + private final VlanId vlanId;
20 26
21 // Public construction is prohibited 27 // Public construction is prohibited
22 - private HostId(URI uri) { 28 + private HostId(MacAddress mac, VlanId vlanId) {
23 - super(uri); 29 + this.mac = mac;
30 + this.vlanId = vlanId;
31 + }
32 +
33 + // Default constructor for serialization
34 + private HostId() {
35 + this.mac = null;
36 + this.vlanId = null;
24 } 37 }
25 38
26 /** 39 /**
27 - * Creates a device id using the supplied URI. 40 + * Returns the host MAC address.
28 * 41 *
29 - * @param uri device URI 42 + * @return MAC address
30 - * @return host identifier 43 + */
44 + public MacAddress mac() {
45 + return mac;
46 + }
47 +
48 + /**
49 + * Returns the host MAC address.
50 + *
51 + * @return MAC address
31 */ 52 */
32 - public static HostId hostId(URI uri) { 53 + public VlanId vlanId() {
33 - return new HostId(uri); 54 + return vlanId;
34 } 55 }
35 56
36 /** 57 /**
37 - * Creates a device id using the supplied URI string. 58 + * Creates a device id using the supplied ID string.
38 * 59 *
39 * @param string device URI string 60 * @param string device URI string
40 * @return host identifier 61 * @return host identifier
41 */ 62 */
42 public static HostId hostId(String string) { 63 public static HostId hostId(String string) {
43 - return hostId(URI.create(string)); 64 + checkArgument(string.length() >= MIN_ID_LENGTH,
65 + "Host ID must be at least %s characters", MIN_ID_LENGTH);
66 + MacAddress mac = MacAddress.valueOf(string.substring(0, MAC_LENGTH));
67 + VlanId vlanId = VlanId.vlanId(Short.parseShort(string.substring(MAC_LENGTH + 1)));
68 + return new HostId(mac, vlanId);
44 } 69 }
45 70
46 /** 71 /**
...@@ -51,7 +76,7 @@ public final class HostId extends ElementId { ...@@ -51,7 +76,7 @@ public final class HostId extends ElementId {
51 * @return host identifier 76 * @return host identifier
52 */ 77 */
53 public static HostId hostId(MacAddress mac, VlanId vlanId) { 78 public static HostId hostId(MacAddress mac, VlanId vlanId) {
54 - return hostId(NIC + ":" + mac + "-" + vlanId); 79 + return new HostId(mac, vlanId);
55 } 80 }
56 81
57 /** 82 /**
...@@ -64,4 +89,26 @@ public final class HostId extends ElementId { ...@@ -64,4 +89,26 @@ public final class HostId extends ElementId {
64 return hostId(mac, VlanId.vlanId(VlanId.UNTAGGED)); 89 return hostId(mac, VlanId.vlanId(VlanId.UNTAGGED));
65 } 90 }
66 91
92 + public String toString() {
93 + return mac + "/" + vlanId;
94 + }
95 +
96 + @Override
97 + public int hashCode() {
98 + return Objects.hash(mac, vlanId);
99 + }
100 +
101 + @Override
102 + public boolean equals(Object obj) {
103 + if (this == obj) {
104 + return true;
105 + }
106 + if (obj instanceof HostId) {
107 + final HostId other = (HostId) obj;
108 + return Objects.equals(this.mac, other.mac) &&
109 + Objects.equals(this.vlanId, other.vlanId);
110 + }
111 + return false;
112 + }
113 +
67 } 114 }
......
1 package org.onlab.onos.net; 1 package org.onlab.onos.net;
2 2
3 +import static org.onlab.onos.net.PortNumber.P0;
4 +
3 /** 5 /**
4 * Representation of a network edge location where an end-station host is 6 * Representation of a network edge location where an end-station host is
5 * connected. 7 * connected.
6 */ 8 */
7 public class HostLocation extends ConnectPoint { 9 public class HostLocation extends ConnectPoint {
8 10
11 + /**
12 + * Represents a no location or an unknown location.
13 + */
14 + public static final HostLocation NONE = new HostLocation(DeviceId.NONE, P0, 0L);
15 +
9 // Note that time is explicitly excluded from the notion of equality. 16 // Note that time is explicitly excluded from the notion of equality.
10 private final long time; 17 private final long time;
11 18
......
1 +package org.onlab.onos.net;
2 +
3 +/**
4 + * Representation of a network resource.
5 + */
6 +public interface NetworkResource {
7 +}
...@@ -4,6 +4,8 @@ import org.onlab.onos.net.AbstractDescription; ...@@ -4,6 +4,8 @@ import org.onlab.onos.net.AbstractDescription;
4 import org.onlab.onos.net.PortNumber; 4 import org.onlab.onos.net.PortNumber;
5 import org.onlab.onos.net.SparseAnnotations; 5 import org.onlab.onos.net.SparseAnnotations;
6 6
7 +import com.google.common.base.MoreObjects;
8 +
7 /** 9 /**
8 * Default implementation of immutable port description. 10 * Default implementation of immutable port description.
9 */ 11 */
...@@ -48,6 +50,15 @@ public class DefaultPortDescription extends AbstractDescription ...@@ -48,6 +50,15 @@ public class DefaultPortDescription extends AbstractDescription
48 return isEnabled; 50 return isEnabled;
49 } 51 }
50 52
53 + @Override
54 + public String toString() {
55 + return MoreObjects.toStringHelper(getClass())
56 + .add("number", number)
57 + .add("isEnabled", isEnabled)
58 + .add("annotations", annotations())
59 + .toString();
60 + }
61 +
51 // default constructor for serialization 62 // default constructor for serialization
52 private DefaultPortDescription() { 63 private DefaultPortDescription() {
53 this.number = null; 64 this.number = null;
......
1 +package org.onlab.onos.net.flow;
2 +
3 +import java.util.List;
4 +
5 +/**
6 + * Interface capturing the result of a batch operation.
7 + *
8 + */
9 +public interface BatchOperationResult<T> {
10 +
11 + /**
12 + * Returns whether the operation was successful.
13 + * @return true if successful, false otherwise
14 + */
15 + boolean isSuccess();
16 +
17 + /**
18 + * Obtains a list of items which failed.
19 + * @return a list of failures
20 + */
21 + List<T> failedItems();
22 +
23 +}
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 -public class CompletedBatchOperation { 3 +import java.util.List;
4 +
5 +import com.google.common.collect.ImmutableList;
6 +
7 +public class CompletedBatchOperation implements BatchOperationResult<FlowEntry> {
8 +
9 +
10 + private final boolean success;
11 + private final List<FlowEntry> failures;
12 +
13 + public CompletedBatchOperation(boolean success, List<FlowEntry> failures) {
14 + this.success = success;
15 + this.failures = ImmutableList.copyOf(failures);
16 + }
17 +
18 + @Override
19 + public boolean isSuccess() {
20 + return success;
21 + }
22 +
23 + @Override
24 + public List<FlowEntry> failedItems() {
25 + return failures;
26 + }
4 27
5 28
6 } 29 }
......
...@@ -17,6 +17,10 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { ...@@ -17,6 +17,10 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
17 17
18 private long lastSeen = -1; 18 private long lastSeen = -1;
19 19
20 + private final int errType;
21 +
22 + private final int errCode;
23 +
20 24
21 public DefaultFlowEntry(DeviceId deviceId, TrafficSelector selector, 25 public DefaultFlowEntry(DeviceId deviceId, TrafficSelector selector,
22 TrafficTreatment treatment, int priority, FlowEntryState state, 26 TrafficTreatment treatment, int priority, FlowEntryState state,
...@@ -27,6 +31,8 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { ...@@ -27,6 +31,8 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
27 this.life = life; 31 this.life = life;
28 this.packets = packets; 32 this.packets = packets;
29 this.bytes = bytes; 33 this.bytes = bytes;
34 + this.errCode = -1;
35 + this.errType = -1;
30 this.lastSeen = System.currentTimeMillis(); 36 this.lastSeen = System.currentTimeMillis();
31 } 37 }
32 38
...@@ -37,6 +43,8 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { ...@@ -37,6 +43,8 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
37 this.life = life; 43 this.life = life;
38 this.packets = packets; 44 this.packets = packets;
39 this.bytes = bytes; 45 this.bytes = bytes;
46 + this.errCode = -1;
47 + this.errType = -1;
40 this.lastSeen = System.currentTimeMillis(); 48 this.lastSeen = System.currentTimeMillis();
41 } 49 }
42 50
...@@ -46,9 +54,18 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { ...@@ -46,9 +54,18 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
46 this.life = 0; 54 this.life = 0;
47 this.packets = 0; 55 this.packets = 0;
48 this.bytes = 0; 56 this.bytes = 0;
57 + this.errCode = -1;
58 + this.errType = -1;
49 this.lastSeen = System.currentTimeMillis(); 59 this.lastSeen = System.currentTimeMillis();
50 } 60 }
51 61
62 + public DefaultFlowEntry(FlowRule rule, int errType, int errCode) {
63 + super(rule);
64 + this.state = FlowEntryState.FAILED;
65 + this.errType = errType;
66 + this.errCode = errCode;
67 + }
68 +
52 @Override 69 @Override
53 public long life() { 70 public long life() {
54 return life; 71 return life;
...@@ -100,6 +117,16 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { ...@@ -100,6 +117,16 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
100 } 117 }
101 118
102 @Override 119 @Override
120 + public int errType() {
121 + return this.errType;
122 + }
123 +
124 + @Override
125 + public int errCode() {
126 + return this.errCode;
127 + }
128 +
129 + @Override
103 public String toString() { 130 public String toString() {
104 return toStringHelper(this) 131 return toStringHelper(this)
105 .add("rule", super.toString()) 132 .add("rule", super.toString())
...@@ -108,4 +135,6 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { ...@@ -108,4 +135,6 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
108 } 135 }
109 136
110 137
138 +
139 +
111 } 140 }
......
...@@ -21,7 +21,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -21,7 +21,7 @@ public class DefaultFlowRule implements FlowRule {
21 21
22 private final FlowId id; 22 private final FlowId id;
23 23
24 - private final ApplicationId appId; 24 + private final short appId;
25 25
26 private final int timeout; 26 private final int timeout;
27 27
...@@ -36,7 +36,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -36,7 +36,7 @@ public class DefaultFlowRule implements FlowRule {
36 this.timeout = timeout; 36 this.timeout = timeout;
37 this.created = System.currentTimeMillis(); 37 this.created = System.currentTimeMillis();
38 38
39 - this.appId = ApplicationId.valueOf((int) (flowId >> 32)); 39 + this.appId = (short) (flowId >>> 48);
40 this.id = FlowId.valueOf(flowId); 40 this.id = FlowId.valueOf(flowId);
41 } 41 }
42 42
...@@ -52,11 +52,11 @@ public class DefaultFlowRule implements FlowRule { ...@@ -52,11 +52,11 @@ public class DefaultFlowRule implements FlowRule {
52 this.priority = priority; 52 this.priority = priority;
53 this.selector = selector; 53 this.selector = selector;
54 this.treatment = treatement; 54 this.treatment = treatement;
55 - this.appId = appId; 55 + this.appId = appId.id();
56 this.timeout = timeout; 56 this.timeout = timeout;
57 this.created = System.currentTimeMillis(); 57 this.created = System.currentTimeMillis();
58 58
59 - this.id = FlowId.valueOf((((long) appId().id()) << 32) | (this.hash() & 0xffffffffL)); 59 + this.id = FlowId.valueOf((((long) this.appId) << 48) | (this.hash() & 0x0000ffffffffL));
60 } 60 }
61 61
62 public DefaultFlowRule(FlowRule rule) { 62 public DefaultFlowRule(FlowRule rule) {
...@@ -78,7 +78,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -78,7 +78,7 @@ public class DefaultFlowRule implements FlowRule {
78 } 78 }
79 79
80 @Override 80 @Override
81 - public ApplicationId appId() { 81 + public short appId() {
82 return appId; 82 return appId;
83 } 83 }
84 84
......
...@@ -140,6 +140,16 @@ public final class DefaultTrafficSelector implements TrafficSelector { ...@@ -140,6 +140,16 @@ public final class DefaultTrafficSelector implements TrafficSelector {
140 } 140 }
141 141
142 @Override 142 @Override
143 + public Builder matchTcpSrc(Short tcpPort) {
144 + return add(Criteria.matchTcpSrc(tcpPort));
145 + }
146 +
147 + @Override
148 + public Builder matchTcpDst(Short tcpPort) {
149 + return add(Criteria.matchTcpDst(tcpPort));
150 + }
151 +
152 + @Override
143 public TrafficSelector build() { 153 public TrafficSelector build() {
144 return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values())); 154 return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
145 } 155 }
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 -import static org.slf4j.LoggerFactory.getLogger;
4 -
5 -import java.util.Collections;
6 -import java.util.LinkedList;
7 -import java.util.List;
8 -import java.util.Objects;
9 -
10 import org.onlab.onos.net.PortNumber; 3 import org.onlab.onos.net.PortNumber;
11 import org.onlab.onos.net.flow.instructions.Instruction; 4 import org.onlab.onos.net.flow.instructions.Instruction;
12 import org.onlab.onos.net.flow.instructions.Instructions; 5 import org.onlab.onos.net.flow.instructions.Instructions;
13 import org.onlab.packet.IpPrefix; 6 import org.onlab.packet.IpPrefix;
14 import org.onlab.packet.MacAddress; 7 import org.onlab.packet.MacAddress;
15 import org.onlab.packet.VlanId; 8 import org.onlab.packet.VlanId;
16 -import org.slf4j.Logger; 9 +
10 +import java.util.Collections;
11 +import java.util.LinkedList;
12 +import java.util.List;
13 +import java.util.Objects;
17 14
18 /** 15 /**
19 * Default traffic treatment implementation. 16 * Default traffic treatment implementation.
...@@ -58,7 +55,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -58,7 +55,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
58 } 55 }
59 if (obj instanceof DefaultTrafficTreatment) { 56 if (obj instanceof DefaultTrafficTreatment) {
60 DefaultTrafficTreatment that = (DefaultTrafficTreatment) obj; 57 DefaultTrafficTreatment that = (DefaultTrafficTreatment) obj;
61 - return Objects.equals(instructions, that.instructions); 58 + return Objects.equals(instructions, that.instructions);
62 59
63 } 60 }
64 return false; 61 return false;
...@@ -70,8 +67,6 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -70,8 +67,6 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
70 */ 67 */
71 public static final class Builder implements TrafficTreatment.Builder { 68 public static final class Builder implements TrafficTreatment.Builder {
72 69
73 - private final Logger log = getLogger(getClass());
74 -
75 boolean drop = false; 70 boolean drop = false;
76 71
77 List<Instruction> outputs = new LinkedList<>(); 72 List<Instruction> outputs = new LinkedList<>();
...@@ -107,7 +102,8 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -107,7 +102,8 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
107 groups.add(instruction); 102 groups.add(instruction);
108 break; 103 break;
109 default: 104 default:
110 - log.warn("Unknown instruction type {}", instruction.type()); 105 + throw new IllegalArgumentException("Unknown instruction type: " +
106 + instruction.type());
111 } 107 }
112 return this; 108 return this;
113 } 109 }
......
...@@ -29,7 +29,12 @@ public interface FlowEntry extends FlowRule { ...@@ -29,7 +29,12 @@ public interface FlowEntry extends FlowRule {
29 /** 29 /**
30 * Flow has been removed from flow table and can be purged. 30 * Flow has been removed from flow table and can be purged.
31 */ 31 */
32 - REMOVED 32 + REMOVED,
33 +
34 + /**
35 + * Indicates that the installation of this flow has failed.
36 + */
37 + FAILED
33 } 38 }
34 39
35 /** 40 /**
...@@ -95,4 +100,16 @@ public interface FlowEntry extends FlowRule { ...@@ -95,4 +100,16 @@ public interface FlowEntry extends FlowRule {
95 */ 100 */
96 void setBytes(long bytes); 101 void setBytes(long bytes);
97 102
103 + /**
104 + * Indicates the error type.
105 + * @return an integer value of the error
106 + */
107 + int errType();
108 +
109 + /**
110 + * Indicates the error code.
111 + * @return an integer value of the error
112 + */
113 + int errCode();
114 +
98 } 115 }
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 -import org.onlab.onos.ApplicationId;
4 import org.onlab.onos.net.DeviceId; 3 import org.onlab.onos.net.DeviceId;
5 import org.onlab.onos.net.intent.BatchOperationTarget; 4 import org.onlab.onos.net.intent.BatchOperationTarget;
6 5
...@@ -26,7 +25,7 @@ public interface FlowRule extends BatchOperationTarget { ...@@ -26,7 +25,7 @@ public interface FlowRule extends BatchOperationTarget {
26 * 25 *
27 * @return an applicationId 26 * @return an applicationId
28 */ 27 */
29 - ApplicationId appId(); 28 + short appId();
30 29
31 /** 30 /**
32 * Returns the flow rule priority given in natural order; higher numbers 31 * Returns the flow rule priority given in natural order; higher numbers
......
...@@ -37,6 +37,12 @@ public interface FlowRuleProvider extends Provider { ...@@ -37,6 +37,12 @@ public interface FlowRuleProvider extends Provider {
37 */ 37 */
38 void removeRulesById(ApplicationId id, FlowRule... flowRules); 38 void removeRulesById(ApplicationId id, FlowRule... flowRules);
39 39
40 - Future<Void> executeBatch(BatchOperation<FlowRuleBatchEntry> batch); 40 + /**
41 + * Installs a batch of flow rules. Each flowrule is associated to an
42 + * operation which results in either addition, removal or modification.
43 + * @param batch a batch of flow rules
44 + * @return a future indicating the status of this execution
45 + */
46 + Future<CompletedBatchOperation> executeBatch(BatchOperation<FlowRuleBatchEntry> batch);
41 47
42 } 48 }
......
...@@ -98,6 +98,20 @@ public interface TrafficSelector { ...@@ -98,6 +98,20 @@ public interface TrafficSelector {
98 public Builder matchIPDst(IpPrefix ip); 98 public Builder matchIPDst(IpPrefix ip);
99 99
100 /** 100 /**
101 + * Matches a TCP source port number.
102 + * @param tcpPort a TCP source port number
103 + * @return a selection builder
104 + */
105 + public Builder matchTcpSrc(Short tcpPort);
106 +
107 + /**
108 + * Matches a TCP destination port number.
109 + * @param tcpPort a TCP destination port number
110 + * @return a selection builder
111 + */
112 + public Builder matchTcpDst(Short tcpPort);
113 +
114 + /**
101 * Builds an immutable traffic selector. 115 * Builds an immutable traffic selector.
102 * 116 *
103 * @return traffic selector 117 * @return traffic selector
......
...@@ -113,6 +113,25 @@ public final class Criteria { ...@@ -113,6 +113,25 @@ public final class Criteria {
113 return new IPCriterion(ip, Type.IPV4_DST); 113 return new IPCriterion(ip, Type.IPV4_DST);
114 } 114 }
115 115
116 + /**
117 + * Creates a match on TCP source port field using the specified value.
118 + *
119 + * @param tcpPort
120 + * @return match criterion
121 + */
122 + public static Criterion matchTcpSrc(Short tcpPort) {
123 + return new TcpPortCriterion(tcpPort, Type.TCP_SRC);
124 + }
125 +
126 + /**
127 + * Creates a match on TCP destination port field using the specified value.
128 + *
129 + * @param tcpPort
130 + * @return match criterion
131 + */
132 + public static Criterion matchTcpDst(Short tcpPort) {
133 + return new TcpPortCriterion(tcpPort, Type.TCP_DST);
134 + }
116 135
117 /* 136 /*
118 * Implementations of criteria. 137 * Implementations of criteria.
...@@ -437,4 +456,49 @@ public final class Criteria { ...@@ -437,4 +456,49 @@ public final class Criteria {
437 } 456 }
438 457
439 458
459 + public static final class TcpPortCriterion implements Criterion {
460 +
461 + private final Short tcpPort;
462 + private final Type type;
463 +
464 + public TcpPortCriterion(Short tcpPort, Type type) {
465 + this.tcpPort = tcpPort;
466 + this.type = type;
467 + }
468 +
469 + @Override
470 + public Type type() {
471 + return this.type;
472 + }
473 +
474 + public Short tcpPort() {
475 + return this.tcpPort;
476 + }
477 +
478 + @Override
479 + public String toString() {
480 + return toStringHelper(type().toString())
481 + .add("tcpPort", tcpPort).toString();
482 + }
483 +
484 + @Override
485 + public int hashCode() {
486 + return Objects.hash(tcpPort, type);
487 + }
488 +
489 + @Override
490 + public boolean equals(Object obj) {
491 + if (this == obj) {
492 + return true;
493 + }
494 + if (obj instanceof TcpPortCriterion) {
495 + TcpPortCriterion that = (TcpPortCriterion) obj;
496 + return Objects.equals(tcpPort, that.tcpPort) &&
497 + Objects.equals(type, that.type);
498 +
499 +
500 + }
501 + return false;
502 + }
503 + }
440 } 504 }
......
1 package org.onlab.onos.net.host; 1 package org.onlab.onos.net.host;
2 2
3 -import com.google.common.collect.ImmutableSet;
4 import org.onlab.onos.net.AbstractDescription; 3 import org.onlab.onos.net.AbstractDescription;
5 import org.onlab.onos.net.HostLocation; 4 import org.onlab.onos.net.HostLocation;
6 import org.onlab.onos.net.SparseAnnotations; 5 import org.onlab.onos.net.SparseAnnotations;
...@@ -8,9 +7,6 @@ import org.onlab.packet.IpPrefix; ...@@ -8,9 +7,6 @@ import org.onlab.packet.IpPrefix;
8 import org.onlab.packet.MacAddress; 7 import org.onlab.packet.MacAddress;
9 import org.onlab.packet.VlanId; 8 import org.onlab.packet.VlanId;
10 9
11 -import java.util.HashSet;
12 -import java.util.Set;
13 -
14 import static com.google.common.base.MoreObjects.toStringHelper; 10 import static com.google.common.base.MoreObjects.toStringHelper;
15 11
16 /** 12 /**
...@@ -22,7 +18,7 @@ public class DefaultHostDescription extends AbstractDescription ...@@ -22,7 +18,7 @@ public class DefaultHostDescription extends AbstractDescription
22 private final MacAddress mac; 18 private final MacAddress mac;
23 private final VlanId vlan; 19 private final VlanId vlan;
24 private final HostLocation location; 20 private final HostLocation location;
25 - private final Set<IpPrefix> ips; 21 + private final IpPrefix ip;
26 22
27 /** 23 /**
28 * Creates a host description using the supplied information. 24 * Creates a host description using the supplied information.
...@@ -35,7 +31,7 @@ public class DefaultHostDescription extends AbstractDescription ...@@ -35,7 +31,7 @@ public class DefaultHostDescription extends AbstractDescription
35 public DefaultHostDescription(MacAddress mac, VlanId vlan, 31 public DefaultHostDescription(MacAddress mac, VlanId vlan,
36 HostLocation location, 32 HostLocation location,
37 SparseAnnotations... annotations) { 33 SparseAnnotations... annotations) {
38 - this(mac, vlan, location, new HashSet<IpPrefix>(), annotations); 34 + this(mac, vlan, location, null, annotations);
39 } 35 }
40 36
41 /** 37 /**
...@@ -44,17 +40,17 @@ public class DefaultHostDescription extends AbstractDescription ...@@ -44,17 +40,17 @@ public class DefaultHostDescription extends AbstractDescription
44 * @param mac host MAC address 40 * @param mac host MAC address
45 * @param vlan host VLAN identifier 41 * @param vlan host VLAN identifier
46 * @param location host location 42 * @param location host location
47 - * @param ips of host IP addresses 43 + * @param ip host IP address
48 * @param annotations optional key/value annotations map 44 * @param annotations optional key/value annotations map
49 */ 45 */
50 public DefaultHostDescription(MacAddress mac, VlanId vlan, 46 public DefaultHostDescription(MacAddress mac, VlanId vlan,
51 - HostLocation location, Set<IpPrefix> ips, 47 + HostLocation location, IpPrefix ip,
52 SparseAnnotations... annotations) { 48 SparseAnnotations... annotations) {
53 super(annotations); 49 super(annotations);
54 this.mac = mac; 50 this.mac = mac;
55 this.vlan = vlan; 51 this.vlan = vlan;
56 this.location = location; 52 this.location = location;
57 - this.ips = new HashSet<>(ips); 53 + this.ip = ip;
58 } 54 }
59 55
60 @Override 56 @Override
...@@ -73,8 +69,8 @@ public class DefaultHostDescription extends AbstractDescription ...@@ -73,8 +69,8 @@ public class DefaultHostDescription extends AbstractDescription
73 } 69 }
74 70
75 @Override 71 @Override
76 - public Set<IpPrefix> ipAddresses() { 72 + public IpPrefix ipAddress() {
77 - return ImmutableSet.copyOf(ips); 73 + return ip;
78 } 74 }
79 75
80 @Override 76 @Override
...@@ -83,7 +79,7 @@ public class DefaultHostDescription extends AbstractDescription ...@@ -83,7 +79,7 @@ public class DefaultHostDescription extends AbstractDescription
83 .add("mac", mac) 79 .add("mac", mac)
84 .add("vlan", vlan) 80 .add("vlan", vlan)
85 .add("location", location) 81 .add("location", location)
86 - .add("ipAddresses", ips) 82 + .add("ipAddress", ip)
87 .toString(); 83 .toString();
88 } 84 }
89 85
......
1 package org.onlab.onos.net.host; 1 package org.onlab.onos.net.host;
2 2
3 -import java.util.Set;
4 -
5 import org.onlab.onos.net.Description; 3 import org.onlab.onos.net.Description;
6 import org.onlab.onos.net.HostLocation; 4 import org.onlab.onos.net.HostLocation;
7 import org.onlab.packet.IpPrefix; 5 import org.onlab.packet.IpPrefix;
...@@ -35,10 +33,10 @@ public interface HostDescription extends Description { ...@@ -35,10 +33,10 @@ public interface HostDescription extends Description {
35 HostLocation location(); 33 HostLocation location();
36 34
37 /** 35 /**
38 - * Returns zero or more IP address(es) associated with this host's MAC. 36 + * Returns the IP address associated with this host's MAC.
39 * 37 *
40 - * @return a set of IP addresses. 38 + * @return host IP address
41 */ 39 */
42 - Set<IpPrefix> ipAddresses(); 40 + IpPrefix ipAddress();
43 41
44 } 42 }
......
1 package org.onlab.onos.net.intent; 1 package org.onlab.onos.net.intent;
2 2
3 +import java.util.concurrent.Future;
4 +
5 +import org.onlab.onos.net.flow.CompletedBatchOperation;
6 +
3 /** 7 /**
4 * Abstraction of entity capable of installing intents to the environment. 8 * Abstraction of entity capable of installing intents to the environment.
5 */ 9 */
...@@ -10,7 +14,7 @@ public interface IntentInstaller<T extends InstallableIntent> { ...@@ -10,7 +14,7 @@ public interface IntentInstaller<T extends InstallableIntent> {
10 * @param intent intent to be installed 14 * @param intent intent to be installed
11 * @throws IntentException if issues are encountered while installing the intent 15 * @throws IntentException if issues are encountered while installing the intent
12 */ 16 */
13 - void install(T intent); 17 + Future<CompletedBatchOperation> install(T intent);
14 18
15 /** 19 /**
16 * Uninstalls the specified intent from the environment. 20 * Uninstalls the specified intent from the environment.
...@@ -18,5 +22,5 @@ public interface IntentInstaller<T extends InstallableIntent> { ...@@ -18,5 +22,5 @@ public interface IntentInstaller<T extends InstallableIntent> {
18 * @param intent intent to be uninstalled 22 * @param intent intent to be uninstalled
19 * @throws IntentException if issues are encountered while uninstalling the intent 23 * @throws IntentException if issues are encountered while uninstalling the intent
20 */ 24 */
21 - void uninstall(T intent); 25 + Future<CompletedBatchOperation> uninstall(T intent);
22 } 26 }
......
...@@ -33,6 +33,8 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { ...@@ -33,6 +33,8 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> {
33 33
34 /** 34 /**
35 * Returns the number of intents in the store. 35 * Returns the number of intents in the store.
36 + *
37 + * @return the number of intents in the store
36 */ 38 */
37 long getIntentCount(); 39 long getIntentCount();
38 40
...@@ -44,7 +46,7 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { ...@@ -44,7 +46,7 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> {
44 Iterable<Intent> getIntents(); 46 Iterable<Intent> getIntents();
45 47
46 /** 48 /**
47 - * Returns the intent with the specified identifer. 49 + * Returns the intent with the specified identifier.
48 * 50 *
49 * @param intentId intent identification 51 * @param intentId intent identification
50 * @return intent or null if not found 52 * @return intent or null if not found
...@@ -94,7 +96,6 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { ...@@ -94,7 +96,6 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> {
94 * specified original intent. 96 * specified original intent.
95 * 97 *
96 * @param intentId original intent identifier 98 * @param intentId original intent identifier
97 - * @return compiled state transition event
98 */ 99 */
99 void removeInstalledIntents(IntentId intentId); 100 void removeInstalledIntents(IntentId intentId);
100 101
......
...@@ -53,4 +53,4 @@ ...@@ -53,4 +53,4 @@
53 * while the system determines where to perform the compilation or while it 53 * while the system determines where to perform the compilation or while it
54 * performs global recomputation/optimization across all prior intents. 54 * performs global recomputation/optimization across all prior intents.
55 */ 55 */
56 -package org.onlab.onos.net.intent;
...\ No newline at end of file ...\ No newline at end of file
56 +package org.onlab.onos.net.intent;
......
1 package org.onlab.onos.store; 1 package org.onlab.onos.store;
2 2
3 +import java.util.List;
4 +
3 import org.onlab.onos.event.Event; 5 import org.onlab.onos.event.Event;
4 6
5 import static com.google.common.base.Preconditions.checkState; 7 import static com.google.common.base.Preconditions.checkState;
...@@ -41,4 +43,15 @@ public class AbstractStore<E extends Event, D extends StoreDelegate<E>> ...@@ -41,4 +43,15 @@ public class AbstractStore<E extends Event, D extends StoreDelegate<E>>
41 delegate.notify(event); 43 delegate.notify(event);
42 } 44 }
43 } 45 }
46 +
47 + /**
48 + * Notifies the delegate with the specified list of events.
49 + *
50 + * @param events list of events to delegate
51 + */
52 + protected void notifyDelegate(List<E> events) {
53 + for (E event: events) {
54 + notifyDelegate(event);
55 + }
56 + }
44 } 57 }
......
1 +package org.onlab.onos;
2 +
3 +import java.util.Objects;
4 +
5 +/**
6 + * Test application ID.
7 + */
8 +public class TestApplicationId implements ApplicationId {
9 +
10 + private final String name;
11 + private final short id;
12 +
13 + public TestApplicationId(String name) {
14 + this.name = name;
15 + this.id = (short) Objects.hash(name);
16 + }
17 +
18 + public static ApplicationId create(String name) {
19 + return new TestApplicationId(name);
20 + }
21 +
22 + @Override
23 + public short id() {
24 + return id;
25 + }
26 +
27 + @Override
28 + public String name() {
29 + return name;
30 + }
31 +}
1 +package org.onlab.onos.cluster;
2 +
3 +import static org.junit.Assert.*;
4 +import static org.onlab.onos.cluster.ControllerNodeToNodeId.toNodeId;
5 +
6 +import java.util.Arrays;
7 +import java.util.List;
8 +
9 +import org.junit.Test;
10 +import org.onlab.packet.IpPrefix;
11 +
12 +import com.google.common.collect.FluentIterable;
13 +
14 +
15 +public class ControllerNodeToNodeIdTest {
16 +
17 + private static final NodeId NID1 = new NodeId("foo");
18 + private static final NodeId NID2 = new NodeId("bar");
19 + private static final NodeId NID3 = new NodeId("buz");
20 +
21 + private static final IpPrefix IP1 = IpPrefix.valueOf("127.0.0.1");
22 + private static final IpPrefix IP2 = IpPrefix.valueOf("127.0.0.2");
23 + private static final IpPrefix IP3 = IpPrefix.valueOf("127.0.0.3");
24 +
25 + private static final ControllerNode CN1 = new DefaultControllerNode(NID1, IP1);
26 + private static final ControllerNode CN2 = new DefaultControllerNode(NID2, IP2);
27 + private static final ControllerNode CN3 = new DefaultControllerNode(NID3, IP3);
28 +
29 +
30 + @Test
31 + public final void testToNodeId() {
32 +
33 + final Iterable<ControllerNode> nodes = Arrays.asList(CN1, CN2, CN3);
34 + final List<NodeId> nodeIds = Arrays.asList(NID1, NID2, NID3);
35 +
36 + assertEquals(nodeIds,
37 + FluentIterable.from(nodes)
38 + .transform(toNodeId())
39 + .toList());
40 + }
41 +
42 +}
...@@ -9,6 +9,7 @@ import static org.onlab.onos.event.TestEvent.Type.FOO; ...@@ -9,6 +9,7 @@ import static org.onlab.onos.event.TestEvent.Type.FOO;
9 import java.util.List; 9 import java.util.List;
10 import java.util.Timer; 10 import java.util.Timer;
11 11
12 +import org.junit.Ignore;
12 import org.junit.Test; 13 import org.junit.Test;
13 14
14 /** 15 /**
...@@ -41,19 +42,23 @@ public class AbstractEventAccumulatorTest { ...@@ -41,19 +42,23 @@ public class AbstractEventAccumulatorTest {
41 assertEquals("incorrect batch", "abcde", accumulator.batch); 42 assertEquals("incorrect batch", "abcde", accumulator.batch);
42 } 43 }
43 44
45 + @Ignore("FIXME: timing sensitive test failing randomly.")
44 @Test 46 @Test
45 public void timeTrigger() { 47 public void timeTrigger() {
46 TestAccumulator accumulator = new TestAccumulator(); 48 TestAccumulator accumulator = new TestAccumulator();
47 accumulator.add(new TestEvent(FOO, "a")); 49 accumulator.add(new TestEvent(FOO, "a"));
48 - delay(40); 50 + delay(30);
49 assertTrue("should not have fired yet", accumulator.batch.isEmpty()); 51 assertTrue("should not have fired yet", accumulator.batch.isEmpty());
50 accumulator.add(new TestEvent(FOO, "b")); 52 accumulator.add(new TestEvent(FOO, "b"));
51 - delay(40); 53 + delay(30);
52 assertTrue("should not have fired yet", accumulator.batch.isEmpty()); 54 assertTrue("should not have fired yet", accumulator.batch.isEmpty());
53 accumulator.add(new TestEvent(FOO, "c")); 55 accumulator.add(new TestEvent(FOO, "c"));
54 - delay(40); 56 + delay(30);
57 + assertTrue("should not have fired yet", accumulator.batch.isEmpty());
58 + accumulator.add(new TestEvent(FOO, "d"));
59 + delay(30);
55 assertFalse("should have fired", accumulator.batch.isEmpty()); 60 assertFalse("should have fired", accumulator.batch.isEmpty());
56 - assertEquals("incorrect batch", "abc", accumulator.batch); 61 + assertEquals("incorrect batch", "abcd", accumulator.batch);
57 } 62 }
58 63
59 @Test 64 @Test
......
...@@ -18,8 +18,8 @@ public class DefaultEdgeLinkTest { ...@@ -18,8 +18,8 @@ public class DefaultEdgeLinkTest {
18 18
19 private static final ProviderId PID = new ProviderId("of", "foo"); 19 private static final ProviderId PID = new ProviderId("of", "foo");
20 private static final DeviceId DID1 = deviceId("of:foo"); 20 private static final DeviceId DID1 = deviceId("of:foo");
21 - private static final HostId HID1 = hostId("nic:foobar"); 21 + private static final HostId HID1 = hostId("00:00:00:00:00:01/-1");
22 - private static final HostId HID2 = hostId("nic:barfoo"); 22 + private static final HostId HID2 = hostId("00:00:00:00:00:01/-1");
23 private static final PortNumber P0 = portNumber(0); 23 private static final PortNumber P0 = portNumber(0);
24 private static final PortNumber P1 = portNumber(1); 24 private static final PortNumber P1 = portNumber(1);
25 25
...@@ -35,12 +35,8 @@ public class DefaultEdgeLinkTest { ...@@ -35,12 +35,8 @@ public class DefaultEdgeLinkTest {
35 EdgeLink l4 = new DefaultEdgeLink(PID, cp(HID2, P0), 35 EdgeLink l4 = new DefaultEdgeLink(PID, cp(HID2, P0),
36 new HostLocation(DID1, P1, 123L), false); 36 new HostLocation(DID1, P1, 123L), false);
37 37
38 - EdgeLink l5 = new DefaultEdgeLink(PID, cp(HID1, P0),
39 - new HostLocation(DID1, P1, 123L), false);
40 -
41 new EqualsTester().addEqualityGroup(l1, l2) 38 new EqualsTester().addEqualityGroup(l1, l2)
42 .addEqualityGroup(l3, l4) 39 .addEqualityGroup(l3, l4)
43 - .addEqualityGroup(l5)
44 .testEquals(); 40 .testEquals();
45 } 41 }
46 42
......
...@@ -8,7 +8,7 @@ import static org.onlab.onos.net.DeviceId.deviceId; ...@@ -8,7 +8,7 @@ import static org.onlab.onos.net.DeviceId.deviceId;
8 /** 8 /**
9 * Test of the device identifier. 9 * Test of the device identifier.
10 */ 10 */
11 -public class DeviceIdTest extends ElementIdTest { 11 +public class DeviceIdTest {
12 12
13 @Test 13 @Test
14 public void basics() { 14 public void basics() {
......
1 -package org.onlab.onos.net;
2 -
3 -import com.google.common.testing.EqualsTester;
4 -import org.junit.Test;
5 -
6 -import java.net.URI;
7 -
8 -import static org.junit.Assert.assertEquals;
9 -
10 -/**
11 - * Test of the network element identifier.
12 - */
13 -public class ElementIdTest {
14 -
15 - private static class FooId extends ElementId {
16 - public FooId(URI uri) {
17 - super(uri);
18 - }
19 - }
20 -
21 - public static URI uri(String str) {
22 - return URI.create(str);
23 - }
24 -
25 - @Test
26 - public void basics() {
27 - new EqualsTester()
28 - .addEqualityGroup(new FooId(uri("of:foo")),
29 - new FooId(uri("of:foo")))
30 - .addEqualityGroup(new FooId(uri("of:bar")))
31 - .testEquals();
32 - assertEquals("wrong uri", uri("ofcfg:foo"),
33 - new FooId(uri("ofcfg:foo")).uri());
34 - }
35 -
36 -}
...@@ -11,20 +11,18 @@ import static org.onlab.onos.net.HostId.hostId; ...@@ -11,20 +11,18 @@ import static org.onlab.onos.net.HostId.hostId;
11 /** 11 /**
12 * Test for the host identifier. 12 * Test for the host identifier.
13 */ 13 */
14 -public class HostIdTest extends ElementIdTest { 14 +public class HostIdTest {
15 15
16 private static final MacAddress MAC1 = MacAddress.valueOf("00:11:00:00:00:01"); 16 private static final MacAddress MAC1 = MacAddress.valueOf("00:11:00:00:00:01");
17 private static final MacAddress MAC2 = MacAddress.valueOf("00:22:00:00:00:02"); 17 private static final MacAddress MAC2 = MacAddress.valueOf("00:22:00:00:00:02");
18 private static final VlanId VLAN1 = VlanId.vlanId((short) 11); 18 private static final VlanId VLAN1 = VlanId.vlanId((short) 11);
19 private static final VlanId VLAN2 = VlanId.vlanId((short) 22); 19 private static final VlanId VLAN2 = VlanId.vlanId((short) 22);
20 20
21 - @Override
22 @Test 21 @Test
23 public void basics() { 22 public void basics() {
24 new EqualsTester() 23 new EqualsTester()
25 - .addEqualityGroup(hostId("nic:00:11:00:00:00:01-11"), 24 + .addEqualityGroup(hostId(MAC1, VLAN1), hostId(MAC1, VLAN1))
26 - hostId(MAC1, VLAN1)) 25 + .addEqualityGroup(hostId(MAC2, VLAN2), hostId(MAC2, VLAN2))
27 - .addEqualityGroup(hostId(MAC2, VLAN2))
28 .testEquals(); 26 .testEquals();
29 } 27 }
30 28
......
...@@ -31,7 +31,7 @@ public final class NetTestTools { ...@@ -31,7 +31,7 @@ public final class NetTestTools {
31 31
32 // Short-hand for producing a host id from a string 32 // Short-hand for producing a host id from a string
33 public static HostId hid(String id) { 33 public static HostId hid(String id) {
34 - return hostId("nic:" + id); 34 + return hostId(id);
35 } 35 }
36 36
37 // Crates a new device with the specified id 37 // Crates a new device with the specified id
......
...@@ -10,9 +10,8 @@ import com.google.common.testing.EqualsTester; ...@@ -10,9 +10,8 @@ import com.google.common.testing.EqualsTester;
10 /** 10 /**
11 * Test of the port number. 11 * Test of the port number.
12 */ 12 */
13 -public class PortNumberTest extends ElementIdTest { 13 +public class PortNumberTest {
14 14
15 - @Override
16 @Test 15 @Test
17 public void basics() { 16 public void basics() {
18 new EqualsTester() 17 new EqualsTester()
......
1 package org.onlab.onos.net.host; 1 package org.onlab.onos.net.host;
2 2
3 -import static org.junit.Assert.assertEquals;
4 -import static org.junit.Assert.assertTrue;
5 -
6 -import java.util.Set;
7 -
8 import org.junit.Test; 3 import org.junit.Test;
9 import org.onlab.onos.net.DeviceId; 4 import org.onlab.onos.net.DeviceId;
10 import org.onlab.onos.net.HostLocation; 5 import org.onlab.onos.net.HostLocation;
...@@ -13,7 +8,8 @@ import org.onlab.packet.IpPrefix; ...@@ -13,7 +8,8 @@ import org.onlab.packet.IpPrefix;
13 import org.onlab.packet.MacAddress; 8 import org.onlab.packet.MacAddress;
14 import org.onlab.packet.VlanId; 9 import org.onlab.packet.VlanId;
15 10
16 -import com.google.common.collect.Sets; 11 +import static org.junit.Assert.assertEquals;
12 +import static org.junit.Assert.assertTrue;
17 13
18 /** 14 /**
19 * Test for the default host description. 15 * Test for the default host description.
...@@ -22,24 +18,22 @@ public class DefualtHostDecriptionTest { ...@@ -22,24 +18,22 @@ public class DefualtHostDecriptionTest {
22 18
23 private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01"); 19 private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01");
24 private static final VlanId VLAN = VlanId.vlanId((short) 10); 20 private static final VlanId VLAN = VlanId.vlanId((short) 10);
21 + private static final IpPrefix IP = IpPrefix.valueOf("10.0.0.1");
22 +
25 private static final HostLocation LOC = new HostLocation( 23 private static final HostLocation LOC = new HostLocation(
26 - DeviceId.deviceId("of:foo"), 24 + DeviceId.deviceId("of:foo"),
27 - PortNumber.portNumber(100), 25 + PortNumber.portNumber(100),
28 - 123L 26 + 123L
29 - ); 27 + );
30 - private static final Set<IpPrefix> IPS = Sets.newHashSet(
31 - IpPrefix.valueOf("10.0.0.1"),
32 - IpPrefix.valueOf("10.0.0.2")
33 - );
34 28
35 @Test 29 @Test
36 public void basics() { 30 public void basics() {
37 HostDescription host = 31 HostDescription host =
38 - new DefaultHostDescription(MAC, VLAN, LOC, IPS); 32 + new DefaultHostDescription(MAC, VLAN, LOC, IP);
39 assertEquals("incorrect mac", MAC, host.hwAddress()); 33 assertEquals("incorrect mac", MAC, host.hwAddress());
40 assertEquals("incorrect vlan", VLAN, host.vlan()); 34 assertEquals("incorrect vlan", VLAN, host.vlan());
41 assertEquals("incorrect location", LOC, host.location()); 35 assertEquals("incorrect location", LOC, host.location());
42 - assertTrue("incorrect ip's", IPS.equals(host.ipAddresses())); 36 + assertEquals("incorrect ip's", IP, host.ipAddress());
43 assertTrue("incorrect toString", host.toString().contains("vlan=10")); 37 assertTrue("incorrect toString", host.toString().contains("vlan=10"));
44 } 38 }
45 39
......
1 package org.onlab.onos.net.intent; 1 package org.onlab.onos.net.intent;
2 2
3 -import org.junit.After; 3 +import static org.junit.Assert.assertEquals;
4 -import org.junit.Before; 4 +import static org.junit.Assert.assertFalse;
5 -import org.junit.Test; 5 +import static org.junit.Assert.assertNull;
6 +import static org.junit.Assert.fail;
7 +import static org.onlab.onos.net.intent.IntentEvent.Type.FAILED;
8 +import static org.onlab.onos.net.intent.IntentEvent.Type.INSTALLED;
9 +import static org.onlab.onos.net.intent.IntentEvent.Type.SUBMITTED;
10 +import static org.onlab.onos.net.intent.IntentEvent.Type.WITHDRAWN;
6 11
7 import java.util.ArrayList; 12 import java.util.ArrayList;
8 import java.util.Arrays; 13 import java.util.Arrays;
9 import java.util.Collections; 14 import java.util.Collections;
10 import java.util.Iterator; 15 import java.util.Iterator;
11 import java.util.List; 16 import java.util.List;
17 +import java.util.concurrent.Future;
12 18
13 -import static org.junit.Assert.*; 19 +import org.junit.After;
14 -import static org.onlab.onos.net.intent.IntentEvent.Type.*; 20 +import org.junit.Before;
21 +import org.junit.Test;
22 +import org.onlab.onos.net.flow.CompletedBatchOperation;
15 23
16 /** 24 /**
17 * Suite of tests for the intent service contract. 25 * Suite of tests for the intent service contract.
...@@ -290,17 +298,19 @@ public class IntentServiceTest { ...@@ -290,17 +298,19 @@ public class IntentServiceTest {
290 } 298 }
291 299
292 @Override 300 @Override
293 - public void install(TestInstallableIntent intent) { 301 + public Future<CompletedBatchOperation> install(TestInstallableIntent intent) {
294 if (fail) { 302 if (fail) {
295 throw new IntentException("install failed by design"); 303 throw new IntentException("install failed by design");
296 } 304 }
305 + return null;
297 } 306 }
298 307
299 @Override 308 @Override
300 - public void uninstall(TestInstallableIntent intent) { 309 + public Future<CompletedBatchOperation> uninstall(TestInstallableIntent intent) {
301 if (fail) { 310 if (fail) {
302 throw new IntentException("remove failed by design"); 311 throw new IntentException("remove failed by design");
303 } 312 }
313 + return null;
304 } 314 }
305 } 315 }
306 316
......
1 -package org.onlab.onos.cluster.impl; 1 +package org.onlab.onos.impl;
2 2
3 import org.apache.felix.scr.annotations.Activate; 3 import org.apache.felix.scr.annotations.Activate;
4 import org.apache.felix.scr.annotations.Component; 4 import org.apache.felix.scr.annotations.Component;
5 import org.apache.felix.scr.annotations.Service; 5 import org.apache.felix.scr.annotations.Service;
6 +import org.onlab.onos.ApplicationId;
6 import org.onlab.onos.CoreService; 7 import org.onlab.onos.CoreService;
7 import org.onlab.onos.Version; 8 import org.onlab.onos.Version;
8 import org.onlab.util.Tools; 9 import org.onlab.util.Tools;
9 10
10 import java.io.File; 11 import java.io.File;
11 import java.util.List; 12 import java.util.List;
13 +import java.util.Map;
14 +import java.util.concurrent.ConcurrentHashMap;
15 +import java.util.concurrent.atomic.AtomicInteger;
12 16
13 /** 17 /**
14 * Core service implementation. 18 * Core service implementation.
...@@ -17,9 +21,13 @@ import java.util.List; ...@@ -17,9 +21,13 @@ import java.util.List;
17 @Service 21 @Service
18 public class CoreManager implements CoreService { 22 public class CoreManager implements CoreService {
19 23
24 + private static final AtomicInteger ID_DISPENSER = new AtomicInteger(1);
25 +
20 private static final File VERSION_FILE = new File("../VERSION"); 26 private static final File VERSION_FILE = new File("../VERSION");
21 private static Version version = Version.version("1.0.0-SNAPSHOT"); 27 private static Version version = Version.version("1.0.0-SNAPSHOT");
22 28
29 + private final Map<Short, DefaultApplicationId> appIds = new ConcurrentHashMap<>();
30 +
23 // TODO: work in progress 31 // TODO: work in progress
24 32
25 @Activate 33 @Activate
...@@ -35,4 +43,17 @@ public class CoreManager implements CoreService { ...@@ -35,4 +43,17 @@ public class CoreManager implements CoreService {
35 return version; 43 return version;
36 } 44 }
37 45
46 + @Override
47 + public ApplicationId getAppId(Short id) {
48 + return appIds.get(id);
49 + }
50 +
51 + @Override
52 + public ApplicationId registerApplication(String name) {
53 + short id = (short) ID_DISPENSER.getAndIncrement();
54 + DefaultApplicationId appId = new DefaultApplicationId(id, name);
55 + appIds.put(id, appId);
56 + return appId;
57 + }
58 +
38 } 59 }
......
1 +package org.onlab.onos.impl;
2 +
3 +import org.onlab.onos.ApplicationId;
4 +
5 +import java.util.Objects;
6 +
7 +import static com.google.common.base.MoreObjects.toStringHelper;
8 +
9 +/**
10 + * Application id generator class.
11 + */
12 +public class DefaultApplicationId implements ApplicationId {
13 +
14 + private final short id;
15 + private final String name;
16 +
17 + // Ban public construction
18 + protected DefaultApplicationId(Short id, String identifier) {
19 + this.id = id;
20 + this.name = identifier;
21 + }
22 +
23 + @Override
24 + public short id() {
25 + return id;
26 + }
27 +
28 + @Override
29 + public String name() {
30 + return name;
31 + }
32 +
33 + @Override
34 + public int hashCode() {
35 + return Objects.hash(id);
36 + }
37 +
38 + @Override
39 + public boolean equals(Object obj) {
40 + if (this == obj) {
41 + return true;
42 + }
43 + if (obj instanceof DefaultApplicationId) {
44 + DefaultApplicationId other = (DefaultApplicationId) obj;
45 + return Objects.equals(this.id, other.id);
46 + }
47 + return false;
48 + }
49 +
50 + @Override
51 + public String toString() {
52 + return toStringHelper(this).add("id", id).add("name", name).toString();
53 + }
54 +
55 +}
1 +/**
2 + *
3 + */
4 +package org.onlab.onos.impl;
...\ No newline at end of file ...\ No newline at end of file
...@@ -5,10 +5,12 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -5,10 +5,12 @@ import static org.slf4j.LoggerFactory.getLogger;
5 5
6 import java.util.Iterator; 6 import java.util.Iterator;
7 import java.util.List; 7 import java.util.List;
8 +import java.util.concurrent.CancellationException;
8 import java.util.concurrent.ExecutionException; 9 import java.util.concurrent.ExecutionException;
9 import java.util.concurrent.Future; 10 import java.util.concurrent.Future;
10 import java.util.concurrent.TimeUnit; 11 import java.util.concurrent.TimeUnit;
11 import java.util.concurrent.TimeoutException; 12 import java.util.concurrent.TimeoutException;
13 +import java.util.concurrent.atomic.AtomicReference;
12 14
13 import org.apache.felix.scr.annotations.Activate; 15 import org.apache.felix.scr.annotations.Activate;
14 import org.apache.felix.scr.annotations.Component; 16 import org.apache.felix.scr.annotations.Component;
...@@ -26,6 +28,7 @@ import org.onlab.onos.net.flow.CompletedBatchOperation; ...@@ -26,6 +28,7 @@ import org.onlab.onos.net.flow.CompletedBatchOperation;
26 import org.onlab.onos.net.flow.FlowEntry; 28 import org.onlab.onos.net.flow.FlowEntry;
27 import org.onlab.onos.net.flow.FlowRule; 29 import org.onlab.onos.net.flow.FlowRule;
28 import org.onlab.onos.net.flow.FlowRuleBatchEntry; 30 import org.onlab.onos.net.flow.FlowRuleBatchEntry;
31 +import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
29 import org.onlab.onos.net.flow.FlowRuleBatchOperation; 32 import org.onlab.onos.net.flow.FlowRuleBatchOperation;
30 import org.onlab.onos.net.flow.FlowRuleEvent; 33 import org.onlab.onos.net.flow.FlowRuleEvent;
31 import org.onlab.onos.net.flow.FlowRuleListener; 34 import org.onlab.onos.net.flow.FlowRuleListener;
...@@ -52,6 +55,8 @@ public class FlowRuleManager ...@@ -52,6 +55,8 @@ public class FlowRuleManager
52 extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService> 55 extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService>
53 implements FlowRuleService, FlowRuleProviderRegistry { 56 implements FlowRuleService, FlowRuleProviderRegistry {
54 57
58 + enum BatchState { STARTED, FINISHED, CANCELLED };
59 +
55 public static final String FLOW_RULE_NULL = "FlowRule cannot be null"; 60 public static final String FLOW_RULE_NULL = "FlowRule cannot be null";
56 private final Logger log = getLogger(getClass()); 61 private final Logger log = getLogger(getClass());
57 62
...@@ -144,7 +149,7 @@ public class FlowRuleManager ...@@ -144,7 +149,7 @@ public class FlowRuleManager
144 FlowRuleBatchOperation batch) { 149 FlowRuleBatchOperation batch) {
145 Multimap<FlowRuleProvider, FlowRuleBatchEntry> batches = 150 Multimap<FlowRuleProvider, FlowRuleBatchEntry> batches =
146 ArrayListMultimap.create(); 151 ArrayListMultimap.create();
147 - List<Future<Void>> futures = Lists.newArrayList(); 152 + List<Future<CompletedBatchOperation>> futures = Lists.newArrayList();
148 for (FlowRuleBatchEntry fbe : batch.getOperations()) { 153 for (FlowRuleBatchEntry fbe : batch.getOperations()) {
149 final FlowRule f = fbe.getTarget(); 154 final FlowRule f = fbe.getTarget();
150 final Device device = deviceService.getDevice(f.deviceId()); 155 final Device device = deviceService.getDevice(f.deviceId());
...@@ -165,10 +170,10 @@ public class FlowRuleManager ...@@ -165,10 +170,10 @@ public class FlowRuleManager
165 for (FlowRuleProvider provider : batches.keySet()) { 170 for (FlowRuleProvider provider : batches.keySet()) {
166 FlowRuleBatchOperation b = 171 FlowRuleBatchOperation b =
167 new FlowRuleBatchOperation(batches.get(provider)); 172 new FlowRuleBatchOperation(batches.get(provider));
168 - Future<Void> future = provider.executeBatch(b); 173 + Future<CompletedBatchOperation> future = provider.executeBatch(b);
169 futures.add(future); 174 futures.add(future);
170 } 175 }
171 - return new FlowRuleBatchFuture(futures); 176 + return new FlowRuleBatchFuture(futures, batches);
172 } 177 }
173 178
174 @Override 179 @Override
...@@ -341,59 +346,140 @@ public class FlowRuleManager ...@@ -341,59 +346,140 @@ public class FlowRuleManager
341 private class FlowRuleBatchFuture 346 private class FlowRuleBatchFuture
342 implements Future<CompletedBatchOperation> { 347 implements Future<CompletedBatchOperation> {
343 348
344 - private final List<Future<Void>> futures; 349 + private final List<Future<CompletedBatchOperation>> futures;
350 + private final Multimap<FlowRuleProvider, FlowRuleBatchEntry> batches;
351 + private final AtomicReference<BatchState> state;
352 + private CompletedBatchOperation overall;
353 +
354 +
345 355
346 - public FlowRuleBatchFuture(List<Future<Void>> futures) { 356 + public FlowRuleBatchFuture(List<Future<CompletedBatchOperation>> futures,
357 + Multimap<FlowRuleProvider, FlowRuleBatchEntry> batches) {
347 this.futures = futures; 358 this.futures = futures;
359 + this.batches = batches;
360 + state = new AtomicReference<FlowRuleManager.BatchState>();
361 + state.set(BatchState.STARTED);
348 } 362 }
349 363
350 @Override 364 @Override
351 public boolean cancel(boolean mayInterruptIfRunning) { 365 public boolean cancel(boolean mayInterruptIfRunning) {
352 - // TODO Auto-generated method stub 366 + if (state.get() == BatchState.FINISHED) {
353 - return false; 367 + return false;
368 + }
369 + if (!state.compareAndSet(BatchState.STARTED, BatchState.CANCELLED)) {
370 + return false;
371 + }
372 + cleanUpBatch();
373 + for (Future<CompletedBatchOperation> f : futures) {
374 + f.cancel(mayInterruptIfRunning);
375 + }
376 + return true;
354 } 377 }
355 378
356 @Override 379 @Override
357 public boolean isCancelled() { 380 public boolean isCancelled() {
358 - // TODO Auto-generated method stub 381 + return state.get() == BatchState.CANCELLED;
359 - return false;
360 } 382 }
361 383
362 @Override 384 @Override
363 public boolean isDone() { 385 public boolean isDone() {
364 - boolean isDone = true; 386 + return state.get() == BatchState.FINISHED;
365 - for (Future<Void> future : futures) {
366 - isDone &= future.isDone();
367 - }
368 - return isDone;
369 } 387 }
370 388
389 +
371 @Override 390 @Override
372 public CompletedBatchOperation get() throws InterruptedException, 391 public CompletedBatchOperation get() throws InterruptedException,
373 - ExecutionException { 392 + ExecutionException {
374 - // TODO Auto-generated method stub 393 +
375 - for (Future<Void> future : futures) { 394 + if (isDone()) {
376 - future.get(); 395 + return overall;
396 + }
397 +
398 + boolean success = true;
399 + List<FlowEntry> failed = Lists.newLinkedList();
400 + CompletedBatchOperation completed;
401 + for (Future<CompletedBatchOperation> future : futures) {
402 + completed = future.get();
403 + success = validateBatchOperation(failed, completed, future);
377 } 404 }
378 - return new CompletedBatchOperation(); 405 +
406 + return finalizeBatchOperation(success, failed);
407 +
379 } 408 }
380 409
381 @Override 410 @Override
382 public CompletedBatchOperation get(long timeout, TimeUnit unit) 411 public CompletedBatchOperation get(long timeout, TimeUnit unit)
383 throws InterruptedException, ExecutionException, 412 throws InterruptedException, ExecutionException,
384 TimeoutException { 413 TimeoutException {
385 - // TODO we should decrement the timeout 414 +
415 + if (isDone()) {
416 + return overall;
417 + }
418 + boolean success = true;
419 + List<FlowEntry> failed = Lists.newLinkedList();
420 + CompletedBatchOperation completed;
386 long start = System.nanoTime(); 421 long start = System.nanoTime();
387 long end = start + unit.toNanos(timeout); 422 long end = start + unit.toNanos(timeout);
388 - for (Future<Void> future : futures) { 423 +
424 + for (Future<CompletedBatchOperation> future : futures) {
389 long now = System.nanoTime(); 425 long now = System.nanoTime();
390 long thisTimeout = end - now; 426 long thisTimeout = end - now;
391 - future.get(thisTimeout, TimeUnit.NANOSECONDS); 427 + completed = future.get(thisTimeout, TimeUnit.NANOSECONDS);
428 + success = validateBatchOperation(failed, completed, future);
392 } 429 }
393 - return new CompletedBatchOperation(); 430 + return finalizeBatchOperation(success, failed);
394 } 431 }
395 432
433 + private boolean validateBatchOperation(List<FlowEntry> failed,
434 + CompletedBatchOperation completed,
435 + Future<CompletedBatchOperation> future) {
436 +
437 + if (isCancelled()) {
438 + throw new CancellationException();
439 + }
440 + if (!completed.isSuccess()) {
441 + failed.addAll(completed.failedItems());
442 + cleanUpBatch();
443 + cancelAllSubBatches();
444 + return false;
445 + }
446 + return true;
447 + }
448 +
449 + private void cancelAllSubBatches() {
450 + for (Future<CompletedBatchOperation> f : futures) {
451 + f.cancel(true);
452 + }
453 + }
454 +
455 + private CompletedBatchOperation finalizeBatchOperation(boolean success,
456 + List<FlowEntry> failed) {
457 + synchronized (this) {
458 + if (!state.compareAndSet(BatchState.STARTED, BatchState.FINISHED)) {
459 + if (state.get() == BatchState.FINISHED) {
460 + return overall;
461 + }
462 + throw new CancellationException();
463 + }
464 + overall = new CompletedBatchOperation(success, failed);
465 + return overall;
466 + }
467 + }
468 +
469 + private void cleanUpBatch() {
470 + for (FlowRuleBatchEntry fbe : batches.values()) {
471 + if (fbe.getOperator() == FlowRuleOperation.ADD ||
472 + fbe.getOperator() == FlowRuleOperation.MODIFY) {
473 + store.deleteFlowRule(fbe.getTarget());
474 + } else if (fbe.getOperator() == FlowRuleOperation.REMOVE) {
475 + store.storeFlowRule(fbe.getTarget());
476 + }
477 + }
478 +
479 + }
396 } 480 }
397 481
398 482
483 +
484 +
399 } 485 }
......
...@@ -168,7 +168,6 @@ public class HostManager ...@@ -168,7 +168,6 @@ public class HostManager
168 checkNotNull(hostId, HOST_ID_NULL); 168 checkNotNull(hostId, HOST_ID_NULL);
169 HostEvent event = store.removeHost(hostId); 169 HostEvent event = store.removeHost(hostId);
170 if (event != null) { 170 if (event != null) {
171 - log.info("Host {} administratively removed", hostId);
172 post(event); 171 post(event);
173 } 172 }
174 } 173 }
...@@ -214,7 +213,6 @@ public class HostManager ...@@ -214,7 +213,6 @@ public class HostManager
214 HostEvent event = store.createOrUpdateHost(provider().id(), hostId, 213 HostEvent event = store.createOrUpdateHost(provider().id(), hostId,
215 hostDescription); 214 hostDescription);
216 if (event != null) { 215 if (event != null) {
217 - log.debug("Host {} detected", hostId);
218 post(event); 216 post(event);
219 } 217 }
220 } 218 }
...@@ -225,7 +223,6 @@ public class HostManager ...@@ -225,7 +223,6 @@ public class HostManager
225 checkValidity(); 223 checkValidity();
226 HostEvent event = store.removeHost(hostId); 224 HostEvent event = store.removeHost(hostId);
227 if (event != null) { 225 if (event != null) {
228 - log.debug("Host {} vanished", hostId);
229 post(event); 226 post(event);
230 } 227 }
231 } 228 }
......
...@@ -13,12 +13,17 @@ import static org.onlab.util.Tools.namedThreads; ...@@ -13,12 +13,17 @@ import static org.onlab.util.Tools.namedThreads;
13 import static org.slf4j.LoggerFactory.getLogger; 13 import static org.slf4j.LoggerFactory.getLogger;
14 14
15 import java.util.ArrayList; 15 import java.util.ArrayList;
16 +import java.util.Iterator;
16 import java.util.List; 17 import java.util.List;
17 import java.util.Map; 18 import java.util.Map;
18 import java.util.Objects; 19 import java.util.Objects;
19 import java.util.concurrent.ConcurrentHashMap; 20 import java.util.concurrent.ConcurrentHashMap;
20 import java.util.concurrent.ConcurrentMap; 21 import java.util.concurrent.ConcurrentMap;
22 +import java.util.concurrent.ExecutionException;
21 import java.util.concurrent.ExecutorService; 23 import java.util.concurrent.ExecutorService;
24 +import java.util.concurrent.Future;
25 +import java.util.concurrent.TimeUnit;
26 +import java.util.concurrent.TimeoutException;
22 27
23 import org.apache.felix.scr.annotations.Activate; 28 import org.apache.felix.scr.annotations.Activate;
24 import org.apache.felix.scr.annotations.Component; 29 import org.apache.felix.scr.annotations.Component;
...@@ -28,6 +33,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -28,6 +33,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
28 import org.apache.felix.scr.annotations.Service; 33 import org.apache.felix.scr.annotations.Service;
29 import org.onlab.onos.event.AbstractListenerRegistry; 34 import org.onlab.onos.event.AbstractListenerRegistry;
30 import org.onlab.onos.event.EventDeliveryService; 35 import org.onlab.onos.event.EventDeliveryService;
36 +import org.onlab.onos.net.flow.CompletedBatchOperation;
31 import org.onlab.onos.net.intent.InstallableIntent; 37 import org.onlab.onos.net.intent.InstallableIntent;
32 import org.onlab.onos.net.intent.Intent; 38 import org.onlab.onos.net.intent.Intent;
33 import org.onlab.onos.net.intent.IntentCompiler; 39 import org.onlab.onos.net.intent.IntentCompiler;
...@@ -44,7 +50,9 @@ import org.onlab.onos.net.intent.IntentStore; ...@@ -44,7 +50,9 @@ import org.onlab.onos.net.intent.IntentStore;
44 import org.onlab.onos.net.intent.IntentStoreDelegate; 50 import org.onlab.onos.net.intent.IntentStoreDelegate;
45 import org.slf4j.Logger; 51 import org.slf4j.Logger;
46 52
53 +import com.google.common.collect.ImmutableList;
47 import com.google.common.collect.ImmutableMap; 54 import com.google.common.collect.ImmutableMap;
55 +import com.google.common.collect.Lists;
48 56
49 /** 57 /**
50 * An implementation of Intent Manager. 58 * An implementation of Intent Manager.
...@@ -67,7 +75,8 @@ public class IntentManager ...@@ -67,7 +75,8 @@ public class IntentManager
67 private final AbstractListenerRegistry<IntentEvent, IntentListener> 75 private final AbstractListenerRegistry<IntentEvent, IntentListener>
68 listenerRegistry = new AbstractListenerRegistry<>(); 76 listenerRegistry = new AbstractListenerRegistry<>();
69 77
70 - private final ExecutorService executor = newSingleThreadExecutor(namedThreads("onos-intents")); 78 + private ExecutorService executor;
79 + private ExecutorService monitorExecutor;
71 80
72 private final IntentStoreDelegate delegate = new InternalStoreDelegate(); 81 private final IntentStoreDelegate delegate = new InternalStoreDelegate();
73 private final TopologyChangeDelegate topoDelegate = new InternalTopoChangeDelegate(); 82 private final TopologyChangeDelegate topoDelegate = new InternalTopoChangeDelegate();
...@@ -86,6 +95,8 @@ public class IntentManager ...@@ -86,6 +95,8 @@ public class IntentManager
86 store.setDelegate(delegate); 95 store.setDelegate(delegate);
87 trackerService.setDelegate(topoDelegate); 96 trackerService.setDelegate(topoDelegate);
88 eventDispatcher.addSink(IntentEvent.class, listenerRegistry); 97 eventDispatcher.addSink(IntentEvent.class, listenerRegistry);
98 + executor = newSingleThreadExecutor(namedThreads("onos-intents"));
99 + monitorExecutor = newSingleThreadExecutor(namedThreads("onos-intent-monitor"));
89 log.info("Started"); 100 log.info("Started");
90 } 101 }
91 102
...@@ -94,6 +105,8 @@ public class IntentManager ...@@ -94,6 +105,8 @@ public class IntentManager
94 store.unsetDelegate(delegate); 105 store.unsetDelegate(delegate);
95 trackerService.unsetDelegate(topoDelegate); 106 trackerService.unsetDelegate(topoDelegate);
96 eventDispatcher.removeSink(IntentEvent.class); 107 eventDispatcher.removeSink(IntentEvent.class);
108 + executor.shutdown();
109 + monitorExecutor.shutdown();
97 log.info("Stopped"); 110 log.info("Stopped");
98 } 111 }
99 112
...@@ -240,14 +253,23 @@ public class IntentManager ...@@ -240,14 +253,23 @@ public class IntentManager
240 } 253 }
241 } 254 }
242 255
243 - // FIXME: To make SDN-IP workable ASAP, only single level compilation is implemented 256 + /**
244 - // TODO: implement compilation traversing tree structure 257 + * Compiles an intent recursively.
258 + *
259 + * @param intent intent
260 + * @return result of compilation
261 + */
245 private List<InstallableIntent> compileIntent(Intent intent) { 262 private List<InstallableIntent> compileIntent(Intent intent) {
263 + if (intent instanceof InstallableIntent) {
264 + return ImmutableList.of((InstallableIntent) intent);
265 + }
266 +
246 List<InstallableIntent> installable = new ArrayList<>(); 267 List<InstallableIntent> installable = new ArrayList<>();
268 + // TODO do we need to registerSubclassCompiler?
247 for (Intent compiled : getCompiler(intent).compile(intent)) { 269 for (Intent compiled : getCompiler(intent).compile(intent)) {
248 - InstallableIntent installableIntent = (InstallableIntent) compiled; 270 + installable.addAll(compileIntent(compiled));
249 - installable.add(installableIntent);
250 } 271 }
272 +
251 return installable; 273 return installable;
252 } 274 }
253 275
...@@ -261,6 +283,7 @@ public class IntentManager ...@@ -261,6 +283,7 @@ public class IntentManager
261 // Indicate that the intent is entering the installing phase. 283 // Indicate that the intent is entering the installing phase.
262 store.setState(intent, INSTALLING); 284 store.setState(intent, INSTALLING);
263 285
286 + List<Future<CompletedBatchOperation>> installFutures = Lists.newArrayList();
264 try { 287 try {
265 List<InstallableIntent> installables = store.getInstallableIntents(intent.id()); 288 List<InstallableIntent> installables = store.getInstallableIntents(intent.id());
266 if (installables != null) { 289 if (installables != null) {
...@@ -268,17 +291,20 @@ public class IntentManager ...@@ -268,17 +291,20 @@ public class IntentManager
268 registerSubclassInstallerIfNeeded(installable); 291 registerSubclassInstallerIfNeeded(installable);
269 trackerService.addTrackedResources(intent.id(), 292 trackerService.addTrackedResources(intent.id(),
270 installable.requiredLinks()); 293 installable.requiredLinks());
271 - getInstaller(installable).install(installable); 294 + Future<CompletedBatchOperation> future = getInstaller(installable).install(installable);
295 + installFutures.add(future);
272 } 296 }
273 } 297 }
274 - eventDispatcher.post(store.setState(intent, INSTALLED)); 298 + // FIXME we have to wait for the installable intents
275 - 299 + //eventDispatcher.post(store.setState(intent, INSTALLED));
300 + monitorExecutor.execute(new IntentInstallMonitor(intent, installFutures, INSTALLED));
276 } catch (Exception e) { 301 } catch (Exception e) {
277 log.warn("Unable to install intent {} due to: {}", intent.id(), e); 302 log.warn("Unable to install intent {} due to: {}", intent.id(), e);
278 - uninstallIntent(intent); 303 + uninstallIntent(intent, RECOMPILING);
279 304
280 // If compilation failed, kick off the recompiling phase. 305 // If compilation failed, kick off the recompiling phase.
281 - executeRecompilingPhase(intent); 306 + // FIXME
307 + //executeRecompilingPhase(intent);
282 } 308 }
283 } 309 }
284 310
...@@ -327,12 +353,14 @@ public class IntentManager ...@@ -327,12 +353,14 @@ public class IntentManager
327 private void executeWithdrawingPhase(Intent intent) { 353 private void executeWithdrawingPhase(Intent intent) {
328 // Indicate that the intent is being withdrawn. 354 // Indicate that the intent is being withdrawn.
329 store.setState(intent, WITHDRAWING); 355 store.setState(intent, WITHDRAWING);
330 - uninstallIntent(intent); 356 + uninstallIntent(intent, WITHDRAWN);
331 357
332 // If all went well, disassociate the top-level intent with its 358 // If all went well, disassociate the top-level intent with its
333 // installable derivatives and mark it as withdrawn. 359 // installable derivatives and mark it as withdrawn.
334 - store.removeInstalledIntents(intent.id()); 360 + // FIXME need to clean up
335 - eventDispatcher.post(store.setState(intent, WITHDRAWN)); 361 + //store.removeInstalledIntents(intent.id());
362 + // FIXME
363 + //eventDispatcher.post(store.setState(intent, WITHDRAWN));
336 } 364 }
337 365
338 /** 366 /**
...@@ -340,14 +368,17 @@ public class IntentManager ...@@ -340,14 +368,17 @@ public class IntentManager
340 * 368 *
341 * @param intent intent to be uninstalled 369 * @param intent intent to be uninstalled
342 */ 370 */
343 - private void uninstallIntent(Intent intent) { 371 + private void uninstallIntent(Intent intent, IntentState nextState) {
372 + List<Future<CompletedBatchOperation>> uninstallFutures = Lists.newArrayList();
344 try { 373 try {
345 List<InstallableIntent> installables = store.getInstallableIntents(intent.id()); 374 List<InstallableIntent> installables = store.getInstallableIntents(intent.id());
346 if (installables != null) { 375 if (installables != null) {
347 for (InstallableIntent installable : installables) { 376 for (InstallableIntent installable : installables) {
348 - getInstaller(installable).uninstall(installable); 377 + Future<CompletedBatchOperation> future = getInstaller(installable).uninstall(installable);
378 + uninstallFutures.add(future);
349 } 379 }
350 } 380 }
381 + monitorExecutor.execute(new IntentInstallMonitor(intent, uninstallFutures, nextState));
351 } catch (IntentException e) { 382 } catch (IntentException e) {
352 log.warn("Unable to uninstall intent {} due to: {}", intent.id(), e); 383 log.warn("Unable to uninstall intent {} due to: {}", intent.id(), e);
353 } 384 }
...@@ -422,9 +453,10 @@ public class IntentManager ...@@ -422,9 +453,10 @@ public class IntentManager
422 // Attempt recompilation of the specified intents first. 453 // Attempt recompilation of the specified intents first.
423 for (IntentId intentId : intentIds) { 454 for (IntentId intentId : intentIds) {
424 Intent intent = getIntent(intentId); 455 Intent intent = getIntent(intentId);
425 - uninstallIntent(intent); 456 + uninstallIntent(intent, RECOMPILING);
426 457
427 - executeRecompilingPhase(intent); 458 + //FIXME
459 + //executeRecompilingPhase(intent);
428 } 460 }
429 461
430 if (compileAllFailed) { 462 if (compileAllFailed) {
...@@ -460,4 +492,49 @@ public class IntentManager ...@@ -460,4 +492,49 @@ public class IntentManager
460 } 492 }
461 } 493 }
462 494
495 + private class IntentInstallMonitor implements Runnable {
496 +
497 + private final Intent intent;
498 + private final List<Future<CompletedBatchOperation>> futures;
499 + private final IntentState nextState;
500 +
501 + public IntentInstallMonitor(Intent intent,
502 + List<Future<CompletedBatchOperation>> futures, IntentState nextState) {
503 + this.intent = intent;
504 + this.futures = futures;
505 + this.nextState = nextState;
506 + }
507 +
508 + private void updateIntent(Intent intent) {
509 + if (nextState == RECOMPILING) {
510 + executor.execute(new IntentTask(nextState, intent));
511 + } else if (nextState == INSTALLED || nextState == WITHDRAWN) {
512 + eventDispatcher.post(store.setState(intent, nextState));
513 + } else {
514 + log.warn("Invalid next intent state {} for intent {}", nextState, intent);
515 + }
516 + }
517 +
518 + @Override
519 + public void run() {
520 + for (Iterator<Future<CompletedBatchOperation>> i = futures.iterator(); i.hasNext();) {
521 + Future<CompletedBatchOperation> future = i.next();
522 + try {
523 + // TODO: we may want to get the future here and go back to the future.
524 + CompletedBatchOperation completed = future.get(100, TimeUnit.NANOSECONDS);
525 + // TODO check if future succeeded and if not report fail items
526 + i.remove();
527 +
528 + } catch (TimeoutException | InterruptedException | ExecutionException te) {
529 + log.debug("Intallations of intent {} is still pending", intent);
530 + }
531 + }
532 + if (futures.isEmpty()) {
533 + updateIntent(intent);
534 + } else {
535 + // resubmit ourselves if we are not done yet
536 + monitorExecutor.submit(this);
537 + }
538 + }
539 + }
463 } 540 }
......
...@@ -5,7 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -5,7 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger;
5 5
6 import java.util.Iterator; 6 import java.util.Iterator;
7 import java.util.List; 7 import java.util.List;
8 -import java.util.concurrent.ExecutionException; 8 +import java.util.concurrent.Future;
9 9
10 import org.apache.felix.scr.annotations.Activate; 10 import org.apache.felix.scr.annotations.Activate;
11 import org.apache.felix.scr.annotations.Component; 11 import org.apache.felix.scr.annotations.Component;
...@@ -13,8 +13,10 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -13,8 +13,10 @@ import org.apache.felix.scr.annotations.Deactivate;
13 import org.apache.felix.scr.annotations.Reference; 13 import org.apache.felix.scr.annotations.Reference;
14 import org.apache.felix.scr.annotations.ReferenceCardinality; 14 import org.apache.felix.scr.annotations.ReferenceCardinality;
15 import org.onlab.onos.ApplicationId; 15 import org.onlab.onos.ApplicationId;
16 +import org.onlab.onos.CoreService;
16 import org.onlab.onos.net.ConnectPoint; 17 import org.onlab.onos.net.ConnectPoint;
17 import org.onlab.onos.net.Link; 18 import org.onlab.onos.net.Link;
19 +import org.onlab.onos.net.flow.CompletedBatchOperation;
18 import org.onlab.onos.net.flow.DefaultFlowRule; 20 import org.onlab.onos.net.flow.DefaultFlowRule;
19 import org.onlab.onos.net.flow.DefaultTrafficSelector; 21 import org.onlab.onos.net.flow.DefaultTrafficSelector;
20 import org.onlab.onos.net.flow.FlowRule; 22 import org.onlab.onos.net.flow.FlowRule;
...@@ -45,10 +47,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -45,10 +47,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
45 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 47 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
46 protected FlowRuleService flowRuleService; 48 protected FlowRuleService flowRuleService;
47 49
48 - private final ApplicationId appId = ApplicationId.getAppId(); 50 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
51 + protected CoreService coreService;
52 +
53 + private ApplicationId appId;
49 54
50 @Activate 55 @Activate
51 public void activate() { 56 public void activate() {
57 + appId = coreService.registerApplication("org.onlab.onos.net.intent");
52 intentManager.registerInstaller(PathIntent.class, this); 58 intentManager.registerInstaller(PathIntent.class, this);
53 } 59 }
54 60
...@@ -57,8 +63,26 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -57,8 +63,26 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
57 intentManager.unregisterInstaller(PathIntent.class); 63 intentManager.unregisterInstaller(PathIntent.class);
58 } 64 }
59 65
66 + /**
67 + * Apply a list of FlowRules.
68 + *
69 + * @param rules rules to apply
70 + */
71 + private Future<CompletedBatchOperation> applyBatch(List<FlowRuleBatchEntry> rules) {
72 + FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules);
73 + Future<CompletedBatchOperation> future = flowRuleService.applyBatch(batch);
74 + return future;
75 +// try {
76 +// //FIXME don't do this here
77 +// future.get();
78 +// } catch (InterruptedException | ExecutionException e) {
79 +// // TODO Auto-generated catch block
80 +// e.printStackTrace();
81 +// }
82 + }
83 +
60 @Override 84 @Override
61 - public void install(PathIntent intent) { 85 + public Future<CompletedBatchOperation> install(PathIntent intent) {
62 TrafficSelector.Builder builder = 86 TrafficSelector.Builder builder =
63 DefaultTrafficSelector.builder(intent.selector()); 87 DefaultTrafficSelector.builder(intent.selector());
64 Iterator<Link> links = intent.path().links().iterator(); 88 Iterator<Link> links = intent.path().links().iterator();
...@@ -74,20 +98,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -74,20 +98,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
74 builder.build(), treatment, 98 builder.build(), treatment,
75 123, appId, 600); 99 123, appId, 600);
76 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)); 100 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
77 - //flowRuleService.applyFlowRules(rule);
78 prev = link.dst(); 101 prev = link.dst();
79 } 102 }
80 - FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules); 103 +
81 - try { 104 + return applyBatch(rules);
82 - flowRuleService.applyBatch(batch).get();
83 - } catch (InterruptedException | ExecutionException e) {
84 - // TODO Auto-generated catch block
85 - e.printStackTrace();
86 - }
87 } 105 }
88 106
89 @Override 107 @Override
90 - public void uninstall(PathIntent intent) { 108 + public Future<CompletedBatchOperation> uninstall(PathIntent intent) {
91 TrafficSelector.Builder builder = 109 TrafficSelector.Builder builder =
92 DefaultTrafficSelector.builder(intent.selector()); 110 DefaultTrafficSelector.builder(intent.selector());
93 Iterator<Link> links = intent.path().links().iterator(); 111 Iterator<Link> links = intent.path().links().iterator();
...@@ -103,15 +121,131 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -103,15 +121,131 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
103 builder.build(), treatment, 121 builder.build(), treatment,
104 123, appId, 600); 122 123, appId, 600);
105 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule)); 123 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
106 - //flowRuleService.removeFlowRules(rule);
107 prev = link.dst(); 124 prev = link.dst();
108 } 125 }
109 - FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules); 126 + return applyBatch(rules);
110 - try { 127 + }
111 - flowRuleService.applyBatch(batch).get(); 128 +
112 - } catch (InterruptedException | ExecutionException e) { 129 + // TODO refactor below this line... ----------------------------
113 - // TODO Auto-generated catch block 130 +
114 - e.printStackTrace(); 131 + /**
132 + * Generates the series of MatchActionOperations from the
133 + * {@link FlowBatchOperation}.
134 + * <p>
135 + * FIXME: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
136 + * <p>
137 + * FIXME: MatchActionOperations should have dependency field to the other
138 + * match action operations, and this method should use this.
139 + *
140 + * @param op the {@link FlowBatchOperation} object
141 + * @return the list of {@link MatchActionOperations} objects
142 + */
143 + /*
144 + private List<MatchActionOperations>
145 + generateMatchActionOperationsList(FlowBatchOperation op) {
146 +
147 + // MatchAction operations at head (ingress) switches.
148 + MatchActionOperations headOps = matchActionService.createOperationsList();
149 +
150 + // MatchAction operations at rest of the switches.
151 + MatchActionOperations tailOps = matchActionService.createOperationsList();
152 +
153 + MatchActionOperations removeOps = matchActionService.createOperationsList();
154 +
155 + for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
156 +
157 + if (e.getOperator() == FlowBatchOperation.Operator.ADD) {
158 + generateInstallMatchActionOperations(e, tailOps, headOps);
159 + } else if (e.getOperator() == FlowBatchOperation.Operator.REMOVE) {
160 + generateRemoveMatchActionOperations(e, removeOps);
161 + } else {
162 + throw new UnsupportedOperationException(
163 + "FlowManager supports ADD and REMOVE operations only.");
164 + }
165 +
166 + }
167 +
168 + return Arrays.asList(tailOps, headOps, removeOps);
169 + }
170 + */
171 +
172 + /**
173 + * Generates MatchActionOperations for an INSTALL FlowBatchOperation.
174 + * <p/>
175 + * FIXME: Currently only supports flows that generate exactly two match
176 + * action operation sets.
177 + *
178 + * @param e Flow BatchOperationEntry
179 + * @param tailOps MatchActionOperation set that the tail
180 + * MatchActionOperations will be placed in
181 + * @param headOps MatchActionOperation set that the head
182 + * MatchActionOperations will be placed in
183 + */
184 + /*
185 + private void generateInstallMatchActionOperations(
186 + BatchOperationEntry<Operator, ?> e,
187 + MatchActionOperations tailOps,
188 + MatchActionOperations headOps) {
189 +
190 + if (!(e.getTarget() instanceof Flow)) {
191 + throw new IllegalStateException(
192 + "The target is not Flow object: " + e.getTarget());
193 + }
194 +
195 + // Compile flows to match-actions
196 + Flow flow = (Flow) e.getTarget();
197 + List<MatchActionOperations> maOps = flow.compile(
198 + e.getOperator(), matchActionService);
199 + verifyNotNull(maOps, "Could not compile the flow: " + flow);
200 + verify(maOps.size() == 2,
201 + "The flow generates unspported match-action operations.");
202 +
203 + // Map FlowId to MatchActionIds
204 + for (MatchActionOperations maOp : maOps) {
205 + for (MatchActionOperationEntry entry : maOp.getOperations()) {
206 + flowMatchActionsMap.put(
207 + KryoFactory.serialize(flow.getId()),
208 + KryoFactory.serialize(entry.getTarget()));
209 + }
210 + }
211 +
212 + // Merge match-action operations
213 + for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
214 + verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
215 + tailOps.addOperation(mae);
216 + }
217 + for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
218 + verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
219 + headOps.addOperation(mae);
220 + }
221 + }
222 + */
223 + /**
224 + * Generates MatchActionOperations for a REMOVE FlowBatchOperation.
225 + *
226 + * @param e Flow BatchOperationEntry
227 + * @param removeOps MatchActionOperation set that the remove
228 + * MatchActionOperations will be placed in
229 + */
230 + /*
231 + private void generateRemoveMatchActionOperations(
232 + BatchOperationEntry<Operator, ?> e,
233 + MatchActionOperations removeOps) {
234 +
235 + if (!(e.getTarget() instanceof FlowId)) {
236 + throw new IllegalStateException(
237 + "The target is not a FlowId object: " + e.getTarget());
238 + }
239 +
240 + // Compile flows to match-actions
241 + FlowId flowId = (FlowId) e.getTarget();
242 +
243 + for (byte[] matchActionIdBytes :
244 + flowMatchActionsMap.remove(KryoFactory.serialize(flowId))) {
245 + MatchActionId matchActionId = KryoFactory.deserialize(matchActionIdBytes);
246 + removeOps.addOperation(new MatchActionOperationEntry(
247 + MatchActionOperations.Operator.REMOVE, matchActionId));
115 } 248 }
116 } 249 }
250 + */
117 } 251 }
......
...@@ -55,6 +55,7 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -55,6 +55,7 @@ public class ProxyArpManager implements ProxyArpService {
55 private static final String REQUEST_NULL = "Arp request cannot be null."; 55 private static final String REQUEST_NULL = "Arp request cannot be null.";
56 private static final String REQUEST_NOT_ARP = "Ethernet frame does not contain ARP request."; 56 private static final String REQUEST_NOT_ARP = "Ethernet frame does not contain ARP request.";
57 private static final String NOT_ARP_REQUEST = "ARP is not a request."; 57 private static final String NOT_ARP_REQUEST = "ARP is not a request.";
58 + private static final String NOT_ARP_REPLY = "ARP is not a reply.";
58 59
59 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 protected HostService hostService; 61 protected HostService hostService;
...@@ -141,7 +142,7 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -141,7 +142,7 @@ public class ProxyArpManager implements ProxyArpService {
141 checkArgument(eth.getEtherType() == Ethernet.TYPE_ARP, 142 checkArgument(eth.getEtherType() == Ethernet.TYPE_ARP,
142 REQUEST_NOT_ARP); 143 REQUEST_NOT_ARP);
143 ARP arp = (ARP) eth.getPayload(); 144 ARP arp = (ARP) eth.getPayload();
144 - checkArgument(arp.getOpCode() == ARP.OP_REPLY, NOT_ARP_REQUEST); 145 + checkArgument(arp.getOpCode() == ARP.OP_REPLY, NOT_ARP_REPLY);
145 146
146 Host h = hostService.getHost(HostId.hostId(eth.getDestinationMAC(), 147 Host h = hostService.getHost(HostId.hostId(eth.getDestinationMAC(),
147 VlanId.vlanId(eth.getVlanID()))); 148 VlanId.vlanId(eth.getVlanID())));
......
...@@ -22,9 +22,9 @@ import org.onlab.onos.net.Link; ...@@ -22,9 +22,9 @@ import org.onlab.onos.net.Link;
22 import org.onlab.onos.net.Path; 22 import org.onlab.onos.net.Path;
23 import org.onlab.onos.net.PortNumber; 23 import org.onlab.onos.net.PortNumber;
24 import org.onlab.onos.net.host.HostService; 24 import org.onlab.onos.net.host.HostService;
25 -import org.onlab.onos.net.topology.PathService;
26 import org.onlab.onos.net.provider.ProviderId; 25 import org.onlab.onos.net.provider.ProviderId;
27 import org.onlab.onos.net.topology.LinkWeight; 26 import org.onlab.onos.net.topology.LinkWeight;
27 +import org.onlab.onos.net.topology.PathService;
28 import org.onlab.onos.net.topology.Topology; 28 import org.onlab.onos.net.topology.Topology;
29 import org.onlab.onos.net.topology.TopologyService; 29 import org.onlab.onos.net.topology.TopologyService;
30 import org.slf4j.Logger; 30 import org.slf4j.Logger;
...@@ -33,7 +33,6 @@ import java.util.List; ...@@ -33,7 +33,6 @@ import java.util.List;
33 import java.util.Set; 33 import java.util.Set;
34 34
35 import static com.google.common.base.Preconditions.checkNotNull; 35 import static com.google.common.base.Preconditions.checkNotNull;
36 -import static org.onlab.onos.net.DeviceId.deviceId;
37 import static org.slf4j.LoggerFactory.getLogger; 36 import static org.slf4j.LoggerFactory.getLogger;
38 37
39 /** 38 /**
...@@ -162,8 +161,8 @@ public class PathManager implements PathService { ...@@ -162,8 +161,8 @@ public class PathManager implements PathService {
162 // edge link since the src or dst are really an infrastructure device. 161 // edge link since the src or dst are really an infrastructure device.
163 private static class NotHost extends DefaultEdgeLink implements EdgeLink { 162 private static class NotHost extends DefaultEdgeLink implements EdgeLink {
164 NotHost() { 163 NotHost() {
165 - super(PID, new ConnectPoint(HostId.hostId("nic:none"), P0), 164 + super(PID, new ConnectPoint(HostId.NONE, P0),
166 - new HostLocation(deviceId("none:none"), P0, 0L), false); 165 + new HostLocation(DeviceId.NONE, P0, 0L), false);
167 } 166 }
168 } 167 }
169 } 168 }
......
...@@ -19,6 +19,7 @@ import org.junit.Before; ...@@ -19,6 +19,7 @@ import org.junit.Before;
19 import org.junit.Test; 19 import org.junit.Test;
20 import org.onlab.onos.ApplicationId; 20 import org.onlab.onos.ApplicationId;
21 import org.onlab.onos.event.impl.TestEventDispatcher; 21 import org.onlab.onos.event.impl.TestEventDispatcher;
22 +import org.onlab.onos.impl.DefaultApplicationId;
22 import org.onlab.onos.net.DefaultDevice; 23 import org.onlab.onos.net.DefaultDevice;
23 import org.onlab.onos.net.Device; 24 import org.onlab.onos.net.Device;
24 import org.onlab.onos.net.Device.Type; 25 import org.onlab.onos.net.Device.Type;
...@@ -28,6 +29,7 @@ import org.onlab.onos.net.Port; ...@@ -28,6 +29,7 @@ import org.onlab.onos.net.Port;
28 import org.onlab.onos.net.PortNumber; 29 import org.onlab.onos.net.PortNumber;
29 import org.onlab.onos.net.device.DeviceListener; 30 import org.onlab.onos.net.device.DeviceListener;
30 import org.onlab.onos.net.device.DeviceService; 31 import org.onlab.onos.net.device.DeviceService;
32 +import org.onlab.onos.net.flow.CompletedBatchOperation;
31 import org.onlab.onos.net.flow.DefaultFlowEntry; 33 import org.onlab.onos.net.flow.DefaultFlowEntry;
32 import org.onlab.onos.net.flow.DefaultFlowRule; 34 import org.onlab.onos.net.flow.DefaultFlowRule;
33 import org.onlab.onos.net.flow.FlowEntry; 35 import org.onlab.onos.net.flow.FlowEntry;
...@@ -58,6 +60,8 @@ import com.google.common.collect.Sets; ...@@ -58,6 +60,8 @@ import com.google.common.collect.Sets;
58 */ 60 */
59 public class FlowRuleManagerTest { 61 public class FlowRuleManagerTest {
60 62
63 +
64 +
61 private static final ProviderId PID = new ProviderId("of", "foo"); 65 private static final ProviderId PID = new ProviderId("of", "foo");
62 private static final DeviceId DID = DeviceId.deviceId("of:001"); 66 private static final DeviceId DID = DeviceId.deviceId("of:001");
63 private static final int TIMEOUT = 10; 67 private static final int TIMEOUT = 10;
...@@ -86,7 +90,7 @@ public class FlowRuleManagerTest { ...@@ -86,7 +90,7 @@ public class FlowRuleManagerTest {
86 mgr.addListener(listener); 90 mgr.addListener(listener);
87 provider = new TestProvider(PID); 91 provider = new TestProvider(PID);
88 providerService = registry.register(provider); 92 providerService = registry.register(provider);
89 - appId = ApplicationId.getAppId(); 93 + appId = new TestApplicationId((short) 0, "FlowRuleManagerTest");
90 assertTrue("provider should be registered", 94 assertTrue("provider should be registered",
91 registry.getProviders().contains(provider.id())); 95 registry.getProviders().contains(provider.id()));
92 } 96 }
...@@ -408,7 +412,7 @@ public class FlowRuleManagerTest { ...@@ -408,7 +412,7 @@ public class FlowRuleManagerTest {
408 } 412 }
409 413
410 @Override 414 @Override
411 - public Future<Void> executeBatch( 415 + public Future<CompletedBatchOperation> executeBatch(
412 BatchOperation<FlowRuleBatchEntry> batch) { 416 BatchOperation<FlowRuleBatchEntry> batch) {
413 // TODO Auto-generated method stub 417 // TODO Auto-generated method stub
414 return null; 418 return null;
...@@ -474,4 +478,11 @@ public class FlowRuleManagerTest { ...@@ -474,4 +478,11 @@ public class FlowRuleManagerTest {
474 478
475 } 479 }
476 480
481 + public class TestApplicationId extends DefaultApplicationId {
482 +
483 + public TestApplicationId(short id, String name) {
484 + super(id, name);
485 + }
486 + }
487 +
477 } 488 }
......
...@@ -58,8 +58,6 @@ public class HostManagerTest { ...@@ -58,8 +58,6 @@ public class HostManagerTest {
58 58
59 private static final IpPrefix IP1 = IpPrefix.valueOf("10.0.0.1"); 59 private static final IpPrefix IP1 = IpPrefix.valueOf("10.0.0.1");
60 private static final IpPrefix IP2 = IpPrefix.valueOf("10.0.0.2"); 60 private static final IpPrefix IP2 = IpPrefix.valueOf("10.0.0.2");
61 - private static final Set<IpPrefix> IPSET1 = Sets.newHashSet(IP1);
62 - private static final Set<IpPrefix> IPSET2 = Sets.newHashSet(IP2);
63 61
64 private static final DeviceId DID1 = DeviceId.deviceId("of:001"); 62 private static final DeviceId DID1 = DeviceId.deviceId("of:001");
65 private static final DeviceId DID2 = DeviceId.deviceId("of:002"); 63 private static final DeviceId DID2 = DeviceId.deviceId("of:002");
...@@ -94,14 +92,14 @@ public class HostManagerTest { ...@@ -94,14 +92,14 @@ public class HostManagerTest {
94 provider = new TestHostProvider(); 92 provider = new TestHostProvider();
95 providerService = registry.register(provider); 93 providerService = registry.register(provider);
96 assertTrue("provider should be registered", 94 assertTrue("provider should be registered",
97 - registry.getProviders().contains(provider.id())); 95 + registry.getProviders().contains(provider.id()));
98 } 96 }
99 97
100 @After 98 @After
101 public void tearDown() { 99 public void tearDown() {
102 registry.unregister(provider); 100 registry.unregister(provider);
103 assertFalse("provider should not be registered", 101 assertFalse("provider should not be registered",
104 - registry.getProviders().contains(provider.id())); 102 + registry.getProviders().contains(provider.id()));
105 103
106 mgr.removeListener(listener); 104 mgr.removeListener(listener);
107 mgr.deactivate(); 105 mgr.deactivate();
...@@ -109,8 +107,8 @@ public class HostManagerTest { ...@@ -109,8 +107,8 @@ public class HostManagerTest {
109 } 107 }
110 108
111 private void detect(HostId hid, MacAddress mac, VlanId vlan, 109 private void detect(HostId hid, MacAddress mac, VlanId vlan,
112 - HostLocation loc, Set<IpPrefix> ips) { 110 + HostLocation loc, IpPrefix ip) {
113 - HostDescription descr = new DefaultHostDescription(mac, vlan, loc, ips); 111 + HostDescription descr = new DefaultHostDescription(mac, vlan, loc, ip);
114 providerService.hostDetected(hid, descr); 112 providerService.hostDetected(hid, descr);
115 assertNotNull("host should be found", mgr.getHost(hid)); 113 assertNotNull("host should be found", mgr.getHost(hid));
116 } 114 }
...@@ -130,26 +128,26 @@ public class HostManagerTest { ...@@ -130,26 +128,26 @@ public class HostManagerTest {
130 assertNull("host shouldn't be found", mgr.getHost(HID1)); 128 assertNull("host shouldn't be found", mgr.getHost(HID1));
131 129
132 // host addition 130 // host addition
133 - detect(HID1, MAC1, VLAN1, LOC1, IPSET1); 131 + detect(HID1, MAC1, VLAN1, LOC1, IP1);
134 assertEquals("exactly one should be found", 1, mgr.getHostCount()); 132 assertEquals("exactly one should be found", 1, mgr.getHostCount());
135 - detect(HID2, MAC2, VLAN2, LOC2, IPSET1); 133 + detect(HID2, MAC2, VLAN2, LOC2, IP1);
136 assertEquals("two hosts should be found", 2, mgr.getHostCount()); 134 assertEquals("two hosts should be found", 2, mgr.getHostCount());
137 validateEvents(HOST_ADDED, HOST_ADDED); 135 validateEvents(HOST_ADDED, HOST_ADDED);
138 136
139 // host motion 137 // host motion
140 - detect(HID1, MAC1, VLAN1, LOC2, IPSET1); 138 + detect(HID1, MAC1, VLAN1, LOC2, IP1);
141 validateEvents(HOST_MOVED); 139 validateEvents(HOST_MOVED);
142 assertEquals("only two hosts should be found", 2, mgr.getHostCount()); 140 assertEquals("only two hosts should be found", 2, mgr.getHostCount());
143 141
144 // host update 142 // host update
145 - detect(HID1, MAC1, VLAN1, LOC2, IPSET2); 143 + detect(HID1, MAC1, VLAN1, LOC2, IP2);
146 validateEvents(HOST_UPDATED); 144 validateEvents(HOST_UPDATED);
147 assertEquals("only two hosts should be found", 2, mgr.getHostCount()); 145 assertEquals("only two hosts should be found", 2, mgr.getHostCount());
148 } 146 }
149 147
150 @Test 148 @Test
151 public void hostVanished() { 149 public void hostVanished() {
152 - detect(HID1, MAC1, VLAN1, LOC1, IPSET1); 150 + detect(HID1, MAC1, VLAN1, LOC1, IP1);
153 providerService.hostVanished(HID1); 151 providerService.hostVanished(HID1);
154 validateEvents(HOST_ADDED, HOST_REMOVED); 152 validateEvents(HOST_ADDED, HOST_REMOVED);
155 153
...@@ -157,7 +155,7 @@ public class HostManagerTest { ...@@ -157,7 +155,7 @@ public class HostManagerTest {
157 } 155 }
158 156
159 private void validateHosts( 157 private void validateHosts(
160 - String msg, Iterable<Host> hosts, HostId ... ids) { 158 + String msg, Iterable<Host> hosts, HostId... ids) {
161 Set<HostId> hids = Sets.newHashSet(ids); 159 Set<HostId> hids = Sets.newHashSet(ids);
162 for (Host h : hosts) { 160 for (Host h : hosts) {
163 assertTrue(msg, hids.remove(h.id())); 161 assertTrue(msg, hids.remove(h.id()));
...@@ -167,8 +165,8 @@ public class HostManagerTest { ...@@ -167,8 +165,8 @@ public class HostManagerTest {
167 165
168 @Test 166 @Test
169 public void getHosts() { 167 public void getHosts() {
170 - detect(HID1, MAC1, VLAN1, LOC1, IPSET1); 168 + detect(HID1, MAC1, VLAN1, LOC1, IP1);
171 - detect(HID2, MAC2, VLAN1, LOC2, IPSET2); 169 + detect(HID2, MAC2, VLAN1, LOC2, IP2);
172 170
173 validateHosts("host not properly stored", mgr.getHosts(), HID1, HID2); 171 validateHosts("host not properly stored", mgr.getHosts(), HID1, HID2);
174 validateHosts("can't get hosts by VLAN", mgr.getHostsByVlan(VLAN1), HID1, HID2); 172 validateHosts("can't get hosts by VLAN", mgr.getHostsByVlan(VLAN1), HID1, HID2);
...@@ -210,7 +208,7 @@ public class HostManagerTest { ...@@ -210,7 +208,7 @@ public class HostManagerTest {
210 @Test 208 @Test
211 public void bindAddressesToPort() { 209 public void bindAddressesToPort() {
212 PortAddresses add1 = new PortAddresses(CP1, 210 PortAddresses add1 = new PortAddresses(CP1,
213 - Sets.newHashSet(PREFIX1, PREFIX2), MAC1); 211 + Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
214 212
215 mgr.bindAddressesToPort(add1); 213 mgr.bindAddressesToPort(add1);
216 PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1); 214 PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
...@@ -241,7 +239,7 @@ public class HostManagerTest { ...@@ -241,7 +239,7 @@ public class HostManagerTest {
241 @Test 239 @Test
242 public void unbindAddressesFromPort() { 240 public void unbindAddressesFromPort() {
243 PortAddresses add1 = new PortAddresses(CP1, 241 PortAddresses add1 = new PortAddresses(CP1,
244 - Sets.newHashSet(PREFIX1, PREFIX2), MAC1); 242 + Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
245 243
246 mgr.bindAddressesToPort(add1); 244 mgr.bindAddressesToPort(add1);
247 PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1); 245 PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
...@@ -250,7 +248,7 @@ public class HostManagerTest { ...@@ -250,7 +248,7 @@ public class HostManagerTest {
250 assertNotNull(storedAddresses.mac()); 248 assertNotNull(storedAddresses.mac());
251 249
252 PortAddresses rem1 = new PortAddresses(CP1, 250 PortAddresses rem1 = new PortAddresses(CP1,
253 - Sets.newHashSet(PREFIX1), null); 251 + Sets.newHashSet(PREFIX1), null);
254 252
255 mgr.unbindAddressesFromPort(rem1); 253 mgr.unbindAddressesFromPort(rem1);
256 storedAddresses = mgr.getAddressBindingsForPort(CP1); 254 storedAddresses = mgr.getAddressBindingsForPort(CP1);
...@@ -267,7 +265,7 @@ public class HostManagerTest { ...@@ -267,7 +265,7 @@ public class HostManagerTest {
267 assertNull(storedAddresses.mac()); 265 assertNull(storedAddresses.mac());
268 266
269 PortAddresses rem3 = new PortAddresses(CP1, 267 PortAddresses rem3 = new PortAddresses(CP1,
270 - Sets.newHashSet(PREFIX2), MAC1); 268 + Sets.newHashSet(PREFIX2), MAC1);
271 269
272 mgr.unbindAddressesFromPort(rem3); 270 mgr.unbindAddressesFromPort(rem3);
273 storedAddresses = mgr.getAddressBindingsForPort(CP1); 271 storedAddresses = mgr.getAddressBindingsForPort(CP1);
...@@ -279,7 +277,7 @@ public class HostManagerTest { ...@@ -279,7 +277,7 @@ public class HostManagerTest {
279 @Test 277 @Test
280 public void clearAddresses() { 278 public void clearAddresses() {
281 PortAddresses add1 = new PortAddresses(CP1, 279 PortAddresses add1 = new PortAddresses(CP1,
282 - Sets.newHashSet(PREFIX1, PREFIX2), MAC1); 280 + Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
283 281
284 mgr.bindAddressesToPort(add1); 282 mgr.bindAddressesToPort(add1);
285 PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1); 283 PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
...@@ -297,7 +295,7 @@ public class HostManagerTest { ...@@ -297,7 +295,7 @@ public class HostManagerTest {
297 @Test 295 @Test
298 public void getAddressBindingsForPort() { 296 public void getAddressBindingsForPort() {
299 PortAddresses add1 = new PortAddresses(CP1, 297 PortAddresses add1 = new PortAddresses(CP1,
300 - Sets.newHashSet(PREFIX1, PREFIX2), MAC1); 298 + Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
301 299
302 mgr.bindAddressesToPort(add1); 300 mgr.bindAddressesToPort(add1);
303 PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1); 301 PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
...@@ -314,7 +312,7 @@ public class HostManagerTest { ...@@ -314,7 +312,7 @@ public class HostManagerTest {
314 assertTrue(storedAddresses.isEmpty()); 312 assertTrue(storedAddresses.isEmpty());
315 313
316 PortAddresses add1 = new PortAddresses(CP1, 314 PortAddresses add1 = new PortAddresses(CP1,
317 - Sets.newHashSet(PREFIX1, PREFIX2), MAC1); 315 + Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
318 316
319 mgr.bindAddressesToPort(add1); 317 mgr.bindAddressesToPort(add1);
320 318
...@@ -323,7 +321,7 @@ public class HostManagerTest { ...@@ -323,7 +321,7 @@ public class HostManagerTest {
323 assertTrue(storedAddresses.size() == 1); 321 assertTrue(storedAddresses.size() == 1);
324 322
325 PortAddresses add2 = new PortAddresses(CP2, 323 PortAddresses add2 = new PortAddresses(CP2,
326 - Sets.newHashSet(PREFIX3), MAC2); 324 + Sets.newHashSet(PREFIX3), MAC2);
327 325
328 mgr.bindAddressesToPort(add2); 326 mgr.bindAddressesToPort(add2);
329 327
......
...@@ -65,47 +65,48 @@ public class PathManagerTest { ...@@ -65,47 +65,48 @@ public class PathManagerTest {
65 @Test 65 @Test
66 public void infraToEdge() { 66 public void infraToEdge() {
67 DeviceId src = did("src"); 67 DeviceId src = did("src");
68 - HostId dst = hid("dst"); 68 + HostId dst = hid("12:34:56:78:90:ab/1");
69 fakeTopoMgr.paths.add(createPath("src", "middle", "edge")); 69 fakeTopoMgr.paths.add(createPath("src", "middle", "edge"));
70 - fakeHostMgr.hosts.put(dst, host("dst", "edge")); 70 + fakeHostMgr.hosts.put(dst, host("12:34:56:78:90:ab/1", "edge"));
71 Set<Path> paths = service.getPaths(src, dst); 71 Set<Path> paths = service.getPaths(src, dst);
72 validatePaths(paths, 1, 3, src, dst); 72 validatePaths(paths, 1, 3, src, dst);
73 } 73 }
74 74
75 @Test 75 @Test
76 public void edgeToInfra() { 76 public void edgeToInfra() {
77 - HostId src = hid("src"); 77 + HostId src = hid("12:34:56:78:90:ab/1");
78 DeviceId dst = did("dst"); 78 DeviceId dst = did("dst");
79 fakeTopoMgr.paths.add(createPath("edge", "middle", "dst")); 79 fakeTopoMgr.paths.add(createPath("edge", "middle", "dst"));
80 - fakeHostMgr.hosts.put(src, host("src", "edge")); 80 + fakeHostMgr.hosts.put(src, host("12:34:56:78:90:ab/1", "edge"));
81 Set<Path> paths = service.getPaths(src, dst); 81 Set<Path> paths = service.getPaths(src, dst);
82 validatePaths(paths, 1, 3, src, dst); 82 validatePaths(paths, 1, 3, src, dst);
83 } 83 }
84 84
85 @Test 85 @Test
86 public void edgeToEdge() { 86 public void edgeToEdge() {
87 - HostId src = hid("src"); 87 + HostId src = hid("12:34:56:78:90:ab/1");
88 - HostId dst = hid("dst"); 88 + HostId dst = hid("12:34:56:78:90:ef/1");
89 fakeTopoMgr.paths.add(createPath("srcEdge", "middle", "dstEdge")); 89 fakeTopoMgr.paths.add(createPath("srcEdge", "middle", "dstEdge"));
90 - fakeHostMgr.hosts.put(src, host("src", "srcEdge")); 90 + fakeHostMgr.hosts.put(src, host("12:34:56:78:90:ab/1", "srcEdge"));
91 - fakeHostMgr.hosts.put(dst, host("dst", "dstEdge")); 91 + fakeHostMgr.hosts.put(dst, host("12:34:56:78:90:ef/1", "dstEdge"));
92 Set<Path> paths = service.getPaths(src, dst); 92 Set<Path> paths = service.getPaths(src, dst);
93 validatePaths(paths, 1, 4, src, dst); 93 validatePaths(paths, 1, 4, src, dst);
94 } 94 }
95 95
96 @Test 96 @Test
97 public void edgeToEdgeDirect() { 97 public void edgeToEdgeDirect() {
98 - HostId src = hid("src"); 98 + HostId src = hid("12:34:56:78:90:ab/1");
99 - HostId dst = hid("dst"); 99 + HostId dst = hid("12:34:56:78:90:ef/1");
100 - fakeHostMgr.hosts.put(src, host("src", "edge")); 100 + fakeHostMgr.hosts.put(src, host("12:34:56:78:90:ab/1", "edge"));
101 - fakeHostMgr.hosts.put(dst, host("dst", "edge")); 101 + fakeHostMgr.hosts.put(dst, host("12:34:56:78:90:ef/1", "edge"));
102 Set<Path> paths = service.getPaths(src, dst); 102 Set<Path> paths = service.getPaths(src, dst);
103 validatePaths(paths, 1, 2, src, dst); 103 validatePaths(paths, 1, 2, src, dst);
104 } 104 }
105 105
106 @Test 106 @Test
107 public void noEdge() { 107 public void noEdge() {
108 - Set<Path> paths = service.getPaths(hid("src"), hid("dst")); 108 + Set<Path> paths = service.getPaths(hid("12:34:56:78:90:ab/1"),
109 + hid("12:34:56:78:90:ef/1"));
109 assertTrue("there should be no paths", paths.isEmpty()); 110 assertTrue("there should be no paths", paths.isEmpty());
110 } 111 }
111 112
......
...@@ -134,11 +134,11 @@ public class TopologyManagerTest { ...@@ -134,11 +134,11 @@ public class TopologyManagerTest {
134 service.isInfrastructure(topology, new ConnectPoint(did("a"), portNumber(3)))); 134 service.isInfrastructure(topology, new ConnectPoint(did("a"), portNumber(3))));
135 135
136 // One of these cannot be a broadcast point... or we have a loop... 136 // One of these cannot be a broadcast point... or we have a loop...
137 - assertFalse("should not be broadcast point", 137 +// assertFalse("should not be broadcast point",
138 - service.isBroadcastPoint(topology, new ConnectPoint(did("a"), portNumber(1))) && 138 +// service.isBroadcastPoint(topology, new ConnectPoint(did("a"), portNumber(1))) &&
139 - service.isBroadcastPoint(topology, new ConnectPoint(did("b"), portNumber(1))) && 139 +// service.isBroadcastPoint(topology, new ConnectPoint(did("b"), portNumber(1))) &&
140 - service.isBroadcastPoint(topology, new ConnectPoint(did("c"), portNumber(1))) && 140 +// service.isBroadcastPoint(topology, new ConnectPoint(did("c"), portNumber(1))) &&
141 - service.isBroadcastPoint(topology, new ConnectPoint(did("d"), portNumber(1)))); 141 +// service.isBroadcastPoint(topology, new ConnectPoint(did("d"), portNumber(1))));
142 assertTrue("should be broadcast point", 142 assertTrue("should be broadcast point",
143 service.isBroadcastPoint(topology, new ConnectPoint(did("a"), portNumber(3)))); 143 service.isBroadcastPoint(topology, new ConnectPoint(did("a"), portNumber(3))));
144 } 144 }
......
...@@ -54,8 +54,18 @@ ...@@ -54,8 +54,18 @@
54 <artifactId>org.apache.felix.scr.annotations</artifactId> 54 <artifactId>org.apache.felix.scr.annotations</artifactId>
55 </dependency> 55 </dependency>
56 <dependency> 56 <dependency>
57 - <groupId>de.javakaffee</groupId> 57 + <groupId>com.google.guava</groupId>
58 - <artifactId>kryo-serializers</artifactId> 58 + <artifactId>guava-testlib</artifactId>
59 + <scope>test</scope>
60 + </dependency>
61 + <dependency>
62 + <groupId>org.apache.commons</groupId>
63 + <artifactId>commons-lang3</artifactId>
64 + </dependency>
65 + <dependency>
66 + <groupId>org.easymock</groupId>
67 + <artifactId>easymock</artifactId>
68 + <scope>test</scope>
59 </dependency> 69 </dependency>
60 </dependencies> 70 </dependencies>
61 71
......
1 -package org.onlab.onos.store.common.impl;
2 -
3 -import java.util.Map;
4 -
5 -import org.onlab.onos.cluster.NodeId;
6 -import org.onlab.onos.store.Timestamp;
7 -
8 -import com.google.common.collect.ImmutableMap;
9 -
10 -/**
11 - * Anti-Entropy advertisement message.
12 - * <p>
13 - * Message to advertise the information this node holds.
14 - *
15 - * @param <ID> ID type
16 - */
17 -public class AntiEntropyAdvertisement<ID> {
18 -
19 - private final NodeId sender;
20 - private final ImmutableMap<ID, Timestamp> advertisement;
21 -
22 - /**
23 - * Creates anti-entropy advertisement message.
24 - *
25 - * @param sender sender of this message
26 - * @param advertisement timestamp information of the data sender holds
27 - */
28 - public AntiEntropyAdvertisement(NodeId sender, Map<ID, Timestamp> advertisement) {
29 - this.sender = sender;
30 - this.advertisement = ImmutableMap.copyOf(advertisement);
31 - }
32 -
33 - public NodeId sender() {
34 - return sender;
35 - }
36 -
37 - public ImmutableMap<ID, Timestamp> advertisement() {
38 - return advertisement;
39 - }
40 -
41 - // Default constructor for serializer
42 - protected AntiEntropyAdvertisement() {
43 - this.sender = null;
44 - this.advertisement = null;
45 - }
46 -}
1 -package org.onlab.onos.store.common.impl;
2 -
3 -import java.util.Map;
4 -import java.util.Set;
5 -
6 -import org.onlab.onos.cluster.NodeId;
7 -import org.onlab.onos.store.device.impl.VersionedValue;
8 -
9 -import com.google.common.collect.ImmutableMap;
10 -import com.google.common.collect.ImmutableSet;
11 -
12 -/**
13 - * Anti-Entropy reply message.
14 - * <p>
15 - * Message to send in reply to advertisement or another reply.
16 - * Suggest to the sender about the more up-to-date data this node has,
17 - * and request for more recent data that the receiver has.
18 - */
19 -public class AntiEntropyReply<ID, V extends VersionedValue<?>> {
20 -
21 - private final NodeId sender;
22 - private final ImmutableMap<ID, V> suggestion;
23 - private final ImmutableSet<ID> request;
24 -
25 - /**
26 - * Creates a reply to anti-entropy message.
27 - *
28 - * @param sender sender of this message
29 - * @param suggestion collection of more recent values, sender had
30 - * @param request Collection of identifiers
31 - */
32 - public AntiEntropyReply(NodeId sender,
33 - Map<ID, V> suggestion,
34 - Set<ID> request) {
35 - this.sender = sender;
36 - this.suggestion = ImmutableMap.copyOf(suggestion);
37 - this.request = ImmutableSet.copyOf(request);
38 - }
39 -
40 - public NodeId sender() {
41 - return sender;
42 - }
43 -
44 - /**
45 - * Returns collection of values, which the recipient of this reply is likely
46 - * to be missing or has outdated version.
47 - *
48 - * @return
49 - */
50 - public ImmutableMap<ID, V> suggestion() {
51 - return suggestion;
52 - }
53 -
54 - /**
55 - * Returns collection of identifier to request.
56 - *
57 - * @return collection of identifier to request
58 - */
59 - public ImmutableSet<ID> request() {
60 - return request;
61 - }
62 -
63 - /**
64 - * Checks if reply contains any suggestion or request.
65 - *
66 - * @return true if nothing is suggested and requested
67 - */
68 - public boolean isEmpty() {
69 - return suggestion.isEmpty() && request.isEmpty();
70 - }
71 -
72 - // Default constructor for serializer
73 - protected AntiEntropyReply() {
74 - this.sender = null;
75 - this.suggestion = null;
76 - this.request = null;
77 - }
78 -}
...@@ -30,6 +30,7 @@ public final class Timestamped<T> { ...@@ -30,6 +30,7 @@ public final class Timestamped<T> {
30 30
31 /** 31 /**
32 * Returns the value. 32 * Returns the value.
33 + *
33 * @return value 34 * @return value
34 */ 35 */
35 public T value() { 36 public T value() {
...@@ -38,6 +39,7 @@ public final class Timestamped<T> { ...@@ -38,6 +39,7 @@ public final class Timestamped<T> {
38 39
39 /** 40 /**
40 * Returns the time stamp. 41 * Returns the time stamp.
42 + *
41 * @return time stamp 43 * @return time stamp
42 */ 44 */
43 public Timestamp timestamp() { 45 public Timestamp timestamp() {
...@@ -51,7 +53,16 @@ public final class Timestamped<T> { ...@@ -51,7 +53,16 @@ public final class Timestamped<T> {
51 * @return true if this instance is newer. 53 * @return true if this instance is newer.
52 */ 54 */
53 public boolean isNewer(Timestamped<T> other) { 55 public boolean isNewer(Timestamped<T> other) {
54 - return this.timestamp.compareTo(checkNotNull(other).timestamp()) > 0; 56 + return isNewer(checkNotNull(other).timestamp());
57 + }
58 +
59 + /**
60 + * Tests if this timestamp is newer thatn the specified timestamp.
61 + * @param timestamp to compare agains
62 + * @return true if this instance is newer
63 + */
64 + public boolean isNewer(Timestamp timestamp) {
65 + return this.timestamp.compareTo(checkNotNull(timestamp)) > 0;
55 } 66 }
56 67
57 @Override 68 @Override
......
1 -package org.onlab.onos.store.device.impl;
2 -
3 -import java.util.Collection;
4 -import java.util.HashMap;
5 -import java.util.Map;
6 -
7 -import org.onlab.onos.cluster.NodeId;
8 -import org.onlab.onos.net.Device;
9 -import org.onlab.onos.net.DeviceId;
10 -import org.onlab.onos.store.Timestamp;
11 -import org.onlab.onos.store.common.impl.AntiEntropyAdvertisement;
12 -
13 -// TODO DeviceID needs to be changed to something like (ProviderID, DeviceID)
14 -// TODO: Handle Port as part of these messages, or separate messages for Ports?
15 -
16 -public class DeviceAntiEntropyAdvertisement
17 - extends AntiEntropyAdvertisement<DeviceId> {
18 -
19 -
20 - public DeviceAntiEntropyAdvertisement(NodeId sender,
21 - Map<DeviceId, Timestamp> advertisement) {
22 - super(sender, advertisement);
23 - }
24 -
25 - // May need to add ProviderID, etc.
26 - public static DeviceAntiEntropyAdvertisement create(
27 - NodeId self,
28 - Collection<VersionedValue<Device>> localValues) {
29 -
30 - Map<DeviceId, Timestamp> ads = new HashMap<>(localValues.size());
31 - for (VersionedValue<Device> e : localValues) {
32 - ads.put(e.entity().id(), e.timestamp());
33 - }
34 - return new DeviceAntiEntropyAdvertisement(self, ads);
35 - }
36 -
37 - // For serializer
38 - protected DeviceAntiEntropyAdvertisement() {}
39 -}
1 -package org.onlab.onos.store.device.impl;
2 -
3 -import java.util.Collection;
4 -import java.util.HashMap;
5 -import java.util.HashSet;
6 -import java.util.Map;
7 -import java.util.Set;
8 -
9 -import org.onlab.onos.cluster.NodeId;
10 -import org.onlab.onos.net.Device;
11 -import org.onlab.onos.net.DeviceId;
12 -import org.onlab.onos.store.Timestamp;
13 -import org.onlab.onos.store.common.impl.AntiEntropyReply;
14 -
15 -import com.google.common.collect.ImmutableMap;
16 -import com.google.common.collect.ImmutableSet;
17 -
18 -public class DeviceAntiEntropyReply
19 - extends AntiEntropyReply<DeviceId, VersionedValue<Device>> {
20 -
21 -
22 - public DeviceAntiEntropyReply(NodeId sender,
23 - Map<DeviceId, VersionedValue<Device>> suggestion,
24 - Set<DeviceId> request) {
25 - super(sender, suggestion, request);
26 - }
27 -
28 - /**
29 - * Creates a reply to Anti-Entropy advertisement.
30 - *
31 - * @param advertisement to respond to
32 - * @param self node identifier representing local node
33 - * @param localValues local values held on this node
34 - * @return reply message
35 - */
36 - public static DeviceAntiEntropyReply reply(
37 - DeviceAntiEntropyAdvertisement advertisement,
38 - NodeId self,
39 - Collection<VersionedValue<Device>> localValues
40 - ) {
41 -
42 - ImmutableMap<DeviceId, Timestamp> ads = advertisement.advertisement();
43 -
44 - ImmutableMap.Builder<DeviceId, VersionedValue<Device>>
45 - sug = ImmutableMap.builder();
46 -
47 - Set<DeviceId> req = new HashSet<>(ads.keySet());
48 -
49 - for (VersionedValue<Device> e : localValues) {
50 - final DeviceId id = e.entity().id();
51 - final Timestamp local = e.timestamp();
52 - final Timestamp theirs = ads.get(id);
53 - if (theirs == null) {
54 - // they don't have it, suggest
55 - sug.put(id, e);
56 - // don't need theirs
57 - req.remove(id);
58 - } else if (local.compareTo(theirs) < 0) {
59 - // they got older one, suggest
60 - sug.put(id, e);
61 - // don't need theirs
62 - req.remove(id);
63 - } else if (local.equals(theirs)) {
64 - // same, don't need theirs
65 - req.remove(id);
66 - }
67 - }
68 -
69 - return new DeviceAntiEntropyReply(self, sug.build(), req);
70 - }
71 -
72 - /**
73 - * Creates a reply to request for values held locally.
74 - *
75 - * @param requests message containing the request
76 - * @param self node identifier representing local node
77 - * @param localValues local valeds held on this node
78 - * @return reply message
79 - */
80 - public static DeviceAntiEntropyReply reply(
81 - DeviceAntiEntropyReply requests,
82 - NodeId self,
83 - Map<DeviceId, VersionedValue<Device>> localValues
84 - ) {
85 -
86 - Set<DeviceId> reqs = requests.request();
87 -
88 - Map<DeviceId, VersionedValue<Device>> requested = new HashMap<>(reqs.size());
89 - for (DeviceId id : reqs) {
90 - final VersionedValue<Device> value = localValues.get(id);
91 - if (value != null) {
92 - requested.put(id, value);
93 - }
94 - }
95 -
96 - Set<DeviceId> empty = ImmutableSet.of();
97 - return new DeviceAntiEntropyReply(self, requested, empty);
98 - }
99 -
100 - // For serializer
101 - protected DeviceAntiEntropyReply() {}
102 -}
1 +package org.onlab.onos.store.device.impl;
2 +
3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +import static org.onlab.onos.net.DefaultAnnotations.union;
5 +
6 +import java.util.Collections;
7 +import java.util.Map;
8 +import java.util.concurrent.ConcurrentHashMap;
9 +import java.util.concurrent.ConcurrentMap;
10 +
11 +import org.onlab.onos.net.PortNumber;
12 +import org.onlab.onos.net.SparseAnnotations;
13 +import org.onlab.onos.net.device.DefaultDeviceDescription;
14 +import org.onlab.onos.net.device.DefaultPortDescription;
15 +import org.onlab.onos.net.device.DeviceDescription;
16 +import org.onlab.onos.net.device.PortDescription;
17 +import org.onlab.onos.store.Timestamp;
18 +import org.onlab.onos.store.common.impl.Timestamped;
19 +
20 +/*
21 + * Collection of Description of a Device and Ports, given from a Provider.
22 + */
23 +class DeviceDescriptions {
24 +
25 + private volatile Timestamped<DeviceDescription> deviceDesc;
26 +
27 + private final ConcurrentMap<PortNumber, Timestamped<PortDescription>> portDescs;
28 +
29 + public DeviceDescriptions(Timestamped<DeviceDescription> desc) {
30 + this.deviceDesc = checkNotNull(desc);
31 + this.portDescs = new ConcurrentHashMap<>();
32 + }
33 +
34 + public Timestamp getLatestTimestamp() {
35 + Timestamp latest = deviceDesc.timestamp();
36 + for (Timestamped<PortDescription> desc : portDescs.values()) {
37 + if (desc.timestamp().compareTo(latest) > 0) {
38 + latest = desc.timestamp();
39 + }
40 + }
41 + return latest;
42 + }
43 +
44 + public Timestamped<DeviceDescription> getDeviceDesc() {
45 + return deviceDesc;
46 + }
47 +
48 + public Timestamped<PortDescription> getPortDesc(PortNumber number) {
49 + return portDescs.get(number);
50 + }
51 +
52 + public Map<PortNumber, Timestamped<PortDescription>> getPortDescs() {
53 + return Collections.unmodifiableMap(portDescs);
54 + }
55 +
56 + /**
57 + * Puts DeviceDescription, merging annotations as necessary.
58 + *
59 + * @param newDesc new DeviceDescription
60 + */
61 + public void putDeviceDesc(Timestamped<DeviceDescription> newDesc) {
62 + Timestamped<DeviceDescription> oldOne = deviceDesc;
63 + Timestamped<DeviceDescription> newOne = newDesc;
64 + if (oldOne != null) {
65 + SparseAnnotations merged = union(oldOne.value().annotations(),
66 + newDesc.value().annotations());
67 + newOne = new Timestamped<DeviceDescription>(
68 + new DefaultDeviceDescription(newDesc.value(), merged),
69 + newDesc.timestamp());
70 + }
71 + deviceDesc = newOne;
72 + }
73 +
74 + /**
75 + * Puts PortDescription, merging annotations as necessary.
76 + *
77 + * @param newDesc new PortDescription
78 + */
79 + public void putPortDesc(Timestamped<PortDescription> newDesc) {
80 + Timestamped<PortDescription> oldOne = portDescs.get(newDesc.value().portNumber());
81 + Timestamped<PortDescription> newOne = newDesc;
82 + if (oldOne != null) {
83 + SparseAnnotations merged = union(oldOne.value().annotations(),
84 + newDesc.value().annotations());
85 + newOne = new Timestamped<PortDescription>(
86 + new DefaultPortDescription(newDesc.value(), merged),
87 + newDesc.timestamp());
88 + }
89 + portDescs.put(newOne.value().portNumber(), newOne);
90 + }
91 +}
...@@ -2,6 +2,7 @@ package org.onlab.onos.store.device.impl; ...@@ -2,6 +2,7 @@ package org.onlab.onos.store.device.impl;
2 2
3 import org.onlab.onos.store.cluster.messaging.MessageSubject; 3 import org.onlab.onos.store.cluster.messaging.MessageSubject;
4 4
5 +// TODO: add prefix to assure uniqueness.
5 /** 6 /**
6 * MessageSubjects used by GossipDeviceStore peer-peer communication. 7 * MessageSubjects used by GossipDeviceStore peer-peer communication.
7 */ 8 */
...@@ -14,4 +15,8 @@ public final class GossipDeviceStoreMessageSubjects { ...@@ -14,4 +15,8 @@ public final class GossipDeviceStoreMessageSubjects {
14 public static final MessageSubject DEVICE_REMOVED = new MessageSubject("peer-device-removed"); 15 public static final MessageSubject DEVICE_REMOVED = new MessageSubject("peer-device-removed");
15 public static final MessageSubject PORT_UPDATE = new MessageSubject("peer-port-update"); 16 public static final MessageSubject PORT_UPDATE = new MessageSubject("peer-port-update");
16 public static final MessageSubject PORT_STATUS_UPDATE = new MessageSubject("peer-port-status-update"); 17 public static final MessageSubject PORT_STATUS_UPDATE = new MessageSubject("peer-port-status-update");
18 +
19 + public static final MessageSubject DEVICE_ADVERTISE = new MessageSubject("peer-device-advertisements");
20 + // to be used with 3-way anti-entropy process
21 + public static final MessageSubject DEVICE_REQUEST = new MessageSubject("peer-device-request");
17 } 22 }
......
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 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -5,6 +5,8 @@ import org.onlab.onos.net.device.DeviceDescription; ...@@ -5,6 +5,8 @@ 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.common.impl.Timestamped;
7 7
8 +import com.google.common.base.MoreObjects;
9 +
8 /** 10 /**
9 * Information published by GossipDeviceStore to notify peers of a device 11 * Information published by GossipDeviceStore to notify peers of a device
10 * change event. 12 * change event.
...@@ -36,6 +38,15 @@ public class InternalDeviceEvent { ...@@ -36,6 +38,15 @@ public class InternalDeviceEvent {
36 return deviceDescription; 38 return deviceDescription;
37 } 39 }
38 40
41 + @Override
42 + public String toString() {
43 + return MoreObjects.toStringHelper(getClass())
44 + .add("providerId", providerId)
45 + .add("deviceId", deviceId)
46 + .add("deviceDescription", deviceDescription)
47 + .toString();
48 + }
49 +
39 // for serializer 50 // for serializer
40 protected InternalDeviceEvent() { 51 protected InternalDeviceEvent() {
41 this.providerId = null; 52 this.providerId = null;
......
...@@ -3,6 +3,8 @@ package org.onlab.onos.store.device.impl; ...@@ -3,6 +3,8 @@ 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.store.Timestamp; 4 import org.onlab.onos.store.Timestamp;
5 5
6 +import com.google.common.base.MoreObjects;
7 +
6 /** 8 /**
7 * Information published by GossipDeviceStore to notify peers of a device 9 * Information published by GossipDeviceStore to notify peers of a device
8 * going offline. 10 * going offline.
...@@ -30,6 +32,14 @@ public class InternalDeviceOfflineEvent { ...@@ -30,6 +32,14 @@ public class InternalDeviceOfflineEvent {
30 return timestamp; 32 return timestamp;
31 } 33 }
32 34
35 + @Override
36 + public String toString() {
37 + return MoreObjects.toStringHelper(getClass())
38 + .add("deviceId", deviceId)
39 + .add("timestamp", timestamp)
40 + .toString();
41 + }
42 +
33 // for serializer 43 // for serializer
34 @SuppressWarnings("unused") 44 @SuppressWarnings("unused")
35 private InternalDeviceOfflineEvent() { 45 private InternalDeviceOfflineEvent() {
......
...@@ -3,6 +3,8 @@ package org.onlab.onos.store.device.impl; ...@@ -3,6 +3,8 @@ 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.store.Timestamp; 4 import org.onlab.onos.store.Timestamp;
5 5
6 +import com.google.common.base.MoreObjects;
7 +
6 /** 8 /**
7 * Information published by GossipDeviceStore to notify peers of a device 9 * Information published by GossipDeviceStore to notify peers of a device
8 * being administratively removed. 10 * being administratively removed.
...@@ -30,6 +32,14 @@ public class InternalDeviceRemovedEvent { ...@@ -30,6 +32,14 @@ public class InternalDeviceRemovedEvent {
30 return timestamp; 32 return timestamp;
31 } 33 }
32 34
35 + @Override
36 + public String toString() {
37 + return MoreObjects.toStringHelper(getClass())
38 + .add("deviceId", deviceId)
39 + .add("timestamp", timestamp)
40 + .toString();
41 + }
42 +
33 // for serializer 43 // for serializer
34 @SuppressWarnings("unused") 44 @SuppressWarnings("unused")
35 private InternalDeviceRemovedEvent() { 45 private InternalDeviceRemovedEvent() {
......
...@@ -7,6 +7,8 @@ import org.onlab.onos.net.device.PortDescription; ...@@ -7,6 +7,8 @@ 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.common.impl.Timestamped;
9 9
10 +import com.google.common.base.MoreObjects;
11 +
10 /** 12 /**
11 * Information published by GossipDeviceStore to notify peers of a port 13 * Information published by GossipDeviceStore to notify peers of a port
12 * change event. 14 * change event.
...@@ -38,6 +40,15 @@ public class InternalPortEvent { ...@@ -38,6 +40,15 @@ public class InternalPortEvent {
38 return portDescriptions; 40 return portDescriptions;
39 } 41 }
40 42
43 + @Override
44 + public String toString() {
45 + return MoreObjects.toStringHelper(getClass())
46 + .add("providerId", providerId)
47 + .add("deviceId", deviceId)
48 + .add("portDescriptions", portDescriptions)
49 + .toString();
50 + }
51 +
41 // for serializer 52 // for serializer
42 protected InternalPortEvent() { 53 protected InternalPortEvent() {
43 this.providerId = null; 54 this.providerId = null;
......
...@@ -5,6 +5,8 @@ import org.onlab.onos.net.device.PortDescription; ...@@ -5,6 +5,8 @@ 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.common.impl.Timestamped;
7 7
8 +import com.google.common.base.MoreObjects;
9 +
8 /** 10 /**
9 * Information published by GossipDeviceStore to notify peers of a port 11 * Information published by GossipDeviceStore to notify peers of a port
10 * status change event. 12 * status change event.
...@@ -36,6 +38,15 @@ public class InternalPortStatusEvent { ...@@ -36,6 +38,15 @@ public class InternalPortStatusEvent {
36 return portDescription; 38 return portDescription;
37 } 39 }
38 40
41 + @Override
42 + public String toString() {
43 + return MoreObjects.toStringHelper(getClass())
44 + .add("providerId", providerId)
45 + .add("deviceId", deviceId)
46 + .add("portDescription", portDescription)
47 + .toString();
48 + }
49 +
39 // for serializer 50 // for serializer
40 protected InternalPortStatusEvent() { 51 protected InternalPortStatusEvent() {
41 this.providerId = null; 52 this.providerId = null;
......
...@@ -35,6 +35,7 @@ public class InternalPortStatusEventSerializer extends Serializer<InternalPortSt ...@@ -35,6 +35,7 @@ public class InternalPortStatusEventSerializer extends Serializer<InternalPortSt
35 Class<InternalPortStatusEvent> type) { 35 Class<InternalPortStatusEvent> type) {
36 ProviderId providerId = (ProviderId) kryo.readClassAndObject(input); 36 ProviderId providerId = (ProviderId) kryo.readClassAndObject(input);
37 DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input); 37 DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
38 + @SuppressWarnings("unchecked")
38 Timestamped<PortDescription> portDescription = (Timestamped<PortDescription>) kryo.readClassAndObject(input); 39 Timestamped<PortDescription> portDescription = (Timestamped<PortDescription>) kryo.readClassAndObject(input);
39 40
40 return new InternalPortStatusEvent(providerId, deviceId, portDescription); 41 return new InternalPortStatusEvent(providerId, deviceId, portDescription);
......
1 -package org.onlab.onos.store.device.impl;
2 -
3 -import java.util.Objects;
4 -
5 -import org.onlab.onos.store.Timestamp;
6 -
7 -/**
8 - * Wrapper class for a entity that is versioned
9 - * and can either be up or down.
10 - *
11 - * @param <T> type of the value.
12 - */
13 -public class VersionedValue<T> {
14 - private final T entity;
15 - private final Timestamp timestamp;
16 - private final boolean isUp;
17 -
18 - public VersionedValue(T entity, boolean isUp, Timestamp timestamp) {
19 - this.entity = entity;
20 - this.isUp = isUp;
21 - this.timestamp = timestamp;
22 - }
23 -
24 - /**
25 - * Returns the value.
26 - * @return value.
27 - */
28 - public T entity() {
29 - return entity;
30 - }
31 -
32 - /**
33 - * Tells whether the entity is up or down.
34 - * @return true if up, false otherwise.
35 - */
36 - public boolean isUp() {
37 - return isUp;
38 - }
39 -
40 - /**
41 - * Returns the timestamp (version) associated with this entity.
42 - * @return timestamp.
43 - */
44 - public Timestamp timestamp() {
45 - return timestamp;
46 - }
47 -
48 -
49 - @Override
50 - public int hashCode() {
51 - return Objects.hash(entity, timestamp, isUp);
52 - }
53 -
54 - @Override
55 - public boolean equals(Object obj) {
56 - if (this == obj) {
57 - return true;
58 - }
59 - if (obj == null) {
60 - return false;
61 - }
62 - if (getClass() != obj.getClass()) {
63 - return false;
64 - }
65 - @SuppressWarnings("unchecked")
66 - VersionedValue<T> that = (VersionedValue<T>) obj;
67 - return Objects.equals(this.entity, that.entity) &&
68 - Objects.equals(this.timestamp, that.timestamp) &&
69 - Objects.equals(this.isUp, that.isUp);
70 - }
71 -
72 - // Default constructor for serializer
73 - protected VersionedValue() {
74 - this.entity = null;
75 - this.isUp = false;
76 - this.timestamp = null;
77 - }
78 -}
1 +package org.onlab.onos.store.device.impl.peermsg;
2 +
3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +
5 +import java.util.Map;
6 +
7 +import org.onlab.onos.cluster.NodeId;
8 +import org.onlab.onos.net.DeviceId;
9 +import org.onlab.onos.store.Timestamp;
10 +
11 +
12 +/**
13 + * Device Advertisement message.
14 + */
15 +public class DeviceAntiEntropyAdvertisement {
16 +
17 + private final NodeId sender;
18 + private final Map<DeviceFragmentId, Timestamp> deviceFingerPrints;
19 + private final Map<PortFragmentId, Timestamp> portFingerPrints;
20 + private final Map<DeviceId, Timestamp> offline;
21 +
22 +
23 + public DeviceAntiEntropyAdvertisement(NodeId sender,
24 + Map<DeviceFragmentId, Timestamp> devices,
25 + Map<PortFragmentId, Timestamp> ports,
26 + Map<DeviceId, Timestamp> offline) {
27 + this.sender = checkNotNull(sender);
28 + this.deviceFingerPrints = checkNotNull(devices);
29 + this.portFingerPrints = checkNotNull(ports);
30 + this.offline = checkNotNull(offline);
31 + }
32 +
33 + public NodeId sender() {
34 + return sender;
35 + }
36 +
37 + public Map<DeviceFragmentId, Timestamp> deviceFingerPrints() {
38 + return deviceFingerPrints;
39 + }
40 +
41 + public Map<PortFragmentId, Timestamp> ports() {
42 + return portFingerPrints;
43 + }
44 +
45 + public Map<DeviceId, Timestamp> offline() {
46 + return offline;
47 + }
48 +
49 + // For serializer
50 + @SuppressWarnings("unused")
51 + private DeviceAntiEntropyAdvertisement() {
52 + this.sender = null;
53 + this.deviceFingerPrints = null;
54 + this.portFingerPrints = null;
55 + this.offline = null;
56 + }
57 +}
1 +package org.onlab.onos.store.device.impl.peermsg;
2 +
3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +
5 +import java.util.Collection;
6 +
7 +import org.onlab.onos.cluster.NodeId;
8 +
9 +/**
10 + * Message to request for other peers information.
11 + */
12 +public class DeviceAntiEntropyRequest {
13 +
14 + private final NodeId sender;
15 + private final Collection<DeviceFragmentId> devices;
16 + private final Collection<PortFragmentId> ports;
17 +
18 + public DeviceAntiEntropyRequest(NodeId sender,
19 + Collection<DeviceFragmentId> devices,
20 + Collection<PortFragmentId> ports) {
21 +
22 + this.sender = checkNotNull(sender);
23 + this.devices = checkNotNull(devices);
24 + this.ports = checkNotNull(ports);
25 + }
26 +
27 + public NodeId sender() {
28 + return sender;
29 + }
30 +
31 + public Collection<DeviceFragmentId> devices() {
32 + return devices;
33 + }
34 +
35 + public Collection<PortFragmentId> ports() {
36 + return ports;
37 + }
38 +
39 + // For serializer
40 + @SuppressWarnings("unused")
41 + private DeviceAntiEntropyRequest() {
42 + this.sender = null;
43 + this.devices = null;
44 + this.ports = null;
45 + }
46 +}
1 +package org.onlab.onos.store.device.impl.peermsg;
2 +
3 +import java.util.Objects;
4 +
5 +import org.onlab.onos.net.DeviceId;
6 +import org.onlab.onos.net.provider.ProviderId;
7 +
8 +import com.google.common.base.MoreObjects;
9 +
10 +/**
11 + * Identifier for DeviceDesctiption from a Provider.
12 + */
13 +public final class DeviceFragmentId {
14 + public final ProviderId providerId;
15 + public final DeviceId deviceId;
16 +
17 + public DeviceFragmentId(DeviceId deviceId, ProviderId providerId) {
18 + this.providerId = providerId;
19 + this.deviceId = deviceId;
20 + }
21 +
22 + @Override
23 + public int hashCode() {
24 + return Objects.hash(providerId, deviceId);
25 + }
26 +
27 + @Override
28 + public boolean equals(Object obj) {
29 + if (this == obj) {
30 + return true;
31 + }
32 + if (!(obj instanceof DeviceFragmentId)) {
33 + return false;
34 + }
35 + DeviceFragmentId that = (DeviceFragmentId) obj;
36 + return Objects.equals(this.deviceId, that.deviceId) &&
37 + Objects.equals(this.providerId, that.providerId);
38 + }
39 +
40 + @Override
41 + public String toString() {
42 + return MoreObjects.toStringHelper(getClass())
43 + .add("providerId", providerId)
44 + .add("deviceId", deviceId)
45 + .toString();
46 + }
47 +
48 + // for serializer
49 + @SuppressWarnings("unused")
50 + private DeviceFragmentId() {
51 + this.providerId = null;
52 + this.deviceId = null;
53 + }
54 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package org.onlab.onos.store.device.impl.peermsg;
2 +
3 +import java.util.Objects;
4 +
5 +import org.onlab.onos.net.DeviceId;
6 +import org.onlab.onos.net.PortNumber;
7 +import org.onlab.onos.net.provider.ProviderId;
8 +
9 +import com.google.common.base.MoreObjects;
10 +
11 +/**
12 + * Identifier for PortDescription from a Provider.
13 + */
14 +public final class PortFragmentId {
15 + public final ProviderId providerId;
16 + public final DeviceId deviceId;
17 + public final PortNumber portNumber;
18 +
19 + public PortFragmentId(DeviceId deviceId, ProviderId providerId,
20 + PortNumber portNumber) {
21 + this.providerId = providerId;
22 + this.deviceId = deviceId;
23 + this.portNumber = portNumber;
24 + }
25 +
26 + @Override
27 + public int hashCode() {
28 + return Objects.hash(providerId, deviceId, portNumber);
29 + };
30 +
31 + @Override
32 + public boolean equals(Object obj) {
33 + if (this == obj) {
34 + return true;
35 + }
36 + if (!(obj instanceof PortFragmentId)) {
37 + return false;
38 + }
39 + PortFragmentId that = (PortFragmentId) obj;
40 + return Objects.equals(this.deviceId, that.deviceId) &&
41 + Objects.equals(this.portNumber, that.portNumber) &&
42 + Objects.equals(this.providerId, that.providerId);
43 + }
44 +
45 + @Override
46 + public String toString() {
47 + return MoreObjects.toStringHelper(getClass())
48 + .add("providerId", providerId)
49 + .add("deviceId", deviceId)
50 + .add("portNumber", portNumber)
51 + .toString();
52 + }
53 +
54 + // for serializer
55 + @SuppressWarnings("unused")
56 + private PortFragmentId() {
57 + this.providerId = null;
58 + this.deviceId = null;
59 + this.portNumber = null;
60 + }
61 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/**
2 + * Structure and utilities used for inter-Node messaging.
3 + */
4 +package org.onlab.onos.store.device.impl.peermsg;
...@@ -43,8 +43,8 @@ public class DistributedFlowRuleStore ...@@ -43,8 +43,8 @@ public class DistributedFlowRuleStore
43 private final Multimap<DeviceId, FlowEntry> flowEntries = 43 private final Multimap<DeviceId, FlowEntry> flowEntries =
44 ArrayListMultimap.<DeviceId, FlowEntry>create(); 44 ArrayListMultimap.<DeviceId, FlowEntry>create();
45 45
46 - private final Multimap<ApplicationId, FlowRule> flowEntriesById = 46 + private final Multimap<Short, FlowRule> flowEntriesById =
47 - ArrayListMultimap.<ApplicationId, FlowRule>create(); 47 + ArrayListMultimap.<Short, FlowRule>create();
48 48
49 @Activate 49 @Activate
50 public void activate() { 50 public void activate() {
...@@ -83,7 +83,7 @@ public class DistributedFlowRuleStore ...@@ -83,7 +83,7 @@ public class DistributedFlowRuleStore
83 83
84 @Override 84 @Override
85 public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) { 85 public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) {
86 - Collection<FlowRule> rules = flowEntriesById.get(appId); 86 + Collection<FlowRule> rules = flowEntriesById.get(appId.id());
87 if (rules == null) { 87 if (rules == null) {
88 return Collections.emptyList(); 88 return Collections.emptyList();
89 } 89 }
......
1 package org.onlab.onos.store.host.impl; 1 package org.onlab.onos.store.host.impl;
2 2
3 -import static org.onlab.onos.net.host.HostEvent.Type.HOST_ADDED; 3 +import com.google.common.collect.HashMultimap;
4 -import static org.onlab.onos.net.host.HostEvent.Type.HOST_MOVED; 4 +import com.google.common.collect.ImmutableSet;
5 -import static org.onlab.onos.net.host.HostEvent.Type.HOST_REMOVED; 5 +import com.google.common.collect.Multimap;
6 -import static org.onlab.onos.net.host.HostEvent.Type.HOST_UPDATED; 6 +import com.google.common.collect.Sets;
7 -import static org.slf4j.LoggerFactory.getLogger;
8 -
9 -import java.util.Collections;
10 -import java.util.HashSet;
11 -import java.util.Map;
12 -import java.util.Set;
13 -import java.util.concurrent.ConcurrentHashMap;
14 -
15 import org.apache.felix.scr.annotations.Activate; 7 import org.apache.felix.scr.annotations.Activate;
16 import org.apache.felix.scr.annotations.Component; 8 import org.apache.felix.scr.annotations.Component;
17 import org.apache.felix.scr.annotations.Deactivate; 9 import org.apache.felix.scr.annotations.Deactivate;
18 import org.apache.felix.scr.annotations.Service; 10 import org.apache.felix.scr.annotations.Service;
11 +import org.onlab.onos.net.Annotations;
19 import org.onlab.onos.net.ConnectPoint; 12 import org.onlab.onos.net.ConnectPoint;
20 import org.onlab.onos.net.DefaultHost; 13 import org.onlab.onos.net.DefaultHost;
21 import org.onlab.onos.net.DeviceId; 14 import org.onlab.onos.net.DeviceId;
22 import org.onlab.onos.net.Host; 15 import org.onlab.onos.net.Host;
23 import org.onlab.onos.net.HostId; 16 import org.onlab.onos.net.HostId;
17 +import org.onlab.onos.net.HostLocation;
24 import org.onlab.onos.net.host.HostDescription; 18 import org.onlab.onos.net.host.HostDescription;
25 import org.onlab.onos.net.host.HostEvent; 19 import org.onlab.onos.net.host.HostEvent;
26 import org.onlab.onos.net.host.HostStore; 20 import org.onlab.onos.net.host.HostStore;
...@@ -33,10 +27,13 @@ import org.onlab.packet.MacAddress; ...@@ -33,10 +27,13 @@ import org.onlab.packet.MacAddress;
33 import org.onlab.packet.VlanId; 27 import org.onlab.packet.VlanId;
34 import org.slf4j.Logger; 28 import org.slf4j.Logger;
35 29
36 -import com.google.common.collect.HashMultimap; 30 +import java.util.HashSet;
37 -import com.google.common.collect.ImmutableSet; 31 +import java.util.Map;
38 -import com.google.common.collect.Multimap; 32 +import java.util.Set;
39 -import com.google.common.collect.Sets; 33 +import java.util.concurrent.ConcurrentHashMap;
34 +
35 +import static org.onlab.onos.net.host.HostEvent.Type.*;
36 +import static org.slf4j.LoggerFactory.getLogger;
40 37
41 /** 38 /**
42 * Manages inventory of end-station hosts using trivial in-memory 39 * Manages inventory of end-station hosts using trivial in-memory
...@@ -46,13 +43,13 @@ import com.google.common.collect.Sets; ...@@ -46,13 +43,13 @@ import com.google.common.collect.Sets;
46 @Component(immediate = true) 43 @Component(immediate = true)
47 @Service 44 @Service
48 public class DistributedHostStore 45 public class DistributedHostStore
49 -extends AbstractStore<HostEvent, HostStoreDelegate> 46 + extends AbstractStore<HostEvent, HostStoreDelegate>
50 -implements HostStore { 47 + implements HostStore {
51 48
52 private final Logger log = getLogger(getClass()); 49 private final Logger log = getLogger(getClass());
53 50
54 // Host inventory 51 // Host inventory
55 - private final Map<HostId, Host> hosts = new ConcurrentHashMap<>(); 52 + private final Map<HostId, StoredHost> hosts = new ConcurrentHashMap<>(2000000, 0.75f, 16);
56 53
57 // Hosts tracked by their location 54 // Hosts tracked by their location
58 private final Multimap<ConnectPoint, Host> locations = HashMultimap.create(); 55 private final Multimap<ConnectPoint, Host> locations = HashMultimap.create();
...@@ -72,8 +69,8 @@ implements HostStore { ...@@ -72,8 +69,8 @@ implements HostStore {
72 69
73 @Override 70 @Override
74 public HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId, 71 public HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId,
75 - HostDescription hostDescription) { 72 + HostDescription hostDescription) {
76 - Host host = hosts.get(hostId); 73 + StoredHost host = hosts.get(hostId);
77 if (host == null) { 74 if (host == null) {
78 return createHost(providerId, hostId, hostDescription); 75 return createHost(providerId, hostId, hostDescription);
79 } 76 }
...@@ -82,12 +79,12 @@ implements HostStore { ...@@ -82,12 +79,12 @@ implements HostStore {
82 79
83 // creates a new host and sends HOST_ADDED 80 // creates a new host and sends HOST_ADDED
84 private HostEvent createHost(ProviderId providerId, HostId hostId, 81 private HostEvent createHost(ProviderId providerId, HostId hostId,
85 - HostDescription descr) { 82 + HostDescription descr) {
86 - DefaultHost newhost = new DefaultHost(providerId, hostId, 83 + StoredHost newhost = new StoredHost(providerId, hostId,
87 - descr.hwAddress(), 84 + descr.hwAddress(),
88 - descr.vlan(), 85 + descr.vlan(),
89 - descr.location(), 86 + descr.location(),
90 - descr.ipAddresses()); 87 + ImmutableSet.of(descr.ipAddress()));
91 synchronized (this) { 88 synchronized (this) {
92 hosts.put(hostId, newhost); 89 hosts.put(hostId, newhost);
93 locations.put(descr.location(), newhost); 90 locations.put(descr.location(), newhost);
...@@ -96,28 +93,24 @@ implements HostStore { ...@@ -96,28 +93,24 @@ implements HostStore {
96 } 93 }
97 94
98 // checks for type of update to host, sends appropriate event 95 // checks for type of update to host, sends appropriate event
99 - private HostEvent updateHost(ProviderId providerId, Host host, 96 + private HostEvent updateHost(ProviderId providerId, StoredHost host,
100 - HostDescription descr) { 97 + HostDescription descr) {
101 - DefaultHost updated;
102 HostEvent event; 98 HostEvent event;
103 if (!host.location().equals(descr.location())) { 99 if (!host.location().equals(descr.location())) {
104 - updated = new DefaultHost(providerId, host.id(), 100 + host.setLocation(descr.location());
105 - host.mac(), 101 + return new HostEvent(HOST_MOVED, host);
106 - host.vlan(), 102 + }
107 - descr.location(), 103 +
108 - host.ipAddresses()); 104 + if (host.ipAddresses().contains(descr.ipAddress())) {
109 - event = new HostEvent(HOST_MOVED, updated);
110 -
111 - } else if (!(host.ipAddresses().equals(descr.ipAddresses()))) {
112 - updated = new DefaultHost(providerId, host.id(),
113 - host.mac(),
114 - host.vlan(),
115 - descr.location(),
116 - descr.ipAddresses());
117 - event = new HostEvent(HOST_UPDATED, updated);
118 - } else {
119 return null; 105 return null;
120 } 106 }
107 +
108 + Set<IpPrefix> addresses = new HashSet<>(host.ipAddresses());
109 + addresses.add(descr.ipAddress());
110 + StoredHost updated = new StoredHost(providerId, host.id(),
111 + host.mac(), host.vlan(),
112 + descr.location(), addresses);
113 + event = new HostEvent(HOST_UPDATED, updated);
121 synchronized (this) { 114 synchronized (this) {
122 hosts.put(host.id(), updated); 115 hosts.put(host.id(), updated);
123 locations.remove(host.location(), host); 116 locations.remove(host.location(), host);
...@@ -145,7 +138,7 @@ implements HostStore { ...@@ -145,7 +138,7 @@ implements HostStore {
145 138
146 @Override 139 @Override
147 public Iterable<Host> getHosts() { 140 public Iterable<Host> getHosts() {
148 - return Collections.unmodifiableSet(new HashSet<>(hosts.values())); 141 + return ImmutableSet.<Host>copyOf(hosts.values());
149 } 142 }
150 143
151 @Override 144 @Override
...@@ -275,4 +268,35 @@ implements HostStore { ...@@ -275,4 +268,35 @@ implements HostStore {
275 return addresses; 268 return addresses;
276 } 269 }
277 270
271 + // Auxiliary extension to allow location to mutate.
272 + private class StoredHost extends DefaultHost {
273 + private HostLocation location;
274 +
275 + /**
276 + * Creates an end-station host using the supplied information.
277 + *
278 + * @param providerId provider identity
279 + * @param id host identifier
280 + * @param mac host MAC address
281 + * @param vlan host VLAN identifier
282 + * @param location host location
283 + * @param ips host IP addresses
284 + * @param annotations optional key/value annotations
285 + */
286 + public StoredHost(ProviderId providerId, HostId id,
287 + MacAddress mac, VlanId vlan, HostLocation location,
288 + Set<IpPrefix> ips, Annotations... annotations) {
289 + super(providerId, id, mac, vlan, location, ips, annotations);
290 + this.location = location;
291 + }
292 +
293 + void setLocation(HostLocation location) {
294 + this.location = location;
295 + }
296 +
297 + @Override
298 + public HostLocation location() {
299 + return location;
300 + }
301 + }
278 } 302 }
......
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.