Intent F/W improvements
- aggregate installables into FlowRuleOperations - added some impl. to SimpleIntentStore - created Coordinating State Change-Id: I5b26ec1fdb7aaff9d5da4f21b2d5a249568ac5ac
Showing
6 changed files
with
164 additions
and
90 deletions
... | @@ -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) { | ... | ... |
-
Please register or login to post a comment