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 | } | ... | ... |
apps/sdnip/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
5 | + <modelVersion>4.0.0</modelVersion> | ||
6 | + | ||
7 | + <parent> | ||
8 | + <groupId>org.onlab.onos</groupId> | ||
9 | + <artifactId>onos-apps</artifactId> | ||
10 | + <version>1.0.0-SNAPSHOT</version> | ||
11 | + <relativePath>../pom.xml</relativePath> | ||
12 | + </parent> | ||
13 | + | ||
14 | + <artifactId>onos-app-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 | +} |
... | @@ -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 | } | ... | ... |
... | @@ -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 | ... | ... |
... | @@ -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 | +} |
... | @@ -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 | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -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 | ... | ... |
core/store/dist/src/main/java/org/onlab/onos/store/common/impl/AntiEntropyAdvertisement.java
deleted
100644 → 0
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 | -} |
core/store/dist/src/main/java/org/onlab/onos/store/common/impl/AntiEntropyReply.java
deleted
100644 → 0
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 | -} |
core/store/dist/src/main/java/org/onlab/onos/store/device/impl/DeviceAntiEntropyReply.java
deleted
100644 → 0
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 | +} |
This diff is collapsed. Click to expand it.
core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStoreMessageSubjects.java
... | @@ -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); | ... | ... |
core/store/dist/src/main/java/org/onlab/onos/store/device/impl/VersionedValue.java
deleted
100644 → 0
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 | +} |
core/store/dist/src/main/java/org/onlab/onos/store/device/impl/peermsg/DeviceAntiEntropyRequest.java
0 → 100644
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 | +} |
core/store/dist/src/main/java/org/onlab/onos/store/device/impl/peermsg/DeviceFragmentId.java
0 → 100644
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 |
core/store/dist/src/main/java/org/onlab/onos/store/device/impl/peermsg/PortFragmentId.java
0 → 100644
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 |
... | @@ -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.
core/store/dist/src/main/java/org/onlab/onos/store/link/impl/GossipLinkStoreMessageSubjects.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/dist/src/main/java/org/onlab/onos/store/link/impl/InternalLinkRemovedEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
core/store/dist/src/main/java/org/onlab/onos/store/link/impl/LinkAntiEntropyAdvertisement.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/dist/src/main/java/org/onlab/onos/store/link/impl/OnosDistributedLinkStore.java
deleted
100644 → 0
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/dist/src/main/java/org/onlab/onos/store/serializers/DistributedStoreSerializers.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/dist/src/test/java/org/onlab/onos/store/device/impl/peermsg/DeviceFragmentIdTest.java
0 → 100644
This diff is collapsed. Click to expand it.
core/store/dist/src/test/java/org/onlab/onos/store/device/impl/peermsg/PortFragmentIdTest.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
core/store/serializers/src/main/java/org/onlab/onos/store/serializers/ImmutableListSerializer.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFOpticalSwitchImplLINC13.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
This diff is collapsed. Click to expand it.
providers/openflow/host/src/main/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProvider.java
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
tools/package/bin/onos-jpenable
0 → 100755
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
tools/test/bin/onos-update-bundle
0 → 100755
This diff is collapsed. Click to expand it.
tools/test/bin/onos-watch
0 → 100755
This diff is collapsed. Click to expand it.
tools/test/cells/cbench
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment