Showing
6 changed files
with
262 additions
and
49 deletions
... | @@ -34,7 +34,7 @@ private static Logger log = LoggerFactory.getLogger(SimpleNettyClient.class); | ... | @@ -34,7 +34,7 @@ private static Logger log = LoggerFactory.getLogger(SimpleNettyClient.class); |
34 | 34 | ||
35 | System.exit(0); | 35 | System.exit(0); |
36 | } | 36 | } |
37 | - public static void startStandalone(String... args) throws Exception { | 37 | + public static void startStandalone(String[] args) throws Exception { |
38 | String host = args.length > 0 ? args[0] : "localhost"; | 38 | String host = args.length > 0 ? args[0] : "localhost"; |
39 | int port = args.length > 1 ? Integer.parseInt(args[1]) : 8081; | 39 | int port = args.length > 1 ? Integer.parseInt(args[1]) : 8081; |
40 | int warmup = args.length > 2 ? Integer.parseInt(args[2]) : 1000; | 40 | int warmup = args.length > 2 ? Integer.parseInt(args[2]) : 1000; |
... | @@ -46,7 +46,7 @@ private static Logger log = LoggerFactory.getLogger(SimpleNettyClient.class); | ... | @@ -46,7 +46,7 @@ private static Logger log = LoggerFactory.getLogger(SimpleNettyClient.class); |
46 | metrics.activate(); | 46 | metrics.activate(); |
47 | MetricsFeature feature = new MetricsFeature("latency"); | 47 | MetricsFeature feature = new MetricsFeature("latency"); |
48 | MetricsComponent component = metrics.registerComponent("NettyMessaging"); | 48 | MetricsComponent component = metrics.registerComponent("NettyMessaging"); |
49 | - log.info("warmup...."); | 49 | + log.info("connecting " + host + ":" + port + " warmup:" + warmup + " iterations:" + iterations); |
50 | 50 | ||
51 | for (int i = 0; i < warmup; i++) { | 51 | for (int i = 0; i < warmup; i++) { |
52 | messaging.sendAsync(endpoint, "simple", "Hello World".getBytes()); | 52 | messaging.sendAsync(endpoint, "simple", "Hello World".getBytes()); |
... | @@ -73,6 +73,7 @@ private static Logger log = LoggerFactory.getLogger(SimpleNettyClient.class); | ... | @@ -73,6 +73,7 @@ private static Logger log = LoggerFactory.getLogger(SimpleNettyClient.class); |
73 | // System.out.println("Got back:" + new String(response.get(2, TimeUnit.SECONDS))); | 73 | // System.out.println("Got back:" + new String(response.get(2, TimeUnit.SECONDS))); |
74 | context.stop(); | 74 | context.stop(); |
75 | } | 75 | } |
76 | + metrics.deactivate(); | ||
76 | } | 77 | } |
77 | 78 | ||
78 | public static class TestNettyMessagingService extends NettyMessagingService { | 79 | public static class TestNettyMessagingService extends NettyMessagingService { | ... | ... |
... | @@ -18,15 +18,15 @@ public class SimpleNettyClientCommand extends AbstractShellCommand { | ... | @@ -18,15 +18,15 @@ public class SimpleNettyClientCommand extends AbstractShellCommand { |
18 | required = false, multiValued = false) | 18 | required = false, multiValued = false) |
19 | String hostname = "localhost"; | 19 | String hostname = "localhost"; |
20 | 20 | ||
21 | - @Argument(index = 3, name = "port", description = "Port", | 21 | + @Argument(index = 1, name = "port", description = "Port", |
22 | required = false, multiValued = false) | 22 | required = false, multiValued = false) |
23 | String port = "8081"; | 23 | String port = "8081"; |
24 | 24 | ||
25 | - @Argument(index = 1, name = "warmupCount", description = "Warm-up count", | 25 | + @Argument(index = 2, name = "warmupCount", description = "Warm-up count", |
26 | required = false, multiValued = false) | 26 | required = false, multiValued = false) |
27 | String warmupCount = "1000"; | 27 | String warmupCount = "1000"; |
28 | 28 | ||
29 | - @Argument(index = 2, name = "messageCount", description = "Message count", | 29 | + @Argument(index = 3, name = "messageCount", description = "Message count", |
30 | required = false, multiValued = false) | 30 | required = false, multiValued = false) |
31 | String messageCount = "100000"; | 31 | String messageCount = "100000"; |
32 | 32 | ... | ... |
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 | } | ... | ... |
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 | ... | ... |
... | @@ -13,12 +13,14 @@ import static org.onlab.util.Tools.namedThreads; | ... | @@ -13,12 +13,14 @@ 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; |
21 | import java.util.concurrent.ExecutorService; | 22 | import java.util.concurrent.ExecutorService; |
23 | +import java.util.concurrent.Future; | ||
22 | 24 | ||
23 | import org.apache.felix.scr.annotations.Activate; | 25 | import org.apache.felix.scr.annotations.Activate; |
24 | import org.apache.felix.scr.annotations.Component; | 26 | import org.apache.felix.scr.annotations.Component; |
... | @@ -28,6 +30,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -28,6 +30,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
28 | import org.apache.felix.scr.annotations.Service; | 30 | import org.apache.felix.scr.annotations.Service; |
29 | import org.onlab.onos.event.AbstractListenerRegistry; | 31 | import org.onlab.onos.event.AbstractListenerRegistry; |
30 | import org.onlab.onos.event.EventDeliveryService; | 32 | import org.onlab.onos.event.EventDeliveryService; |
33 | +import org.onlab.onos.net.flow.CompletedBatchOperation; | ||
31 | import org.onlab.onos.net.intent.InstallableIntent; | 34 | import org.onlab.onos.net.intent.InstallableIntent; |
32 | import org.onlab.onos.net.intent.Intent; | 35 | import org.onlab.onos.net.intent.Intent; |
33 | import org.onlab.onos.net.intent.IntentCompiler; | 36 | import org.onlab.onos.net.intent.IntentCompiler; |
... | @@ -44,7 +47,9 @@ import org.onlab.onos.net.intent.IntentStore; | ... | @@ -44,7 +47,9 @@ import org.onlab.onos.net.intent.IntentStore; |
44 | import org.onlab.onos.net.intent.IntentStoreDelegate; | 47 | import org.onlab.onos.net.intent.IntentStoreDelegate; |
45 | import org.slf4j.Logger; | 48 | import org.slf4j.Logger; |
46 | 49 | ||
50 | +import com.google.common.collect.ImmutableList; | ||
47 | import com.google.common.collect.ImmutableMap; | 51 | import com.google.common.collect.ImmutableMap; |
52 | +import com.google.common.collect.Lists; | ||
48 | 53 | ||
49 | /** | 54 | /** |
50 | * An implementation of Intent Manager. | 55 | * An implementation of Intent Manager. |
... | @@ -67,7 +72,8 @@ public class IntentManager | ... | @@ -67,7 +72,8 @@ public class IntentManager |
67 | private final AbstractListenerRegistry<IntentEvent, IntentListener> | 72 | private final AbstractListenerRegistry<IntentEvent, IntentListener> |
68 | listenerRegistry = new AbstractListenerRegistry<>(); | 73 | listenerRegistry = new AbstractListenerRegistry<>(); |
69 | 74 | ||
70 | - private final ExecutorService executor = newSingleThreadExecutor(namedThreads("onos-intents")); | 75 | + private ExecutorService executor; |
76 | + private ExecutorService monitorExecutor; | ||
71 | 77 | ||
72 | private final IntentStoreDelegate delegate = new InternalStoreDelegate(); | 78 | private final IntentStoreDelegate delegate = new InternalStoreDelegate(); |
73 | private final TopologyChangeDelegate topoDelegate = new InternalTopoChangeDelegate(); | 79 | private final TopologyChangeDelegate topoDelegate = new InternalTopoChangeDelegate(); |
... | @@ -86,6 +92,8 @@ public class IntentManager | ... | @@ -86,6 +92,8 @@ public class IntentManager |
86 | store.setDelegate(delegate); | 92 | store.setDelegate(delegate); |
87 | trackerService.setDelegate(topoDelegate); | 93 | trackerService.setDelegate(topoDelegate); |
88 | eventDispatcher.addSink(IntentEvent.class, listenerRegistry); | 94 | eventDispatcher.addSink(IntentEvent.class, listenerRegistry); |
95 | + executor = newSingleThreadExecutor(namedThreads("onos-intents")); | ||
96 | + monitorExecutor = newSingleThreadExecutor(namedThreads("onos-intent-monitor")); | ||
89 | log.info("Started"); | 97 | log.info("Started"); |
90 | } | 98 | } |
91 | 99 | ||
... | @@ -94,6 +102,8 @@ public class IntentManager | ... | @@ -94,6 +102,8 @@ public class IntentManager |
94 | store.unsetDelegate(delegate); | 102 | store.unsetDelegate(delegate); |
95 | trackerService.unsetDelegate(topoDelegate); | 103 | trackerService.unsetDelegate(topoDelegate); |
96 | eventDispatcher.removeSink(IntentEvent.class); | 104 | eventDispatcher.removeSink(IntentEvent.class); |
105 | + executor.shutdown(); | ||
106 | + monitorExecutor.shutdown(); | ||
97 | log.info("Stopped"); | 107 | log.info("Stopped"); |
98 | } | 108 | } |
99 | 109 | ||
... | @@ -240,14 +250,23 @@ public class IntentManager | ... | @@ -240,14 +250,23 @@ public class IntentManager |
240 | } | 250 | } |
241 | } | 251 | } |
242 | 252 | ||
243 | - // FIXME: To make SDN-IP workable ASAP, only single level compilation is implemented | 253 | + /** |
244 | - // TODO: implement compilation traversing tree structure | 254 | + * Compiles an intent recursively. |
255 | + * | ||
256 | + * @param intent intent | ||
257 | + * @return result of compilation | ||
258 | + */ | ||
245 | private List<InstallableIntent> compileIntent(Intent intent) { | 259 | private List<InstallableIntent> compileIntent(Intent intent) { |
260 | + if (intent instanceof InstallableIntent) { | ||
261 | + return ImmutableList.of((InstallableIntent) intent); | ||
262 | + } | ||
263 | + | ||
246 | List<InstallableIntent> installable = new ArrayList<>(); | 264 | List<InstallableIntent> installable = new ArrayList<>(); |
265 | + // TODO do we need to registerSubclassCompiler? | ||
247 | for (Intent compiled : getCompiler(intent).compile(intent)) { | 266 | for (Intent compiled : getCompiler(intent).compile(intent)) { |
248 | - InstallableIntent installableIntent = (InstallableIntent) compiled; | 267 | + installable.addAll(compileIntent(compiled)); |
249 | - installable.add(installableIntent); | ||
250 | } | 268 | } |
269 | + | ||
251 | return installable; | 270 | return installable; |
252 | } | 271 | } |
253 | 272 | ||
... | @@ -261,6 +280,7 @@ public class IntentManager | ... | @@ -261,6 +280,7 @@ public class IntentManager |
261 | // Indicate that the intent is entering the installing phase. | 280 | // Indicate that the intent is entering the installing phase. |
262 | store.setState(intent, INSTALLING); | 281 | store.setState(intent, INSTALLING); |
263 | 282 | ||
283 | + List<Future<CompletedBatchOperation>> installFutures = Lists.newArrayList(); | ||
264 | try { | 284 | try { |
265 | List<InstallableIntent> installables = store.getInstallableIntents(intent.id()); | 285 | List<InstallableIntent> installables = store.getInstallableIntents(intent.id()); |
266 | if (installables != null) { | 286 | if (installables != null) { |
... | @@ -268,17 +288,20 @@ public class IntentManager | ... | @@ -268,17 +288,20 @@ public class IntentManager |
268 | registerSubclassInstallerIfNeeded(installable); | 288 | registerSubclassInstallerIfNeeded(installable); |
269 | trackerService.addTrackedResources(intent.id(), | 289 | trackerService.addTrackedResources(intent.id(), |
270 | installable.requiredLinks()); | 290 | installable.requiredLinks()); |
271 | - getInstaller(installable).install(installable); | 291 | + Future<CompletedBatchOperation> future = getInstaller(installable).install(installable); |
292 | + installFutures.add(future); | ||
272 | } | 293 | } |
273 | } | 294 | } |
274 | - eventDispatcher.post(store.setState(intent, INSTALLED)); | 295 | + // FIXME we have to wait for the installable intents |
275 | - | 296 | + //eventDispatcher.post(store.setState(intent, INSTALLED)); |
297 | + monitorExecutor.execute(new IntentInstallMonitor(intent, installFutures, INSTALLED)); | ||
276 | } catch (Exception e) { | 298 | } catch (Exception e) { |
277 | log.warn("Unable to install intent {} due to: {}", intent.id(), e); | 299 | log.warn("Unable to install intent {} due to: {}", intent.id(), e); |
278 | - uninstallIntent(intent); | 300 | + uninstallIntent(intent, RECOMPILING); |
279 | 301 | ||
280 | // If compilation failed, kick off the recompiling phase. | 302 | // If compilation failed, kick off the recompiling phase. |
281 | - executeRecompilingPhase(intent); | 303 | + // FIXME |
304 | + //executeRecompilingPhase(intent); | ||
282 | } | 305 | } |
283 | } | 306 | } |
284 | 307 | ||
... | @@ -327,12 +350,14 @@ public class IntentManager | ... | @@ -327,12 +350,14 @@ public class IntentManager |
327 | private void executeWithdrawingPhase(Intent intent) { | 350 | private void executeWithdrawingPhase(Intent intent) { |
328 | // Indicate that the intent is being withdrawn. | 351 | // Indicate that the intent is being withdrawn. |
329 | store.setState(intent, WITHDRAWING); | 352 | store.setState(intent, WITHDRAWING); |
330 | - uninstallIntent(intent); | 353 | + uninstallIntent(intent, WITHDRAWN); |
331 | 354 | ||
332 | // If all went well, disassociate the top-level intent with its | 355 | // If all went well, disassociate the top-level intent with its |
333 | // installable derivatives and mark it as withdrawn. | 356 | // installable derivatives and mark it as withdrawn. |
334 | - store.removeInstalledIntents(intent.id()); | 357 | + // FIXME need to clean up |
335 | - eventDispatcher.post(store.setState(intent, WITHDRAWN)); | 358 | + //store.removeInstalledIntents(intent.id()); |
359 | + // FIXME | ||
360 | + //eventDispatcher.post(store.setState(intent, WITHDRAWN)); | ||
336 | } | 361 | } |
337 | 362 | ||
338 | /** | 363 | /** |
... | @@ -340,14 +365,17 @@ public class IntentManager | ... | @@ -340,14 +365,17 @@ public class IntentManager |
340 | * | 365 | * |
341 | * @param intent intent to be uninstalled | 366 | * @param intent intent to be uninstalled |
342 | */ | 367 | */ |
343 | - private void uninstallIntent(Intent intent) { | 368 | + private void uninstallIntent(Intent intent, IntentState nextState) { |
369 | + List<Future<CompletedBatchOperation>> uninstallFutures = Lists.newArrayList(); | ||
344 | try { | 370 | try { |
345 | List<InstallableIntent> installables = store.getInstallableIntents(intent.id()); | 371 | List<InstallableIntent> installables = store.getInstallableIntents(intent.id()); |
346 | if (installables != null) { | 372 | if (installables != null) { |
347 | for (InstallableIntent installable : installables) { | 373 | for (InstallableIntent installable : installables) { |
348 | - getInstaller(installable).uninstall(installable); | 374 | + Future<CompletedBatchOperation> future = getInstaller(installable).uninstall(installable); |
375 | + uninstallFutures.add(future); | ||
349 | } | 376 | } |
350 | } | 377 | } |
378 | + monitorExecutor.execute(new IntentInstallMonitor(intent, uninstallFutures, nextState)); | ||
351 | } catch (IntentException e) { | 379 | } catch (IntentException e) { |
352 | log.warn("Unable to uninstall intent {} due to: {}", intent.id(), e); | 380 | log.warn("Unable to uninstall intent {} due to: {}", intent.id(), e); |
353 | } | 381 | } |
... | @@ -422,9 +450,10 @@ public class IntentManager | ... | @@ -422,9 +450,10 @@ public class IntentManager |
422 | // Attempt recompilation of the specified intents first. | 450 | // Attempt recompilation of the specified intents first. |
423 | for (IntentId intentId : intentIds) { | 451 | for (IntentId intentId : intentIds) { |
424 | Intent intent = getIntent(intentId); | 452 | Intent intent = getIntent(intentId); |
425 | - uninstallIntent(intent); | 453 | + uninstallIntent(intent, RECOMPILING); |
426 | 454 | ||
427 | - executeRecompilingPhase(intent); | 455 | + //FIXME |
456 | + //executeRecompilingPhase(intent); | ||
428 | } | 457 | } |
429 | 458 | ||
430 | if (compileAllFailed) { | 459 | if (compileAllFailed) { |
... | @@ -460,4 +489,44 @@ public class IntentManager | ... | @@ -460,4 +489,44 @@ public class IntentManager |
460 | } | 489 | } |
461 | } | 490 | } |
462 | 491 | ||
492 | + private class IntentInstallMonitor implements Runnable { | ||
493 | + | ||
494 | + private final Intent intent; | ||
495 | + private final List<Future<CompletedBatchOperation>> futures; | ||
496 | + private final IntentState nextState; | ||
497 | + | ||
498 | + public IntentInstallMonitor(Intent intent, | ||
499 | + List<Future<CompletedBatchOperation>> futures, IntentState nextState) { | ||
500 | + this.intent = intent; | ||
501 | + this.futures = futures; | ||
502 | + this.nextState = nextState; | ||
503 | + } | ||
504 | + | ||
505 | + private void updateIntent(Intent intent) { | ||
506 | + if (nextState == RECOMPILING) { | ||
507 | + executor.execute(new IntentTask(nextState, intent)); | ||
508 | + } else if (nextState == INSTALLED || nextState == WITHDRAWN) { | ||
509 | + eventDispatcher.post(store.setState(intent, nextState)); | ||
510 | + } else { | ||
511 | + log.warn("Invalid next intent state {} for intent {}", nextState, intent); | ||
512 | + } | ||
513 | + } | ||
514 | + | ||
515 | + @Override | ||
516 | + public void run() { | ||
517 | + for (Iterator<Future<CompletedBatchOperation>> i = futures.iterator(); i.hasNext();) { | ||
518 | + Future<CompletedBatchOperation> future = i.next(); | ||
519 | + if (future.isDone()) { | ||
520 | + // TODO: we may want to get the future here | ||
521 | + i.remove(); | ||
522 | + } | ||
523 | + } | ||
524 | + if (futures.isEmpty()) { | ||
525 | + updateIntent(intent); | ||
526 | + } else { | ||
527 | + // resubmit ourselves if we are not done yet | ||
528 | + monitorExecutor.submit(this); | ||
529 | + } | ||
530 | + } | ||
531 | + } | ||
463 | } | 532 | } | ... | ... |
... | @@ -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; |
... | @@ -15,6 +15,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -15,6 +15,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
15 | import org.onlab.onos.ApplicationId; | 15 | import org.onlab.onos.ApplicationId; |
16 | import org.onlab.onos.net.ConnectPoint; | 16 | import org.onlab.onos.net.ConnectPoint; |
17 | import org.onlab.onos.net.Link; | 17 | import org.onlab.onos.net.Link; |
18 | +import org.onlab.onos.net.flow.CompletedBatchOperation; | ||
18 | import org.onlab.onos.net.flow.DefaultFlowRule; | 19 | import org.onlab.onos.net.flow.DefaultFlowRule; |
19 | import org.onlab.onos.net.flow.DefaultTrafficSelector; | 20 | import org.onlab.onos.net.flow.DefaultTrafficSelector; |
20 | import org.onlab.onos.net.flow.FlowRule; | 21 | import org.onlab.onos.net.flow.FlowRule; |
... | @@ -57,8 +58,26 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -57,8 +58,26 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
57 | intentManager.unregisterInstaller(PathIntent.class); | 58 | intentManager.unregisterInstaller(PathIntent.class); |
58 | } | 59 | } |
59 | 60 | ||
61 | + /** | ||
62 | + * Apply a list of FlowRules. | ||
63 | + * | ||
64 | + * @param rules rules to apply | ||
65 | + */ | ||
66 | + private Future<CompletedBatchOperation> applyBatch(List<FlowRuleBatchEntry> rules) { | ||
67 | + FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules); | ||
68 | + Future<CompletedBatchOperation> future = flowRuleService.applyBatch(batch); | ||
69 | + return future; | ||
70 | +// try { | ||
71 | +// //FIXME don't do this here | ||
72 | +// future.get(); | ||
73 | +// } catch (InterruptedException | ExecutionException e) { | ||
74 | +// // TODO Auto-generated catch block | ||
75 | +// e.printStackTrace(); | ||
76 | +// } | ||
77 | + } | ||
78 | + | ||
60 | @Override | 79 | @Override |
61 | - public void install(PathIntent intent) { | 80 | + public Future<CompletedBatchOperation> install(PathIntent intent) { |
62 | TrafficSelector.Builder builder = | 81 | TrafficSelector.Builder builder = |
63 | DefaultTrafficSelector.builder(intent.selector()); | 82 | DefaultTrafficSelector.builder(intent.selector()); |
64 | Iterator<Link> links = intent.path().links().iterator(); | 83 | Iterator<Link> links = intent.path().links().iterator(); |
... | @@ -74,20 +93,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -74,20 +93,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
74 | builder.build(), treatment, | 93 | builder.build(), treatment, |
75 | 123, appId, 600); | 94 | 123, appId, 600); |
76 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)); | 95 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)); |
77 | - //flowRuleService.applyFlowRules(rule); | ||
78 | prev = link.dst(); | 96 | prev = link.dst(); |
79 | } | 97 | } |
80 | - FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules); | 98 | + |
81 | - try { | 99 | + return applyBatch(rules); |
82 | - flowRuleService.applyBatch(batch).get(); | ||
83 | - } catch (InterruptedException | ExecutionException e) { | ||
84 | - // TODO Auto-generated catch block | ||
85 | - e.printStackTrace(); | ||
86 | - } | ||
87 | } | 100 | } |
88 | 101 | ||
89 | @Override | 102 | @Override |
90 | - public void uninstall(PathIntent intent) { | 103 | + public Future<CompletedBatchOperation> uninstall(PathIntent intent) { |
91 | TrafficSelector.Builder builder = | 104 | TrafficSelector.Builder builder = |
92 | DefaultTrafficSelector.builder(intent.selector()); | 105 | DefaultTrafficSelector.builder(intent.selector()); |
93 | Iterator<Link> links = intent.path().links().iterator(); | 106 | Iterator<Link> links = intent.path().links().iterator(); |
... | @@ -103,15 +116,131 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -103,15 +116,131 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
103 | builder.build(), treatment, | 116 | builder.build(), treatment, |
104 | 123, appId, 600); | 117 | 123, appId, 600); |
105 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule)); | 118 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule)); |
106 | - //flowRuleService.removeFlowRules(rule); | ||
107 | prev = link.dst(); | 119 | prev = link.dst(); |
108 | } | 120 | } |
109 | - FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules); | 121 | + return applyBatch(rules); |
110 | - try { | 122 | + } |
111 | - flowRuleService.applyBatch(batch).get(); | 123 | + |
112 | - } catch (InterruptedException | ExecutionException e) { | 124 | + // TODO refactor below this line... ---------------------------- |
113 | - // TODO Auto-generated catch block | 125 | + |
114 | - e.printStackTrace(); | 126 | + /** |
127 | + * Generates the series of MatchActionOperations from the | ||
128 | + * {@link FlowBatchOperation}. | ||
129 | + * <p> | ||
130 | + * FIXME: Currently supporting PacketPathFlow and SingleDstTreeFlow only. | ||
131 | + * <p> | ||
132 | + * FIXME: MatchActionOperations should have dependency field to the other | ||
133 | + * match action operations, and this method should use this. | ||
134 | + * | ||
135 | + * @param op the {@link FlowBatchOperation} object | ||
136 | + * @return the list of {@link MatchActionOperations} objects | ||
137 | + */ | ||
138 | + /* | ||
139 | + private List<MatchActionOperations> | ||
140 | + generateMatchActionOperationsList(FlowBatchOperation op) { | ||
141 | + | ||
142 | + // MatchAction operations at head (ingress) switches. | ||
143 | + MatchActionOperations headOps = matchActionService.createOperationsList(); | ||
144 | + | ||
145 | + // MatchAction operations at rest of the switches. | ||
146 | + MatchActionOperations tailOps = matchActionService.createOperationsList(); | ||
147 | + | ||
148 | + MatchActionOperations removeOps = matchActionService.createOperationsList(); | ||
149 | + | ||
150 | + for (BatchOperationEntry<Operator, ?> e : op.getOperations()) { | ||
151 | + | ||
152 | + if (e.getOperator() == FlowBatchOperation.Operator.ADD) { | ||
153 | + generateInstallMatchActionOperations(e, tailOps, headOps); | ||
154 | + } else if (e.getOperator() == FlowBatchOperation.Operator.REMOVE) { | ||
155 | + generateRemoveMatchActionOperations(e, removeOps); | ||
156 | + } else { | ||
157 | + throw new UnsupportedOperationException( | ||
158 | + "FlowManager supports ADD and REMOVE operations only."); | ||
159 | + } | ||
160 | + | ||
161 | + } | ||
162 | + | ||
163 | + return Arrays.asList(tailOps, headOps, removeOps); | ||
164 | + } | ||
165 | + */ | ||
166 | + | ||
167 | + /** | ||
168 | + * Generates MatchActionOperations for an INSTALL FlowBatchOperation. | ||
169 | + * <p/> | ||
170 | + * FIXME: Currently only supports flows that generate exactly two match | ||
171 | + * action operation sets. | ||
172 | + * | ||
173 | + * @param e Flow BatchOperationEntry | ||
174 | + * @param tailOps MatchActionOperation set that the tail | ||
175 | + * MatchActionOperations will be placed in | ||
176 | + * @param headOps MatchActionOperation set that the head | ||
177 | + * MatchActionOperations will be placed in | ||
178 | + */ | ||
179 | + /* | ||
180 | + private void generateInstallMatchActionOperations( | ||
181 | + BatchOperationEntry<Operator, ?> e, | ||
182 | + MatchActionOperations tailOps, | ||
183 | + MatchActionOperations headOps) { | ||
184 | + | ||
185 | + if (!(e.getTarget() instanceof Flow)) { | ||
186 | + throw new IllegalStateException( | ||
187 | + "The target is not Flow object: " + e.getTarget()); | ||
188 | + } | ||
189 | + | ||
190 | + // Compile flows to match-actions | ||
191 | + Flow flow = (Flow) e.getTarget(); | ||
192 | + List<MatchActionOperations> maOps = flow.compile( | ||
193 | + e.getOperator(), matchActionService); | ||
194 | + verifyNotNull(maOps, "Could not compile the flow: " + flow); | ||
195 | + verify(maOps.size() == 2, | ||
196 | + "The flow generates unspported match-action operations."); | ||
197 | + | ||
198 | + // Map FlowId to MatchActionIds | ||
199 | + for (MatchActionOperations maOp : maOps) { | ||
200 | + for (MatchActionOperationEntry entry : maOp.getOperations()) { | ||
201 | + flowMatchActionsMap.put( | ||
202 | + KryoFactory.serialize(flow.getId()), | ||
203 | + KryoFactory.serialize(entry.getTarget())); | ||
204 | + } | ||
205 | + } | ||
206 | + | ||
207 | + // Merge match-action operations | ||
208 | + for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) { | ||
209 | + verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL); | ||
210 | + tailOps.addOperation(mae); | ||
211 | + } | ||
212 | + for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) { | ||
213 | + verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL); | ||
214 | + headOps.addOperation(mae); | ||
215 | + } | ||
216 | + } | ||
217 | + */ | ||
218 | + /** | ||
219 | + * Generates MatchActionOperations for a REMOVE FlowBatchOperation. | ||
220 | + * | ||
221 | + * @param e Flow BatchOperationEntry | ||
222 | + * @param removeOps MatchActionOperation set that the remove | ||
223 | + * MatchActionOperations will be placed in | ||
224 | + */ | ||
225 | + /* | ||
226 | + private void generateRemoveMatchActionOperations( | ||
227 | + BatchOperationEntry<Operator, ?> e, | ||
228 | + MatchActionOperations removeOps) { | ||
229 | + | ||
230 | + if (!(e.getTarget() instanceof FlowId)) { | ||
231 | + throw new IllegalStateException( | ||
232 | + "The target is not a FlowId object: " + e.getTarget()); | ||
233 | + } | ||
234 | + | ||
235 | + // Compile flows to match-actions | ||
236 | + FlowId flowId = (FlowId) e.getTarget(); | ||
237 | + | ||
238 | + for (byte[] matchActionIdBytes : | ||
239 | + flowMatchActionsMap.remove(KryoFactory.serialize(flowId))) { | ||
240 | + MatchActionId matchActionId = KryoFactory.deserialize(matchActionIdBytes); | ||
241 | + removeOps.addOperation(new MatchActionOperationEntry( | ||
242 | + MatchActionOperations.Operator.REMOVE, matchActionId)); | ||
115 | } | 243 | } |
116 | } | 244 | } |
245 | + */ | ||
117 | } | 246 | } | ... | ... |
-
Please register or login to post a comment