tom

Merge remote-tracking branch 'origin/master'

...@@ -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);
115 } 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);
116 } 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));
243 + }
244 + }
245 + */
117 } 246 }
......