Brian O'Connor

Intent F/W improvements

 - aggregate installables into FlowRuleOperations
 - added some impl. to SimpleIntentStore
 - created Coordinating State

Change-Id: I5b26ec1fdb7aaff9d5da4f21b2d5a249568ac5ac
...@@ -15,16 +15,14 @@ ...@@ -15,16 +15,14 @@
15 */ 15 */
16 package org.onosproject.net.intent; 16 package org.onosproject.net.intent;
17 17
18 -import org.onosproject.net.flow.FlowRule;
19 -import org.onosproject.net.flow.FlowRuleBatchEntry;
20 import org.onosproject.net.flow.FlowRuleBatchOperation; 18 import org.onosproject.net.flow.FlowRuleBatchOperation;
21 -import org.onosproject.net.flow.FlowRuleOperations;
22 19
23 import java.util.List; 20 import java.util.List;
24 21
25 /** 22 /**
26 * Abstraction of entity capable of installing intents to the environment. 23 * Abstraction of entity capable of installing intents to the environment.
27 */ 24 */
25 +//TODO consider refactoring this API
28 public interface IntentInstaller<T extends Intent> { 26 public interface IntentInstaller<T extends Intent> {
29 /** 27 /**
30 * Installs the specified intent to the environment. 28 * Installs the specified intent to the environment.
...@@ -33,32 +31,7 @@ public interface IntentInstaller<T extends Intent> { ...@@ -33,32 +31,7 @@ public interface IntentInstaller<T extends Intent> {
33 * @return flow rule operations to complete install 31 * @return flow rule operations to complete install
34 * @throws IntentException if issues are encountered while installing the intent 32 * @throws IntentException if issues are encountered while installing the intent
35 */ 33 */
36 - @Deprecated
37 List<FlowRuleBatchOperation> install(T intent); 34 List<FlowRuleBatchOperation> install(T intent);
38 - // FIXME
39 - default FlowRuleOperations.Builder install2(T intent) {
40 - FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
41 - for (FlowRuleBatchOperation batch : install(intent)) {
42 - for (FlowRuleBatchEntry entry : batch.getOperations()) {
43 - FlowRule rule = entry.target();
44 - switch (entry.operator()) {
45 - case ADD:
46 - builder.add(rule);
47 - break;
48 - case REMOVE:
49 - builder.remove(rule);
50 - break;
51 - case MODIFY:
52 - builder.modify(rule);
53 - break;
54 - default:
55 - break;
56 - }
57 - }
58 - builder.newStage();
59 - }
60 - return builder;
61 - }
62 35
63 /** 36 /**
64 * Uninstalls the specified intent from the environment. 37 * Uninstalls the specified intent from the environment.
...@@ -67,32 +40,7 @@ public interface IntentInstaller<T extends Intent> { ...@@ -67,32 +40,7 @@ public interface IntentInstaller<T extends Intent> {
67 * @return flow rule operations to complete uninstall 40 * @return flow rule operations to complete uninstall
68 * @throws IntentException if issues are encountered while uninstalling the intent 41 * @throws IntentException if issues are encountered while uninstalling the intent
69 */ 42 */
70 - @Deprecated
71 List<FlowRuleBatchOperation> uninstall(T intent); 43 List<FlowRuleBatchOperation> uninstall(T intent);
72 - // FIXME
73 - default FlowRuleOperations.Builder uninstall2(T intent) {
74 - FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
75 - for (FlowRuleBatchOperation batch : uninstall(intent)) {
76 - for (FlowRuleBatchEntry entry : batch.getOperations()) {
77 - FlowRule rule = entry.target();
78 - switch (entry.operator()) {
79 - case ADD:
80 - builder.add(rule);
81 - break;
82 - case REMOVE:
83 - builder.remove(rule);
84 - break;
85 - case MODIFY:
86 - builder.modify(rule);
87 - break;
88 - default:
89 - break;
90 - }
91 - }
92 - builder.newStage();
93 - }
94 - return builder;
95 - }
96 44
97 /** 45 /**
98 * Replaces the specified intent with a new one in the environment. 46 * Replaces the specified intent with a new one in the environment.
...@@ -104,29 +52,5 @@ public interface IntentInstaller<T extends Intent> { ...@@ -104,29 +52,5 @@ public interface IntentInstaller<T extends Intent> {
104 */ 52 */
105 @Deprecated 53 @Deprecated
106 List<FlowRuleBatchOperation> replace(T oldIntent, T newIntent); 54 List<FlowRuleBatchOperation> replace(T oldIntent, T newIntent);
107 - // FIXME
108 - default FlowRuleOperations.Builder replace2(T oldIntent, T newIntent) {
109 - FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
110 - for (FlowRuleBatchOperation batch : replace(oldIntent, newIntent)) {
111 - for (FlowRuleBatchEntry entry : batch.getOperations()) {
112 - FlowRule rule = entry.target();
113 - switch (entry.operator()) {
114 - case ADD:
115 - builder.add(rule);
116 - break;
117 - case REMOVE:
118 - builder.remove(rule);
119 - break;
120 - case MODIFY:
121 - builder.modify(rule);
122 - break;
123 - default:
124 - break;
125 - }
126 - }
127 - builder.newStage();
128 - }
129 - return builder;
130 - }
131 55
132 } 56 }
......
...@@ -46,7 +46,7 @@ class Compiling implements IntentUpdate { ...@@ -46,7 +46,7 @@ class Compiling implements IntentUpdate {
46 try { 46 try {
47 List<Intent> installables = (current != null) ? current.installables() : null; 47 List<Intent> installables = (current != null) ? current.installables() : null;
48 pending.setInstallables(intentManager.compileIntent(pending.intent(), installables)); 48 pending.setInstallables(intentManager.compileIntent(pending.intent(), installables));
49 - return Optional.of(new Installing(intentManager, pending, current)); 49 + return Optional.of(new Coordinating(intentManager, pending, current));
50 } catch (PathNotFoundException e) { 50 } catch (PathNotFoundException e) {
51 log.debug("Path not found for intent {}", pending.intent()); 51 log.debug("Path not found for intent {}", pending.intent());
52 // TODO: revisit to implement failure handling 52 // TODO: revisit to implement failure handling
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.net.intent.impl;
17 +
18 +import org.onosproject.net.flow.FlowRuleOperations;
19 +import org.onosproject.net.intent.IntentData;
20 +import org.slf4j.Logger;
21 +import org.slf4j.LoggerFactory;
22 +
23 +import java.util.Optional;
24 +
25 +import static com.google.common.base.Preconditions.checkNotNull;
26 +
27 +// TODO: better naming because install() method actually generate FlowRuleBatchOperations
28 +class Coordinating implements IntentUpdate {
29 +
30 + private static final Logger log = LoggerFactory.getLogger(Coordinating.class);
31 +
32 + private final IntentManager intentManager;
33 + private final IntentData pending;
34 + private final IntentData current;
35 +
36 + // TODO: define an interface and use it, instead of IntentManager
37 + Coordinating(IntentManager intentManager, IntentData pending, IntentData current) {
38 + this.intentManager = checkNotNull(intentManager);
39 + this.pending = checkNotNull(pending);
40 + this.current = current;
41 + }
42 +
43 + @Override
44 + public Optional<IntentUpdate> execute() {
45 + try {
46 + FlowRuleOperations flowRules = intentManager.coordinate(pending);
47 + return Optional.of(new Installing(intentManager, pending, flowRules));
48 + } catch (FlowRuleBatchOperationConversionException e) {
49 + log.warn("Unable to install intent {} due to:", pending.intent().id(), e.getCause());
50 + return Optional.of(new InstallingFailed(pending)); //FIXME
51 + }
52 + }
53 +}
...@@ -31,22 +31,19 @@ class Installing implements IntentUpdate { ...@@ -31,22 +31,19 @@ class Installing implements IntentUpdate {
31 31
32 private final IntentManager intentManager; 32 private final IntentManager intentManager;
33 private final IntentData pending; 33 private final IntentData pending;
34 - private final IntentData current; 34 + private final FlowRuleOperations flowRules;
35 35
36 // TODO: define an interface and use it, instead of IntentManager 36 // TODO: define an interface and use it, instead of IntentManager
37 - Installing(IntentManager intentManager, IntentData pending, IntentData current) { 37 + Installing(IntentManager intentManager, IntentData pending, FlowRuleOperations flowRules) {
38 this.intentManager = checkNotNull(intentManager); 38 this.intentManager = checkNotNull(intentManager);
39 this.pending = checkNotNull(pending); 39 this.pending = checkNotNull(pending);
40 - this.current = current; 40 + this.flowRules = flowRules;
41 } 41 }
42 42
43 @Override 43 @Override
44 public Optional<IntentUpdate> execute() { 44 public Optional<IntentUpdate> execute() {
45 try { 45 try {
46 - FlowRuleOperations flowRules = intentManager.coordinate(pending.installables()); 46 + intentManager.flowRuleService.apply(flowRules); // FIXME we need to provide a context
47 - // TODO: call FlowRuleService API to push FlowRules and track resources,
48 - // which the submitted intent will use.
49 - intentManager.flowRuleService.apply(flowRules);
50 return Optional.of(new Installed(pending)); 47 return Optional.of(new Installed(pending));
51 } catch (FlowRuleBatchOperationConversionException e) { 48 } catch (FlowRuleBatchOperationConversionException e) {
52 log.warn("Unable to install intent {} due to:", pending.intent().id(), e.getCause()); 49 log.warn("Unable to install intent {} due to:", pending.intent().id(), e.getCause());
......
...@@ -28,8 +28,13 @@ import org.onosproject.core.CoreService; ...@@ -28,8 +28,13 @@ import org.onosproject.core.CoreService;
28 import org.onosproject.core.IdGenerator; 28 import org.onosproject.core.IdGenerator;
29 import org.onosproject.event.AbstractListenerRegistry; 29 import org.onosproject.event.AbstractListenerRegistry;
30 import org.onosproject.event.EventDeliveryService; 30 import org.onosproject.event.EventDeliveryService;
31 +import org.onosproject.net.flow.FlowRule;
32 +import org.onosproject.net.flow.FlowRuleBatchEntry;
31 import org.onosproject.net.flow.FlowRuleBatchOperation; 33 import org.onosproject.net.flow.FlowRuleBatchOperation;
34 +import org.onosproject.net.flow.FlowRuleEvent;
35 +import org.onosproject.net.flow.FlowRuleListener;
32 import org.onosproject.net.flow.FlowRuleOperations; 36 import org.onosproject.net.flow.FlowRuleOperations;
37 +import org.onosproject.net.flow.FlowRuleOperationsContext;
33 import org.onosproject.net.flow.FlowRuleService; 38 import org.onosproject.net.flow.FlowRuleService;
34 import org.onosproject.net.intent.Intent; 39 import org.onosproject.net.intent.Intent;
35 import org.onosproject.net.intent.IntentBatchDelegate; 40 import org.onosproject.net.intent.IntentBatchDelegate;
...@@ -50,6 +55,7 @@ import org.slf4j.Logger; ...@@ -50,6 +55,7 @@ import org.slf4j.Logger;
50 import java.util.ArrayList; 55 import java.util.ArrayList;
51 import java.util.Collection; 56 import java.util.Collection;
52 import java.util.EnumSet; 57 import java.util.EnumSet;
58 +import java.util.Iterator;
53 import java.util.List; 59 import java.util.List;
54 import java.util.Map; 60 import java.util.Map;
55 import java.util.Optional; 61 import java.util.Optional;
...@@ -281,19 +287,74 @@ public class IntentManager ...@@ -281,19 +287,74 @@ public class IntentManager
281 287
282 //TODO javadoc 288 //TODO javadoc
283 //FIXME 289 //FIXME
284 - FlowRuleOperations coordinate(List<Intent> installables) { 290 + FlowRuleOperations coordinate(IntentData pending) {
285 - //List<FlowRuleBatchOperation> batches = new ArrayList<>(installables.size()); 291 + List<Intent> installables = pending.installables();
292 + List<List<FlowRuleBatchOperation>> plans = new ArrayList<>(installables.size());
286 for (Intent installable : installables) { 293 for (Intent installable : installables) {
287 try { 294 try {
288 registerSubclassInstallerIfNeeded(installable); 295 registerSubclassInstallerIfNeeded(installable);
289 //FIXME need to migrate installers to FlowRuleOperations 296 //FIXME need to migrate installers to FlowRuleOperations
290 // FIXME need to aggregate the FlowRuleOperations across installables 297 // FIXME need to aggregate the FlowRuleOperations across installables
291 - getInstaller(installable).install2(installable).build(null/*FIXME*/); 298 + plans.add(getInstaller(installable).install(installable));
292 } catch (Exception e) { // TODO this should be IntentException 299 } catch (Exception e) { // TODO this should be IntentException
293 throw new FlowRuleBatchOperationConversionException(null/*FIXME*/, e); 300 throw new FlowRuleBatchOperationConversionException(null/*FIXME*/, e);
294 } 301 }
295 } 302 }
296 - return null; 303 +
304 + return merge(plans).build(new FlowRuleOperationsContext() { // FIXME move this out
305 + @Override
306 + public void onSuccess(FlowRuleOperations ops) {
307 + log.info("Completed installing: {}", pending.key());
308 + pending.setState(INSTALLED);
309 + store.write(pending);
310 + }
311 +
312 + @Override
313 + public void onError(FlowRuleOperations ops) {
314 + //FIXME store.write(pending.setState(BROKEN));
315 + }
316 + });
317 + }
318 +
319 + // FIXME... needs tests... or maybe it's just perfect
320 + private FlowRuleOperations.Builder merge(List<List<FlowRuleBatchOperation>> plans) {
321 + FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
322 + // Build a batch one stage at a time
323 + for (int stageNumber = 0;; stageNumber++) {
324 + // Get the sub-stage from each plan (List<FlowRuleBatchOperation>)
325 + for (Iterator<List<FlowRuleBatchOperation>> itr = plans.iterator(); itr.hasNext();) {
326 + List<FlowRuleBatchOperation> plan = itr.next();
327 + if (plan.size() <= stageNumber) {
328 + // we have consumed all stages from this plan, so remove it
329 + itr.remove();
330 + continue;
331 + }
332 + // write operations from this sub-stage into the builder
333 + FlowRuleBatchOperation stage = plan.get(stageNumber);
334 + for (FlowRuleBatchEntry entry : stage.getOperations()) {
335 + FlowRule rule = entry.target();
336 + switch (entry.operator()) {
337 + case ADD:
338 + builder.add(rule);
339 + break;
340 + case REMOVE:
341 + builder.remove(rule);
342 + break;
343 + case MODIFY:
344 + builder.modify(rule);
345 + break;
346 + default:
347 + break;
348 + }
349 + }
350 + }
351 + // we are done with the stage, start the next one...
352 + if (plans.isEmpty()) {
353 + break; // we don't need to start a new stage, we are done.
354 + }
355 + builder.newStage();
356 + }
357 + return builder;
297 } 358 }
298 359
299 /** 360 /**
...@@ -311,7 +372,7 @@ public class IntentManager ...@@ -311,7 +372,7 @@ public class IntentManager
311 installable.resources()); 372 installable.resources());
312 try { 373 try {
313 // FIXME need to aggregate the FlowRuleOperations across installables 374 // FIXME need to aggregate the FlowRuleOperations across installables
314 - getInstaller(installable).uninstall2(installable).build(null/*FIXME*/); 375 + getInstaller(installable).uninstall(installable); //.build(null/*FIXME*/);
315 } catch (IntentException e) { 376 } catch (IntentException e) {
316 log.warn("Unable to uninstall intent {} due to:", intent.id(), e); 377 log.warn("Unable to uninstall intent {} due to:", intent.id(), e);
317 // TODO: this should never happen. but what if it does? 378 // TODO: this should never happen. but what if it does?
......
...@@ -25,6 +25,8 @@ import org.onosproject.net.intent.BatchWrite.Operation; ...@@ -25,6 +25,8 @@ import org.onosproject.net.intent.BatchWrite.Operation;
25 import org.onosproject.net.intent.Intent; 25 import org.onosproject.net.intent.Intent;
26 import org.onosproject.net.intent.IntentData; 26 import org.onosproject.net.intent.IntentData;
27 import org.onosproject.net.intent.IntentEvent; 27 import org.onosproject.net.intent.IntentEvent;
28 +import org.onosproject.net.intent.IntentId;
29 +import org.onosproject.net.intent.IntentState;
28 import org.onosproject.net.intent.IntentStore; 30 import org.onosproject.net.intent.IntentStore;
29 import org.onosproject.net.intent.IntentStoreDelegate; 31 import org.onosproject.net.intent.IntentStoreDelegate;
30 import org.onosproject.net.intent.Key; 32 import org.onosproject.net.intent.Key;
...@@ -33,6 +35,7 @@ import org.slf4j.Logger; ...@@ -33,6 +35,7 @@ import org.slf4j.Logger;
33 35
34 import java.util.List; 36 import java.util.List;
35 import java.util.Map; 37 import java.util.Map;
38 +import java.util.Objects;
36 import java.util.stream.Collectors; 39 import java.util.stream.Collectors;
37 40
38 import static com.google.common.base.Preconditions.checkNotNull; 41 import static com.google.common.base.Preconditions.checkNotNull;
...@@ -73,6 +76,36 @@ public class SimpleIntentStore ...@@ -73,6 +76,36 @@ public class SimpleIntentStore
73 } 76 }
74 77
75 @Override 78 @Override
79 + public Intent getIntent(IntentId intentId) {
80 + for (IntentData data : current.values()) {
81 + if (Objects.equals(data.intent().id(), intentId)) {
82 + return data.intent();
83 + }
84 + }
85 + return null;
86 + }
87 +
88 + @Override
89 + public IntentState getIntentState(IntentId intentId) {
90 + for (IntentData data : current.values()) {
91 + if (Objects.equals(data.intent().id(), intentId)) {
92 + return data.state();
93 + }
94 + }
95 + return null;
96 + }
97 +
98 + @Override
99 + public List<Intent> getInstallableIntents(IntentId intentId) {
100 + for (IntentData data : current.values()) {
101 + if (Objects.equals(data.intent().id(), intentId)) {
102 + return data.installables();
103 + }
104 + }
105 + return null;
106 + }
107 +
108 + @Override
76 public IntentData getIntentData(Key key) { 109 public IntentData getIntentData(Key key) {
77 return current.get(key); 110 return current.get(key);
78 } 111 }
...@@ -164,6 +197,12 @@ public class SimpleIntentStore ...@@ -164,6 +197,12 @@ public class SimpleIntentStore
164 } 197 }
165 } 198 }
166 199
200 + @Override
201 + public Intent getIntent(Key key) {
202 + IntentData data = current.get(key);
203 + return (data != null) ? data.intent() : null;
204 + }
205 +
167 206
168 @Override 207 @Override
169 public void addPending(IntentData data) { 208 public void addPending(IntentData data) {
......