Refactored intermediate IntentUpdate classes
Change-Id: I3d4a435ef4aa97559d5407d49f45519098c3f193
Showing
12 changed files
with
415 additions
and
426 deletions
... | @@ -15,7 +15,10 @@ | ... | @@ -15,7 +15,10 @@ |
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; | ||
18 | import org.onosproject.net.flow.FlowRuleBatchOperation; | 20 | import org.onosproject.net.flow.FlowRuleBatchOperation; |
21 | +import org.onosproject.net.flow.FlowRuleOperations; | ||
19 | 22 | ||
20 | import java.util.List; | 23 | import java.util.List; |
21 | 24 | ||
... | @@ -30,7 +33,32 @@ public interface IntentInstaller<T extends Intent> { | ... | @@ -30,7 +33,32 @@ public interface IntentInstaller<T extends Intent> { |
30 | * @return flow rule operations to complete install | 33 | * @return flow rule operations to complete install |
31 | * @throws IntentException if issues are encountered while installing the intent | 34 | * @throws IntentException if issues are encountered while installing the intent |
32 | */ | 35 | */ |
36 | + @Deprecated | ||
33 | List<FlowRuleBatchOperation> install(T intent); | 37 | 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 | + } | ||
34 | 62 | ||
35 | /** | 63 | /** |
36 | * Uninstalls the specified intent from the environment. | 64 | * Uninstalls the specified intent from the environment. |
... | @@ -39,7 +67,32 @@ public interface IntentInstaller<T extends Intent> { | ... | @@ -39,7 +67,32 @@ public interface IntentInstaller<T extends Intent> { |
39 | * @return flow rule operations to complete uninstall | 67 | * @return flow rule operations to complete uninstall |
40 | * @throws IntentException if issues are encountered while uninstalling the intent | 68 | * @throws IntentException if issues are encountered while uninstalling the intent |
41 | */ | 69 | */ |
70 | + @Deprecated | ||
42 | List<FlowRuleBatchOperation> uninstall(T intent); | 71 | 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 | + } | ||
43 | 96 | ||
44 | /** | 97 | /** |
45 | * Replaces the specified intent with a new one in the environment. | 98 | * Replaces the specified intent with a new one in the environment. |
... | @@ -49,6 +102,31 @@ public interface IntentInstaller<T extends Intent> { | ... | @@ -49,6 +102,31 @@ public interface IntentInstaller<T extends Intent> { |
49 | * @return flow rule operations to complete the replace | 102 | * @return flow rule operations to complete the replace |
50 | * @throws IntentException if issues are encountered while uninstalling the intent | 103 | * @throws IntentException if issues are encountered while uninstalling the intent |
51 | */ | 104 | */ |
105 | + @Deprecated | ||
52 | List<FlowRuleBatchOperation> replace(T oldIntent, T newIntent); | 106 | 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 | + } | ||
53 | 131 | ||
54 | } | 132 | } | ... | ... |
... | @@ -16,10 +16,12 @@ | ... | @@ -16,10 +16,12 @@ |
16 | package org.onosproject.net.intent.impl; | 16 | package org.onosproject.net.intent.impl; |
17 | 17 | ||
18 | import org.onosproject.net.intent.Intent; | 18 | import org.onosproject.net.intent.Intent; |
19 | +import org.onosproject.net.intent.IntentData; | ||
19 | import org.onosproject.net.intent.IntentException; | 20 | import org.onosproject.net.intent.IntentException; |
20 | import org.slf4j.Logger; | 21 | import org.slf4j.Logger; |
21 | import org.slf4j.LoggerFactory; | 22 | import org.slf4j.LoggerFactory; |
22 | 23 | ||
24 | +import java.util.List; | ||
23 | import java.util.Optional; | 25 | import java.util.Optional; |
24 | 26 | ||
25 | import static com.google.common.base.Preconditions.checkNotNull; | 27 | import static com.google.common.base.Preconditions.checkNotNull; |
... | @@ -30,25 +32,29 @@ class Compiling implements IntentUpdate { | ... | @@ -30,25 +32,29 @@ class Compiling implements IntentUpdate { |
30 | 32 | ||
31 | // TODO: define an interface and use it, instead of IntentManager | 33 | // TODO: define an interface and use it, instead of IntentManager |
32 | private final IntentManager intentManager; | 34 | private final IntentManager intentManager; |
33 | - private final Intent intent; | 35 | + private final IntentData pending; |
36 | + private final IntentData current; | ||
34 | 37 | ||
35 | - Compiling(IntentManager intentManager, Intent intent) { | 38 | + Compiling(IntentManager intentManager, IntentData pending, IntentData current) { |
36 | this.intentManager = checkNotNull(intentManager); | 39 | this.intentManager = checkNotNull(intentManager); |
37 | - this.intent = checkNotNull(intent); | 40 | + this.pending = checkNotNull(pending); |
41 | + this.current = current; | ||
38 | } | 42 | } |
39 | 43 | ||
40 | @Override | 44 | @Override |
41 | public Optional<IntentUpdate> execute() { | 45 | public Optional<IntentUpdate> execute() { |
42 | try { | 46 | try { |
43 | - return Optional.of(new Installing(intentManager, intent, intentManager.compileIntent(intent, null))); | 47 | + List<Intent> installables = (current != null) ? current.installables() : null; |
48 | + pending.setInstallables(intentManager.compileIntent(pending.intent(), installables)); | ||
49 | + return Optional.of(new Installing(intentManager, pending, current)); | ||
44 | } catch (PathNotFoundException e) { | 50 | } catch (PathNotFoundException e) { |
45 | - log.debug("Path not found for intent {}", intent); | 51 | + log.debug("Path not found for intent {}", pending.intent()); |
46 | // TODO: revisit to implement failure handling | 52 | // TODO: revisit to implement failure handling |
47 | - return Optional.of(new DoNothing()); | 53 | + return Optional.of(new CompilingFailed(pending)); //FIXME failed state transition |
48 | } catch (IntentException e) { | 54 | } catch (IntentException e) { |
49 | - log.warn("Unable to compile intent {} due to:", intent.id(), e); | 55 | + log.warn("Unable to compile intent {} due to:", pending.intent().id(), e); |
50 | // TODO: revisit to implement failure handling | 56 | // TODO: revisit to implement failure handling |
51 | - return Optional.of(new DoNothing()); | 57 | + return Optional.of(new CompilingFailed(pending)); //FIXME failed state transition |
52 | } | 58 | } |
53 | } | 59 | } |
54 | } | 60 | } | ... | ... |
... | @@ -15,8 +15,26 @@ | ... | @@ -15,8 +15,26 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.intent.impl; | 16 | package org.onosproject.net.intent.impl; |
17 | 17 | ||
18 | +import org.onosproject.net.intent.IntentData; | ||
19 | + | ||
20 | +import static org.onosproject.net.intent.IntentState.FAILED; | ||
21 | + | ||
18 | /** | 22 | /** |
19 | - * Represents a phase doing nothing. | 23 | + * Represents a phase where the compile has failed. |
20 | */ | 24 | */ |
21 | -class DoNothing implements CompletedIntentUpdate { | 25 | +class CompilingFailed implements CompletedIntentUpdate { |
26 | + | ||
27 | + private final IntentData intentData; | ||
28 | + | ||
29 | + CompilingFailed(IntentData intentData) { | ||
30 | + this.intentData = intentData; | ||
31 | + this.intentData.setState(FAILED); | ||
32 | + } | ||
33 | + | ||
34 | + @Override | ||
35 | + public IntentData data() { | ||
36 | + return intentData; | ||
37 | + } | ||
38 | + | ||
39 | + //FIXME we also need to decide what to do with the current intent's resources i.e. cleanup or revert | ||
22 | } | 40 | } | ... | ... |
... | @@ -15,11 +15,8 @@ | ... | @@ -15,11 +15,8 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.intent.impl; | 16 | package org.onosproject.net.intent.impl; |
17 | 17 | ||
18 | -import org.onosproject.net.flow.FlowRuleBatchOperation; | 18 | +import org.onosproject.net.intent.IntentData; |
19 | -import org.onosproject.net.intent.Intent; | ||
20 | 19 | ||
21 | -import java.util.Collections; | ||
22 | -import java.util.List; | ||
23 | import java.util.Optional; | 20 | import java.util.Optional; |
24 | 21 | ||
25 | /** | 22 | /** |
... | @@ -27,38 +24,10 @@ import java.util.Optional; | ... | @@ -27,38 +24,10 @@ import java.util.Optional; |
27 | */ | 24 | */ |
28 | interface CompletedIntentUpdate extends IntentUpdate { | 25 | interface CompletedIntentUpdate extends IntentUpdate { |
29 | 26 | ||
30 | - /** | ||
31 | - * Moves forward with the contained current batch. | ||
32 | - * This method is invoked when the batch is successfully completed. | ||
33 | - */ | ||
34 | - default void batchSuccess() {} | ||
35 | - | ||
36 | - /** | ||
37 | - * Reverts the contained batches. | ||
38 | - * This method is invoked when the batch results in failure. | ||
39 | - */ | ||
40 | - default void batchFailed() {} | ||
41 | - | ||
42 | - /** | ||
43 | - * Returns the current FlowRuleBatchOperation. | ||
44 | - * | ||
45 | - * @return current FlowRuleBatchOperation | ||
46 | - */ | ||
47 | - default FlowRuleBatchOperation currentBatch() { | ||
48 | - return null; | ||
49 | - } | ||
50 | - | ||
51 | - /** | ||
52 | - * Returns all of installable intents this instance holds. | ||
53 | - * | ||
54 | - * @return all of installable intents | ||
55 | - */ | ||
56 | - default List<Intent> allInstallables() { | ||
57 | - return Collections.emptyList(); | ||
58 | - } | ||
59 | - | ||
60 | @Override | 27 | @Override |
61 | default Optional<IntentUpdate> execute() { | 28 | default Optional<IntentUpdate> execute() { |
62 | return Optional.empty(); | 29 | return Optional.empty(); |
63 | } | 30 | } |
31 | + | ||
32 | + IntentData data(); | ||
64 | } | 33 | } | ... | ... |
... | @@ -15,7 +15,6 @@ | ... | @@ -15,7 +15,6 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.intent.impl; | 16 | package org.onosproject.net.intent.impl; |
17 | 17 | ||
18 | -import org.onosproject.net.intent.Intent; | ||
19 | import org.onosproject.net.intent.IntentData; | 18 | import org.onosproject.net.intent.IntentData; |
20 | 19 | ||
21 | import java.util.Optional; | 20 | import java.util.Optional; |
... | @@ -27,17 +26,17 @@ class InstallRequest implements IntentUpdate { | ... | @@ -27,17 +26,17 @@ class InstallRequest implements IntentUpdate { |
27 | 26 | ||
28 | // TODO: define an interface and use it, instead of IntentManager | 27 | // TODO: define an interface and use it, instead of IntentManager |
29 | private final IntentManager intentManager; | 28 | private final IntentManager intentManager; |
30 | - private final Intent intent; | 29 | + private final IntentData pending; |
31 | - private final IntentData currentState; | ||
32 | 30 | ||
33 | - InstallRequest(IntentManager intentManager, Intent intent, IntentData currentState) { | 31 | + InstallRequest(IntentManager intentManager, IntentData intentData) { |
34 | this.intentManager = checkNotNull(intentManager); | 32 | this.intentManager = checkNotNull(intentManager); |
35 | - this.intent = checkNotNull(intent); | 33 | + this.pending = checkNotNull(intentData); |
36 | - this.currentState = currentState; | ||
37 | } | 34 | } |
38 | 35 | ||
39 | @Override | 36 | @Override |
40 | public Optional<IntentUpdate> execute() { | 37 | public Optional<IntentUpdate> execute() { |
41 | - return Optional.of(new Compiling(intentManager, intent)); //FIXME | 38 | + //FIXME... store hack |
39 | + IntentData current = intentManager.store.getIntentData(pending.key()); | ||
40 | + return Optional.of(new Compiling(intentManager, pending, current)); | ||
42 | } | 41 | } |
43 | } | 42 | } | ... | ... |
... | @@ -15,60 +15,21 @@ | ... | @@ -15,60 +15,21 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.intent.impl; | 16 | package org.onosproject.net.intent.impl; |
17 | 17 | ||
18 | -import com.google.common.collect.ImmutableList; | 18 | +import org.onosproject.net.intent.IntentData; |
19 | -import org.onosproject.net.flow.FlowRuleBatchOperation; | ||
20 | -import org.onosproject.net.intent.Intent; | ||
21 | -import org.onosproject.net.intent.IntentState; | ||
22 | - | ||
23 | -import java.util.LinkedList; | ||
24 | -import java.util.List; | ||
25 | 19 | ||
26 | import static com.google.common.base.Preconditions.checkNotNull; | 20 | import static com.google.common.base.Preconditions.checkNotNull; |
27 | -import static org.onosproject.net.intent.IntentState.FAILED; | ||
28 | import static org.onosproject.net.intent.IntentState.INSTALLING; | 21 | import static org.onosproject.net.intent.IntentState.INSTALLING; |
29 | 22 | ||
30 | class Installed implements CompletedIntentUpdate { | 23 | class Installed implements CompletedIntentUpdate { |
31 | 24 | ||
32 | - // TODO: define an interface and use it, instead of IntentManager | 25 | + private final IntentData intentData; |
33 | - private final IntentManager intentManager; | ||
34 | - private final Intent intent; | ||
35 | - private final List<Intent> installables; | ||
36 | - private IntentState intentState; | ||
37 | - private final List<FlowRuleBatchOperation> batches; | ||
38 | - private int currentBatch = 0; | ||
39 | - | ||
40 | - Installed(IntentManager intentManager, | ||
41 | - Intent intent, List<Intent> installables, List<FlowRuleBatchOperation> batches) { | ||
42 | - this.intentManager = checkNotNull(intentManager); | ||
43 | - this.intent = checkNotNull(intent); | ||
44 | - this.installables = ImmutableList.copyOf(checkNotNull(installables)); | ||
45 | - this.batches = new LinkedList<>(checkNotNull(batches)); | ||
46 | - this.intentState = INSTALLING; | ||
47 | - } | ||
48 | - | ||
49 | - @Override | ||
50 | - public void batchSuccess() { | ||
51 | - currentBatch++; | ||
52 | - } | ||
53 | - | ||
54 | - @Override | ||
55 | - public List<Intent> allInstallables() { | ||
56 | - return installables; | ||
57 | - } | ||
58 | 26 | ||
59 | - @Override | 27 | + Installed(IntentData intentData) { |
60 | - public FlowRuleBatchOperation currentBatch() { | 28 | + this.intentData = checkNotNull(intentData); |
61 | - return currentBatch < batches.size() ? batches.get(currentBatch) : null; | 29 | + this.intentData.setState(INSTALLING); |
62 | } | 30 | } |
63 | 31 | ||
64 | - @Override | 32 | + public IntentData data() { |
65 | - public void batchFailed() { | 33 | + return intentData; |
66 | - for (int i = batches.size() - 1; i >= currentBatch; i--) { | ||
67 | - batches.remove(i); | ||
68 | - } | ||
69 | - intentState = FAILED; | ||
70 | - batches.addAll(intentManager.uninstallIntent(intent, installables)); | ||
71 | - | ||
72 | - // TODO we might want to try to recompile the new intent | ||
73 | } | 34 | } |
74 | } | 35 | } | ... | ... |
... | @@ -15,13 +15,11 @@ | ... | @@ -15,13 +15,11 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.intent.impl; | 16 | package org.onosproject.net.intent.impl; |
17 | 17 | ||
18 | -import com.google.common.collect.ImmutableList; | 18 | +import org.onosproject.net.flow.FlowRuleOperations; |
19 | -import org.onosproject.net.flow.FlowRuleBatchOperation; | 19 | +import org.onosproject.net.intent.IntentData; |
20 | -import org.onosproject.net.intent.Intent; | ||
21 | import org.slf4j.Logger; | 20 | import org.slf4j.Logger; |
22 | import org.slf4j.LoggerFactory; | 21 | import org.slf4j.LoggerFactory; |
23 | 22 | ||
24 | -import java.util.List; | ||
25 | import java.util.Optional; | 23 | import java.util.Optional; |
26 | 24 | ||
27 | import static com.google.common.base.Preconditions.checkNotNull; | 25 | import static com.google.common.base.Preconditions.checkNotNull; |
... | @@ -32,26 +30,27 @@ class Installing implements IntentUpdate { | ... | @@ -32,26 +30,27 @@ class Installing implements IntentUpdate { |
32 | private static final Logger log = LoggerFactory.getLogger(Installing.class); | 30 | private static final Logger log = LoggerFactory.getLogger(Installing.class); |
33 | 31 | ||
34 | private final IntentManager intentManager; | 32 | private final IntentManager intentManager; |
35 | - private final Intent intent; | 33 | + private final IntentData pending; |
36 | - private final List<Intent> installables; | 34 | + private final IntentData current; |
37 | 35 | ||
38 | // TODO: define an interface and use it, instead of IntentManager | 36 | // TODO: define an interface and use it, instead of IntentManager |
39 | - Installing(IntentManager intentManager, Intent intent, List<Intent> installables) { | 37 | + Installing(IntentManager intentManager, IntentData pending, IntentData current) { |
40 | this.intentManager = checkNotNull(intentManager); | 38 | this.intentManager = checkNotNull(intentManager); |
41 | - this.intent = checkNotNull(intent); | 39 | + this.pending = checkNotNull(pending); |
42 | - this.installables = ImmutableList.copyOf(checkNotNull(installables)); | 40 | + this.current = current; |
43 | } | 41 | } |
44 | 42 | ||
45 | @Override | 43 | @Override |
46 | public Optional<IntentUpdate> execute() { | 44 | public Optional<IntentUpdate> execute() { |
47 | try { | 45 | try { |
48 | - List<FlowRuleBatchOperation> converted = intentManager.convert(installables); | 46 | + FlowRuleOperations flowRules = intentManager.coordinate(pending.installables()); |
49 | // TODO: call FlowRuleService API to push FlowRules and track resources, | 47 | // TODO: call FlowRuleService API to push FlowRules and track resources, |
50 | // which the submitted intent will use. | 48 | // which the submitted intent will use. |
51 | - return Optional.of(new Installed(intentManager, intent, installables, converted)); | 49 | + intentManager.flowRuleService.apply(flowRules); |
50 | + return Optional.of(new Installed(pending)); | ||
52 | } catch (FlowRuleBatchOperationConversionException e) { | 51 | } catch (FlowRuleBatchOperationConversionException e) { |
53 | - log.warn("Unable to install intent {} due to:", intent.id(), e.getCause()); | 52 | + log.warn("Unable to install intent {} due to:", pending.intent().id(), e.getCause()); |
54 | - return Optional.of(new InstallingFailed(intentManager, intent, installables, e.converted())); | 53 | + return Optional.of(new InstallingFailed(pending)); |
55 | } | 54 | } |
56 | } | 55 | } |
57 | } | 56 | } | ... | ... |
... | @@ -15,53 +15,23 @@ | ... | @@ -15,53 +15,23 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.intent.impl; | 16 | package org.onosproject.net.intent.impl; |
17 | 17 | ||
18 | -import com.google.common.collect.ImmutableList; | 18 | +import org.onosproject.net.intent.IntentData; |
19 | -import org.onosproject.net.flow.FlowRuleBatchOperation; | ||
20 | -import org.onosproject.net.intent.Intent; | ||
21 | - | ||
22 | -import java.util.LinkedList; | ||
23 | -import java.util.List; | ||
24 | 19 | ||
25 | import static com.google.common.base.Preconditions.checkNotNull; | 20 | import static com.google.common.base.Preconditions.checkNotNull; |
21 | +import static org.onosproject.net.intent.IntentState.FAILED; | ||
26 | 22 | ||
27 | class InstallingFailed implements CompletedIntentUpdate { | 23 | class InstallingFailed implements CompletedIntentUpdate { |
28 | 24 | ||
29 | - private IntentManager intentManager; | 25 | + private final IntentData intentData; |
30 | - private final Intent intent; | ||
31 | - private final List<Intent> installables; | ||
32 | - private final List<FlowRuleBatchOperation> batches; | ||
33 | - private int currentBatch = 0; | ||
34 | - | ||
35 | - InstallingFailed(IntentManager intentManager, | ||
36 | - Intent intent, List<Intent> installables, List<FlowRuleBatchOperation> batches) { | ||
37 | - this.intentManager = intentManager; | ||
38 | - this.intent = checkNotNull(intent); | ||
39 | - this.installables = ImmutableList.copyOf(checkNotNull(installables)); | ||
40 | - this.batches = new LinkedList<>(checkNotNull(batches)); | ||
41 | - } | ||
42 | 26 | ||
43 | - @Override | 27 | + InstallingFailed(IntentData intentData) { |
44 | - public List<Intent> allInstallables() { | 28 | + this.intentData = checkNotNull(intentData); |
45 | - return installables; | 29 | + this.intentData.setState(FAILED); //FIXME maybe should be "BROKEN" |
30 | + //TODO consider adding the flow rule operations here | ||
46 | } | 31 | } |
47 | 32 | ||
48 | @Override | 33 | @Override |
49 | - public void batchSuccess() { | 34 | + public IntentData data() { |
50 | - currentBatch++; | 35 | + return intentData; |
51 | - } | ||
52 | - | ||
53 | - @Override | ||
54 | - public FlowRuleBatchOperation currentBatch() { | ||
55 | - return currentBatch < batches.size() ? batches.get(currentBatch) : null; | ||
56 | - } | ||
57 | - | ||
58 | - @Override | ||
59 | - public void batchFailed() { | ||
60 | - for (int i = batches.size() - 1; i >= currentBatch; i--) { | ||
61 | - batches.remove(i); | ||
62 | - } | ||
63 | - batches.addAll(intentManager.uninstallIntent(intent, installables)); | ||
64 | - | ||
65 | - // TODO we might want to try to recompile the new intent | ||
66 | } | 36 | } |
67 | } | 37 | } | ... | ... |
... | @@ -15,23 +15,9 @@ | ... | @@ -15,23 +15,9 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.intent.impl; | 16 | package org.onosproject.net.intent.impl; |
17 | 17 | ||
18 | -import java.util.ArrayList; | 18 | +import com.google.common.collect.ImmutableList; |
19 | -import java.util.Collection; | 19 | +import com.google.common.collect.ImmutableMap; |
20 | -import java.util.Collections; | 20 | +import com.google.common.collect.Lists; |
21 | -import java.util.EnumSet; | ||
22 | -import java.util.List; | ||
23 | -import java.util.Map; | ||
24 | -import java.util.Optional; | ||
25 | -import java.util.concurrent.Callable; | ||
26 | -import java.util.concurrent.ConcurrentHashMap; | ||
27 | -import java.util.concurrent.ConcurrentMap; | ||
28 | -import java.util.concurrent.ExecutionException; | ||
29 | -import java.util.concurrent.ExecutorService; | ||
30 | -import java.util.concurrent.Future; | ||
31 | -import java.util.concurrent.TimeUnit; | ||
32 | -import java.util.concurrent.TimeoutException; | ||
33 | -import java.util.stream.Collectors; | ||
34 | - | ||
35 | import org.apache.felix.scr.annotations.Activate; | 21 | import org.apache.felix.scr.annotations.Activate; |
36 | import org.apache.felix.scr.annotations.Component; | 22 | import org.apache.felix.scr.annotations.Component; |
37 | import org.apache.felix.scr.annotations.Deactivate; | 23 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -42,8 +28,8 @@ import org.onosproject.core.CoreService; | ... | @@ -42,8 +28,8 @@ import org.onosproject.core.CoreService; |
42 | import org.onosproject.core.IdGenerator; | 28 | import org.onosproject.core.IdGenerator; |
43 | import org.onosproject.event.AbstractListenerRegistry; | 29 | import org.onosproject.event.AbstractListenerRegistry; |
44 | import org.onosproject.event.EventDeliveryService; | 30 | import org.onosproject.event.EventDeliveryService; |
45 | -import org.onosproject.net.flow.CompletedBatchOperation; | ||
46 | import org.onosproject.net.flow.FlowRuleBatchOperation; | 31 | import org.onosproject.net.flow.FlowRuleBatchOperation; |
32 | +import org.onosproject.net.flow.FlowRuleOperations; | ||
47 | import org.onosproject.net.flow.FlowRuleService; | 33 | import org.onosproject.net.flow.FlowRuleService; |
48 | import org.onosproject.net.intent.Intent; | 34 | import org.onosproject.net.intent.Intent; |
49 | import org.onosproject.net.intent.IntentBatchDelegate; | 35 | import org.onosproject.net.intent.IntentBatchDelegate; |
... | @@ -61,17 +47,25 @@ import org.onosproject.net.intent.IntentStore; | ... | @@ -61,17 +47,25 @@ import org.onosproject.net.intent.IntentStore; |
61 | import org.onosproject.net.intent.IntentStoreDelegate; | 47 | import org.onosproject.net.intent.IntentStoreDelegate; |
62 | import org.slf4j.Logger; | 48 | import org.slf4j.Logger; |
63 | 49 | ||
64 | -import com.google.common.collect.ImmutableList; | 50 | +import java.util.ArrayList; |
65 | -import com.google.common.collect.ImmutableMap; | 51 | +import java.util.Collection; |
66 | -import com.google.common.collect.Lists; | 52 | +import java.util.EnumSet; |
53 | +import java.util.List; | ||
54 | +import java.util.Map; | ||
55 | +import java.util.Optional; | ||
56 | +import java.util.concurrent.Callable; | ||
57 | +import java.util.concurrent.ConcurrentHashMap; | ||
58 | +import java.util.concurrent.ConcurrentMap; | ||
59 | +import java.util.concurrent.ExecutionException; | ||
60 | +import java.util.concurrent.ExecutorService; | ||
61 | +import java.util.concurrent.Future; | ||
62 | +import java.util.stream.Collectors; | ||
67 | 63 | ||
68 | import static com.google.common.base.Preconditions.checkNotNull; | 64 | import static com.google.common.base.Preconditions.checkNotNull; |
69 | import static java.util.concurrent.Executors.newFixedThreadPool; | 65 | import static java.util.concurrent.Executors.newFixedThreadPool; |
70 | import static java.util.concurrent.Executors.newSingleThreadExecutor; | 66 | import static java.util.concurrent.Executors.newSingleThreadExecutor; |
71 | import static org.onlab.util.Tools.namedThreads; | 67 | import static org.onlab.util.Tools.namedThreads; |
72 | -import static org.onosproject.net.intent.IntentState.FAILED; | 68 | +import static org.onosproject.net.intent.IntentState.*; |
73 | -import static org.onosproject.net.intent.IntentState.INSTALL_REQ; | ||
74 | -import static org.onosproject.net.intent.IntentState.WITHDRAW_REQ; | ||
75 | import static org.slf4j.LoggerFactory.getLogger; | 69 | import static org.slf4j.LoggerFactory.getLogger; |
76 | 70 | ||
77 | /** | 71 | /** |
... | @@ -285,6 +279,23 @@ public class IntentManager | ... | @@ -285,6 +279,23 @@ public class IntentManager |
285 | return installable; | 279 | return installable; |
286 | } | 280 | } |
287 | 281 | ||
282 | + //TODO javadoc | ||
283 | + //FIXME | ||
284 | + FlowRuleOperations coordinate(List<Intent> installables) { | ||
285 | + //List<FlowRuleBatchOperation> batches = new ArrayList<>(installables.size()); | ||
286 | + for (Intent installable : installables) { | ||
287 | + try { | ||
288 | + registerSubclassInstallerIfNeeded(installable); | ||
289 | + //FIXME need to migrate installers to FlowRuleOperations | ||
290 | + // FIXME need to aggregate the FlowRuleOperations across installables | ||
291 | + getInstaller(installable).install2(installable).build(null/*FIXME*/); | ||
292 | + } catch (Exception e) { // TODO this should be IntentException | ||
293 | + throw new FlowRuleBatchOperationConversionException(null/*FIXME*/, e); | ||
294 | + } | ||
295 | + } | ||
296 | + return null; | ||
297 | + } | ||
298 | + | ||
288 | /** | 299 | /** |
289 | * Uninstalls all installable intents associated with the given intent. | 300 | * Uninstalls all installable intents associated with the given intent. |
290 | * | 301 | * |
... | @@ -292,19 +303,21 @@ public class IntentManager | ... | @@ -292,19 +303,21 @@ public class IntentManager |
292 | * @param installables installable intents | 303 | * @param installables installable intents |
293 | * @return list of batches to uninstall intent | 304 | * @return list of batches to uninstall intent |
294 | */ | 305 | */ |
295 | - List<FlowRuleBatchOperation> uninstallIntent(Intent intent, List<Intent> installables) { | 306 | + //FIXME |
307 | + FlowRuleOperations uninstallIntent(Intent intent, List<Intent> installables) { | ||
296 | List<FlowRuleBatchOperation> batches = Lists.newArrayList(); | 308 | List<FlowRuleBatchOperation> batches = Lists.newArrayList(); |
297 | for (Intent installable : installables) { | 309 | for (Intent installable : installables) { |
298 | trackerService.removeTrackedResources(intent.id(), | 310 | trackerService.removeTrackedResources(intent.id(), |
299 | installable.resources()); | 311 | installable.resources()); |
300 | try { | 312 | try { |
301 | - batches.addAll(getInstaller(installable).uninstall(installable)); | 313 | + // FIXME need to aggregate the FlowRuleOperations across installables |
314 | + getInstaller(installable).uninstall2(installable).build(null/*FIXME*/); | ||
302 | } catch (IntentException e) { | 315 | } catch (IntentException e) { |
303 | log.warn("Unable to uninstall intent {} due to:", intent.id(), e); | 316 | log.warn("Unable to uninstall intent {} due to:", intent.id(), e); |
304 | // TODO: this should never happen. but what if it does? | 317 | // TODO: this should never happen. but what if it does? |
305 | } | 318 | } |
306 | } | 319 | } |
307 | - return batches; | 320 | + return null; //FIXME |
308 | } | 321 | } |
309 | 322 | ||
310 | /** | 323 | /** |
... | @@ -414,12 +427,11 @@ public class IntentManager | ... | @@ -414,12 +427,11 @@ public class IntentManager |
414 | 427 | ||
415 | // TODO: simplify the branching statements | 428 | // TODO: simplify the branching statements |
416 | private IntentUpdate createIntentUpdate(IntentData intentData) { | 429 | private IntentUpdate createIntentUpdate(IntentData intentData) { |
417 | - IntentData currentState = store.getIntentData(intentData.key()); | ||
418 | switch (intentData.state()) { | 430 | switch (intentData.state()) { |
419 | case INSTALL_REQ: | 431 | case INSTALL_REQ: |
420 | - return new InstallRequest(this, intentData.intent(), currentState); | 432 | + return new InstallRequest(this, intentData); |
421 | case WITHDRAW_REQ: | 433 | case WITHDRAW_REQ: |
422 | - return new WithdrawRequest(this, intentData.intent(), currentState); | 434 | + return new WithdrawRequest(this, intentData); |
423 | // fallthrough | 435 | // fallthrough |
424 | case COMPILING: | 436 | case COMPILING: |
425 | case INSTALLING: | 437 | case INSTALLING: |
... | @@ -430,21 +442,12 @@ public class IntentManager | ... | @@ -430,21 +442,12 @@ public class IntentManager |
430 | case FAILED: | 442 | case FAILED: |
431 | default: | 443 | default: |
432 | // illegal state | 444 | // illegal state |
433 | - return new DoNothing(); | 445 | + return new CompilingFailed(intentData); |
434 | } | 446 | } |
435 | } | 447 | } |
436 | 448 | ||
437 | - List<FlowRuleBatchOperation> convert(List<Intent> installables) { | 449 | + private Future<CompletedIntentUpdate> submitIntentData(IntentData data) { |
438 | - List<FlowRuleBatchOperation> batches = new ArrayList<>(installables.size()); | 450 | + return workerExecutor.submit(new IntentWorker(data)); |
439 | - for (Intent installable : installables) { | ||
440 | - try { | ||
441 | - registerSubclassInstallerIfNeeded(installable); | ||
442 | - batches.addAll(getInstaller(installable).install(installable)); | ||
443 | - } catch (Exception e) { // TODO this should be IntentException | ||
444 | - throw new FlowRuleBatchOperationConversionException(batches, e); | ||
445 | - } | ||
446 | - } | ||
447 | - return batches; | ||
448 | } | 451 | } |
449 | 452 | ||
450 | private class IntentBatchPreprocess implements Runnable { | 453 | private class IntentBatchPreprocess implements Runnable { |
... | @@ -476,15 +479,13 @@ public class IntentManager | ... | @@ -476,15 +479,13 @@ public class IntentManager |
476 | @Override | 479 | @Override |
477 | public void run() { | 480 | public void run() { |
478 | try { | 481 | try { |
479 | - // 1. wrap each intentdata in a runnable and submit | 482 | + /* |
480 | - List<Future<IntentUpdate>> updates = createIntentUpdates(); | 483 | + 1. wrap each intentdata in a runnable and submit |
481 | - // TODO | 484 | + 2. wait for completion of all the work |
482 | - // 2. wait for completion of all the work | 485 | + 3. accumulate results and submit batch write of IntentData to store |
483 | - // 3. accumulate results and submit batch write of IntentData to store | 486 | + (we can also try to update these individually) |
484 | - // (we can also try to update these individually) | 487 | + */ |
485 | - | 488 | + submitUpdates(waitForFutures(createIntentUpdates())); |
486 | - | ||
487 | - //new IntentBatchApplyFirst(data, processIntentUpdates(updates), endTime, 0, null).run(); | ||
488 | } catch (Exception e) { | 489 | } catch (Exception e) { |
489 | log.error("Error submitting batches:", e); | 490 | log.error("Error submitting batches:", e); |
490 | // FIXME incomplete Intents should be cleaned up | 491 | // FIXME incomplete Intents should be cleaned up |
... | @@ -498,18 +499,33 @@ public class IntentManager | ... | @@ -498,18 +499,33 @@ public class IntentManager |
498 | } | 499 | } |
499 | } | 500 | } |
500 | 501 | ||
501 | - private List<Future<IntentUpdate>> createIntentUpdates() { | 502 | + private List<Future<CompletedIntentUpdate>> createIntentUpdates() { |
502 | return data.stream() | 503 | return data.stream() |
503 | - .map(IntentManager.this::submitIntentData) | 504 | + .map(IntentManager.this::submitIntentData) |
504 | - .collect(Collectors.toList()); | 505 | + .collect(Collectors.toList()); |
506 | + } | ||
507 | + | ||
508 | + private List<CompletedIntentUpdate> waitForFutures(List<Future<CompletedIntentUpdate>> futures) { | ||
509 | + ImmutableList.Builder<CompletedIntentUpdate> updateBuilder = ImmutableList.builder(); | ||
510 | + for (Future<CompletedIntentUpdate> future : futures) { | ||
511 | + try { | ||
512 | + updateBuilder.add(future.get()); | ||
513 | + } catch (InterruptedException | ExecutionException e) { | ||
514 | + //FIXME | ||
515 | + log.warn("Future failed: {}", e); | ||
516 | + } | ||
517 | + } | ||
518 | + return updateBuilder.build(); | ||
505 | } | 519 | } |
506 | - } | ||
507 | 520 | ||
508 | - private Future<IntentUpdate> submitIntentData(IntentData data) { | 521 | + private void submitUpdates(List<CompletedIntentUpdate> updates) { |
509 | - return workerExecutor.submit(new IntentWorker(data)); | 522 | + store.batchWrite(updates.stream() |
523 | + .map(CompletedIntentUpdate::data) | ||
524 | + .collect(Collectors.toList())); | ||
525 | + } | ||
510 | } | 526 | } |
511 | 527 | ||
512 | - private class IntentWorker implements Callable<IntentUpdate> { | 528 | + private final class IntentWorker implements Callable<CompletedIntentUpdate> { |
513 | 529 | ||
514 | private final IntentData data; | 530 | private final IntentData data; |
515 | 531 | ||
... | @@ -518,7 +534,7 @@ public class IntentManager | ... | @@ -518,7 +534,7 @@ public class IntentManager |
518 | } | 534 | } |
519 | 535 | ||
520 | @Override | 536 | @Override |
521 | - public IntentUpdate call() throws Exception { | 537 | + public CompletedIntentUpdate call() throws Exception { |
522 | IntentUpdate update = createIntentUpdate(data); | 538 | IntentUpdate update = createIntentUpdate(data); |
523 | Optional<IntentUpdate> currentPhase = Optional.of(update); | 539 | Optional<IntentUpdate> currentPhase = Optional.of(update); |
524 | IntentUpdate previousPhase = update; | 540 | IntentUpdate previousPhase = update; |
... | @@ -527,167 +543,7 @@ public class IntentManager | ... | @@ -527,167 +543,7 @@ public class IntentManager |
527 | previousPhase = currentPhase.get(); | 543 | previousPhase = currentPhase.get(); |
528 | currentPhase = previousPhase.execute(); | 544 | currentPhase = previousPhase.execute(); |
529 | } | 545 | } |
530 | - return previousPhase; | 546 | + return (CompletedIntentUpdate) previousPhase; |
531 | - } | ||
532 | - } | ||
533 | - | ||
534 | - | ||
535 | - // TODO: better naming | ||
536 | - private class IntentBatchApplyFirst extends IntentBatchPreprocess { | ||
537 | - | ||
538 | - protected final List<CompletedIntentUpdate> intentUpdates; | ||
539 | - protected final int installAttempt; | ||
540 | - protected Future<CompletedBatchOperation> future; | ||
541 | - | ||
542 | - IntentBatchApplyFirst(Collection<IntentData> operations, List<CompletedIntentUpdate> intentUpdates, | ||
543 | - long endTime, int installAttempt, Future<CompletedBatchOperation> future) { | ||
544 | - super(operations, endTime); | ||
545 | - this.intentUpdates = ImmutableList.copyOf(intentUpdates); | ||
546 | - this.future = future; | ||
547 | - this.installAttempt = installAttempt; | ||
548 | - } | ||
549 | - | ||
550 | - @Override | ||
551 | - public void run() { | ||
552 | - Future<CompletedBatchOperation> future = applyNextBatch(intentUpdates); | ||
553 | - new IntentBatchProcessFutures(data, intentUpdates, endTime, installAttempt, future).run(); | ||
554 | - } | ||
555 | - | ||
556 | - /** | ||
557 | - * Builds and applies the next batch, and returns the future. | ||
558 | - * | ||
559 | - * @return Future for next batch | ||
560 | - */ | ||
561 | - protected Future<CompletedBatchOperation> applyNextBatch(List<CompletedIntentUpdate> updates) { | ||
562 | - //TODO test this. (also, maybe save this batch) | ||
563 | - | ||
564 | - FlowRuleBatchOperation batch = createFlowRuleBatchOperation(updates); | ||
565 | - if (batch.size() > 0) { | ||
566 | - //FIXME apply batch might throw an exception | ||
567 | - return flowRuleService.applyBatch(batch); | ||
568 | - } else { | ||
569 | - return null; | ||
570 | - } | ||
571 | - } | ||
572 | - | ||
573 | - private FlowRuleBatchOperation createFlowRuleBatchOperation(List<CompletedIntentUpdate> intentUpdates) { | ||
574 | - FlowRuleBatchOperation batch = new FlowRuleBatchOperation(Collections.emptyList(), null, 0); | ||
575 | - for (CompletedIntentUpdate update : intentUpdates) { | ||
576 | - FlowRuleBatchOperation currentBatch = update.currentBatch(); | ||
577 | - if (currentBatch != null) { | ||
578 | - batch.addAll(currentBatch); | ||
579 | - } | ||
580 | - } | ||
581 | - return batch; | ||
582 | - } | ||
583 | - | ||
584 | - protected void abandonShip() { | ||
585 | - // the batch has failed | ||
586 | - // TODO: maybe we should do more? | ||
587 | - log.error("Walk the plank, matey..."); | ||
588 | - future = null; | ||
589 | - //FIXME | ||
590 | -// batchService.removeIntentOperations(data); | ||
591 | - } | ||
592 | - } | ||
593 | - | ||
594 | - // TODO: better naming | ||
595 | - private class IntentBatchProcessFutures extends IntentBatchApplyFirst { | ||
596 | - | ||
597 | - IntentBatchProcessFutures(Collection<IntentData> operations, List<CompletedIntentUpdate> intentUpdates, | ||
598 | - long endTime, int installAttempt, Future<CompletedBatchOperation> future) { | ||
599 | - super(operations, intentUpdates, endTime, installAttempt, future); | ||
600 | - } | ||
601 | - | ||
602 | - @Override | ||
603 | - public void run() { | ||
604 | - try { | ||
605 | - Future<CompletedBatchOperation> future = processFutures(); | ||
606 | - if (future == null) { | ||
607 | - // there are no outstanding batches; we are done | ||
608 | - //FIXME | ||
609 | - return; //? | ||
610 | -// batchService.removeIntentOperations(data); | ||
611 | - } else if (System.currentTimeMillis() > endTime) { | ||
612 | - // - cancel current FlowRuleBatch and resubmit again | ||
613 | - retry(); | ||
614 | - } else { | ||
615 | - // we are not done yet, yield the thread by resubmitting ourselves | ||
616 | - batchExecutor.submit(new IntentBatchProcessFutures(data, intentUpdates, endTime, | ||
617 | - installAttempt, future)); | ||
618 | - } | ||
619 | - } catch (Exception e) { | ||
620 | - log.error("Error submitting batches:", e); | ||
621 | - // FIXME incomplete Intents should be cleaned up | ||
622 | - // (transition to FAILED, etc.) | ||
623 | - abandonShip(); | ||
624 | - } | ||
625 | - } | ||
626 | - | ||
627 | - /** | ||
628 | - * Iterate through the pending futures, and remove them when they have completed. | ||
629 | - */ | ||
630 | - private Future<CompletedBatchOperation> processFutures() { | ||
631 | - try { | ||
632 | - CompletedBatchOperation completed = future.get(100, TimeUnit.NANOSECONDS); | ||
633 | - updateBatches(completed); | ||
634 | - return applyNextBatch(intentUpdates); | ||
635 | - } catch (TimeoutException | InterruptedException te) { | ||
636 | - log.trace("Installation of intents are still pending: {}", data); | ||
637 | - return future; | ||
638 | - } catch (ExecutionException e) { | ||
639 | - log.warn("Execution of batch failed: {}", data, e); | ||
640 | - abandonShip(); | ||
641 | - return future; | ||
642 | - } | ||
643 | - } | ||
644 | - | ||
645 | - private void updateBatches(CompletedBatchOperation completed) { | ||
646 | - if (completed.isSuccess()) { | ||
647 | - for (CompletedIntentUpdate update : intentUpdates) { | ||
648 | - update.batchSuccess(); | ||
649 | - } | ||
650 | - } else { | ||
651 | - // entire batch has been reverted... | ||
652 | - log.debug("Failed items: {}", completed.failedItems()); | ||
653 | - log.debug("Failed ids: {}", completed.failedIds()); | ||
654 | - | ||
655 | - for (Long id : completed.failedIds()) { | ||
656 | - IntentId targetId = IntentId.valueOf(id); | ||
657 | - for (CompletedIntentUpdate update : intentUpdates) { | ||
658 | - for (Intent intent : update.allInstallables()) { | ||
659 | - if (intent.id().equals(targetId)) { | ||
660 | - update.batchFailed(); | ||
661 | - break; | ||
662 | - } | ||
663 | - } | ||
664 | - } | ||
665 | - // don't increment the non-failed items, as they have been reverted. | ||
666 | - } | ||
667 | - } | ||
668 | - } | ||
669 | - | ||
670 | - private void retry() { | ||
671 | - log.debug("Execution timed out, retrying."); | ||
672 | - if (future.cancel(true)) { // cancel success; batch is reverted | ||
673 | - // reset the timer | ||
674 | - long timeLimit = calculateTimeoutLimit(); | ||
675 | - int attempts = installAttempt + 1; | ||
676 | - if (attempts == MAX_ATTEMPTS) { | ||
677 | - log.warn("Install request timed out: {}", data); | ||
678 | - for (CompletedIntentUpdate update : intentUpdates) { | ||
679 | - update.batchFailed(); | ||
680 | - } | ||
681 | - } else if (attempts > MAX_ATTEMPTS) { | ||
682 | - abandonShip(); | ||
683 | - return; | ||
684 | - } | ||
685 | - Future<CompletedBatchOperation> future = applyNextBatch(intentUpdates); | ||
686 | - batchExecutor.submit(new IntentBatchProcessFutures(data, intentUpdates, timeLimit, attempts, future)); | ||
687 | - } else { | ||
688 | - log.error("Cancelling FlowRuleBatch failed."); | ||
689 | - abandonShip(); | ||
690 | - } | ||
691 | } | 547 | } |
692 | } | 548 | } |
693 | 549 | ||
... | @@ -700,4 +556,166 @@ public class IntentManager | ... | @@ -700,4 +556,166 @@ public class IntentManager |
700 | // TODO ensure that only one batch is in flight at a time | 556 | // TODO ensure that only one batch is in flight at a time |
701 | } | 557 | } |
702 | } | 558 | } |
559 | + | ||
560 | +// /////////**************************/////////////////// | ||
561 | +// FIXME Need to build and monitor contexts from FlowRuleService | ||
562 | +// | ||
563 | +// // TODO: better naming | ||
564 | +// private class IntentBatchApplyFirst extends IntentBatchPreprocess { | ||
565 | +// | ||
566 | +// protected final List<CompletedIntentUpdate> intentUpdates; | ||
567 | +// protected final int installAttempt; | ||
568 | +// protected Future<CompletedBatchOperation> future; | ||
569 | +// | ||
570 | +// IntentBatchApplyFirst(Collection<IntentData> operations, List<CompletedIntentUpdate> intentUpdates, | ||
571 | +// long endTime, int installAttempt, Future<CompletedBatchOperation> future) { | ||
572 | +// super(operations, endTime); | ||
573 | +// this.intentUpdates = ImmutableList.copyOf(intentUpdates); | ||
574 | +// this.future = future; | ||
575 | +// this.installAttempt = installAttempt; | ||
576 | +// } | ||
577 | +// | ||
578 | +// @Override | ||
579 | +// public void run() { | ||
580 | +// Future<CompletedBatchOperation> future = applyNextBatch(intentUpdates); | ||
581 | +// new IntentBatchProcessFutures(data, intentUpdates, endTime, installAttempt, future).run(); | ||
582 | +// } | ||
583 | +// | ||
584 | +// /** | ||
585 | +// * Builds and applies the next batch, and returns the future. | ||
586 | +// * | ||
587 | +// * @return Future for next batch | ||
588 | +// */ | ||
589 | +// protected Future<CompletedBatchOperation> applyNextBatch(List<CompletedIntentUpdate> updates) { | ||
590 | +// //TODO test this. (also, maybe save this batch) | ||
591 | +// | ||
592 | +// FlowRuleBatchOperation batch = createFlowRuleBatchOperation(updates); | ||
593 | +// if (batch.size() > 0) { | ||
594 | +// //FIXME apply batch might throw an exception | ||
595 | +// return flowRuleService.applyBatch(batch); | ||
596 | +// } else { | ||
597 | +// return null; | ||
598 | +// } | ||
599 | +// } | ||
600 | +// | ||
601 | +// private FlowRuleBatchOperation createFlowRuleBatchOperation(List<CompletedIntentUpdate> intentUpdates) { | ||
602 | +// FlowRuleBatchOperation batch = new FlowRuleBatchOperation(Collections.emptyList(), null, 0); | ||
603 | +// for (CompletedIntentUpdate update : intentUpdates) { | ||
604 | +// FlowRuleBatchOperation currentBatch = update.currentBatch(); | ||
605 | +// if (currentBatch != null) { | ||
606 | +// batch.addAll(currentBatch); | ||
607 | +// } | ||
608 | +// } | ||
609 | +// return batch; | ||
610 | +// } | ||
611 | +// | ||
612 | +// protected void abandonShip() { | ||
613 | +// // the batch has failed | ||
614 | +// // TODO: maybe we should do more? | ||
615 | +// log.error("Walk the plank, matey..."); | ||
616 | +// future = null; | ||
617 | +// //FIXME | ||
618 | +// //batchService.removeIntentOperations(data); | ||
619 | +// } | ||
620 | +// } | ||
621 | +// | ||
622 | +// // TODO: better naming | ||
623 | +// private class IntentBatchProcessFutures extends IntentBatchApplyFirst { | ||
624 | +// | ||
625 | +// IntentBatchProcessFutures(Collection<IntentData> operations, List<CompletedIntentUpdate> intentUpdates, | ||
626 | +// long endTime, int installAttempt, Future<CompletedBatchOperation> future) { | ||
627 | +// super(operations, intentUpdates, endTime, installAttempt, future); | ||
628 | +// } | ||
629 | +// | ||
630 | +// @Override | ||
631 | +// public void run() { | ||
632 | +// try { | ||
633 | +// Future<CompletedBatchOperation> future = processFutures(); | ||
634 | +// if (future == null) { | ||
635 | +// // there are no outstanding batches; we are done | ||
636 | +// //FIXME | ||
637 | +// return; //? | ||
638 | +// //batchService.removeIntentOperations(data); | ||
639 | +// } else if (System.currentTimeMillis() > endTime) { | ||
640 | +// // - cancel current FlowRuleBatch and resubmit again | ||
641 | +// retry(); | ||
642 | +// } else { | ||
643 | +// // we are not done yet, yield the thread by resubmitting ourselves | ||
644 | +// batchExecutor.submit(new IntentBatchProcessFutures(data, intentUpdates, endTime, | ||
645 | +// installAttempt, future)); | ||
646 | +// } | ||
647 | +// } catch (Exception e) { | ||
648 | +// log.error("Error submitting batches:", e); | ||
649 | +// // FIXME incomplete Intents should be cleaned up | ||
650 | +// // (transition to FAILED, etc.) | ||
651 | +// abandonShip(); | ||
652 | +// } | ||
653 | +// } | ||
654 | +// | ||
655 | +// /** | ||
656 | +// * Iterate through the pending futures, and remove them when they have completed. | ||
657 | +// */ | ||
658 | +// private Future<CompletedBatchOperation> processFutures() { | ||
659 | +// try { | ||
660 | +// CompletedBatchOperation completed = future.get(100, TimeUnit.NANOSECONDS); | ||
661 | +// updateBatches(completed); | ||
662 | +// return applyNextBatch(intentUpdates); | ||
663 | +// } catch (TimeoutException | InterruptedException te) { | ||
664 | +// log.trace("Installation of intents are still pending: {}", data); | ||
665 | +// return future; | ||
666 | +// } catch (ExecutionException e) { | ||
667 | +// log.warn("Execution of batch failed: {}", data, e); | ||
668 | +// abandonShip(); | ||
669 | +// return future; | ||
670 | +// } | ||
671 | +// } | ||
672 | +// | ||
673 | +// private void updateBatches(CompletedBatchOperation completed) { | ||
674 | +// if (completed.isSuccess()) { | ||
675 | +// for (CompletedIntentUpdate update : intentUpdates) { | ||
676 | +// update.batchSuccess(); | ||
677 | +// } | ||
678 | +// } else { | ||
679 | +// // entire batch has been reverted... | ||
680 | +// log.debug("Failed items: {}", completed.failedItems()); | ||
681 | +// log.debug("Failed ids: {}", completed.failedIds()); | ||
682 | +// | ||
683 | +// for (Long id : completed.failedIds()) { | ||
684 | +// IntentId targetId = IntentId.valueOf(id); | ||
685 | +// for (CompletedIntentUpdate update : intentUpdates) { | ||
686 | +// for (Intent intent : update.allInstallables()) { | ||
687 | +// if (intent.id().equals(targetId)) { | ||
688 | +// update.batchFailed(); | ||
689 | +// break; | ||
690 | +// } | ||
691 | +// } | ||
692 | +// } | ||
693 | +// // don't increment the non-failed items, as they have been reverted. | ||
694 | +// } | ||
695 | +// } | ||
696 | +// } | ||
697 | +// | ||
698 | +// private void retry() { | ||
699 | +// log.debug("Execution timed out, retrying."); | ||
700 | +// if (future.cancel(true)) { // cancel success; batch is reverted | ||
701 | +// // reset the timer | ||
702 | +// long timeLimit = calculateTimeoutLimit(); | ||
703 | +// int attempts = installAttempt + 1; | ||
704 | +// if (attempts == MAX_ATTEMPTS) { | ||
705 | +// log.warn("Install request timed out: {}", data); | ||
706 | +// for (CompletedIntentUpdate update : intentUpdates) { | ||
707 | +// update.batchFailed(); | ||
708 | +// } | ||
709 | +// } else if (attempts > MAX_ATTEMPTS) { | ||
710 | +// abandonShip(); | ||
711 | +// return; | ||
712 | +// } | ||
713 | +// Future<CompletedBatchOperation> future = applyNextBatch(intentUpdates); | ||
714 | +// batchExecutor.submit(new IntentBatchProcessFutures(data, intentUpdates, timeLimit, attempts, future)); | ||
715 | +// } else { | ||
716 | +// log.error("Cancelling FlowRuleBatch failed."); | ||
717 | +// abandonShip(); | ||
718 | +// } | ||
719 | +// } | ||
720 | +// } | ||
703 | } | 721 | } | ... | ... |
... | @@ -15,7 +15,6 @@ | ... | @@ -15,7 +15,6 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.intent.impl; | 16 | package org.onosproject.net.intent.impl; |
17 | 17 | ||
18 | -import org.onosproject.net.intent.Intent; | ||
19 | import org.onosproject.net.intent.IntentData; | 18 | import org.onosproject.net.intent.IntentData; |
20 | 19 | ||
21 | import java.util.Optional; | 20 | import java.util.Optional; |
... | @@ -26,17 +25,20 @@ class WithdrawRequest implements IntentUpdate { | ... | @@ -26,17 +25,20 @@ class WithdrawRequest implements IntentUpdate { |
26 | 25 | ||
27 | // TODO: define an interface and use it, instead of IntentManager | 26 | // TODO: define an interface and use it, instead of IntentManager |
28 | private final IntentManager intentManager; | 27 | private final IntentManager intentManager; |
29 | - private final Intent intent; | 28 | + private final IntentData pending; |
30 | - private final IntentData currentState; | ||
31 | 29 | ||
32 | - WithdrawRequest(IntentManager intentManager, Intent intent, IntentData currentState) { | 30 | + WithdrawRequest(IntentManager intentManager, IntentData intentData) { |
33 | this.intentManager = checkNotNull(intentManager); | 31 | this.intentManager = checkNotNull(intentManager); |
34 | - this.intent = checkNotNull(intent); | 32 | + this.pending = checkNotNull(intentData); |
35 | - this.currentState = currentState; | ||
36 | } | 33 | } |
37 | 34 | ||
38 | @Override | 35 | @Override |
39 | public Optional<IntentUpdate> execute() { | 36 | public Optional<IntentUpdate> execute() { |
40 | - return Optional.of(new Withdrawing(intentManager, intent, currentState.installables())); //FIXME | 37 | + //FIXME... store hack |
38 | + IntentData current = intentManager.store.getIntentData(pending.key()); | ||
39 | + //TODO perhaps we want to validate that the pending and current are the | ||
40 | + // same version i.e. they are the same | ||
41 | + // Note: this call is not just the symmetric version of submit | ||
42 | + return Optional.of(new Withdrawing(intentManager, pending, current)); | ||
41 | } | 43 | } |
42 | } | 44 | } | ... | ... |
... | @@ -15,11 +15,9 @@ | ... | @@ -15,11 +15,9 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.intent.impl; | 16 | package org.onosproject.net.intent.impl; |
17 | 17 | ||
18 | -import com.google.common.collect.ImmutableList; | 18 | +import org.onosproject.net.flow.FlowRuleOperations; |
19 | -import org.onosproject.net.flow.FlowRuleBatchOperation; | 19 | +import org.onosproject.net.intent.IntentData; |
20 | -import org.onosproject.net.intent.Intent; | ||
21 | 20 | ||
22 | -import java.util.List; | ||
23 | import java.util.Optional; | 21 | import java.util.Optional; |
24 | 22 | ||
25 | import static com.google.common.base.Preconditions.checkNotNull; | 23 | import static com.google.common.base.Preconditions.checkNotNull; |
... | @@ -28,19 +26,21 @@ class Withdrawing implements IntentUpdate { | ... | @@ -28,19 +26,21 @@ class Withdrawing implements IntentUpdate { |
28 | 26 | ||
29 | // TODO: define an interface and use it, instead of IntentManager | 27 | // TODO: define an interface and use it, instead of IntentManager |
30 | private final IntentManager intentManager; | 28 | private final IntentManager intentManager; |
31 | - private final Intent intent; | 29 | + private final IntentData pending; |
32 | - private final List<Intent> installables; | 30 | + private final IntentData current; |
33 | 31 | ||
34 | - Withdrawing(IntentManager intentManager, Intent intent, List<Intent> installables) { | 32 | + Withdrawing(IntentManager intentManager, IntentData pending, IntentData current) { |
35 | this.intentManager = checkNotNull(intentManager); | 33 | this.intentManager = checkNotNull(intentManager); |
36 | - this.intent = checkNotNull(intent); | 34 | + this.pending = checkNotNull(pending); |
37 | - this.installables = ImmutableList.copyOf(installables); | 35 | + this.current = checkNotNull(current); |
38 | } | 36 | } |
39 | 37 | ||
40 | @Override | 38 | @Override |
41 | public Optional<IntentUpdate> execute() { | 39 | public Optional<IntentUpdate> execute() { |
42 | - List<FlowRuleBatchOperation> batches = intentManager.uninstallIntent(intent, installables); | 40 | + FlowRuleOperations flowRules |
41 | + = intentManager.uninstallIntent(current.intent(), current.installables()); | ||
42 | + intentManager.flowRuleService.apply(flowRules); //FIXME | ||
43 | 43 | ||
44 | - return Optional.of(new Withdrawn(intentManager, intent, installables, batches)); | 44 | + return Optional.of(new Withdrawn(pending)); |
45 | } | 45 | } |
46 | } | 46 | } | ... | ... |
... | @@ -15,53 +15,22 @@ | ... | @@ -15,53 +15,22 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.intent.impl; | 16 | package org.onosproject.net.intent.impl; |
17 | 17 | ||
18 | -import com.google.common.collect.ImmutableList; | 18 | +import org.onosproject.net.intent.IntentData; |
19 | -import org.onosproject.net.flow.FlowRuleBatchOperation; | ||
20 | -import org.onosproject.net.intent.Intent; | ||
21 | - | ||
22 | -import java.util.LinkedList; | ||
23 | -import java.util.List; | ||
24 | 19 | ||
25 | import static com.google.common.base.Preconditions.checkNotNull; | 20 | import static com.google.common.base.Preconditions.checkNotNull; |
21 | +import static org.onosproject.net.intent.IntentState.WITHDRAWING; | ||
26 | 22 | ||
27 | class Withdrawn implements CompletedIntentUpdate { | 23 | class Withdrawn implements CompletedIntentUpdate { |
28 | 24 | ||
29 | - // TODO: define an interface and use it, instead of IntentManager | 25 | + private final IntentData intentData; |
30 | - private final IntentManager intentManager; | ||
31 | - private final Intent intent; | ||
32 | - private final List<Intent> installables; | ||
33 | - private final List<FlowRuleBatchOperation> batches; | ||
34 | - private int currentBatch; | ||
35 | - | ||
36 | - Withdrawn(IntentManager intentManager, | ||
37 | - Intent intent, List<Intent> installables, List<FlowRuleBatchOperation> batches) { | ||
38 | - this.intentManager = checkNotNull(intentManager); | ||
39 | - this.intent = checkNotNull(intent); | ||
40 | - this.installables = ImmutableList.copyOf(installables); | ||
41 | - this.batches = new LinkedList<>(batches); | ||
42 | - this.currentBatch = 0; | ||
43 | - } | ||
44 | - | ||
45 | - @Override | ||
46 | - public List<Intent> allInstallables() { | ||
47 | - return installables; | ||
48 | - } | ||
49 | - | ||
50 | - @Override | ||
51 | - public void batchSuccess() { | ||
52 | - currentBatch++; | ||
53 | - } | ||
54 | 26 | ||
55 | - @Override | 27 | + Withdrawn(IntentData intentData) { |
56 | - public FlowRuleBatchOperation currentBatch() { | 28 | + this.intentData = checkNotNull(intentData); |
57 | - return currentBatch < batches.size() ? batches.get(currentBatch) : null; | 29 | + this.intentData.setState(WITHDRAWING); |
58 | } | 30 | } |
59 | 31 | ||
60 | @Override | 32 | @Override |
61 | - public void batchFailed() { | 33 | + public IntentData data() { |
62 | - for (int i = batches.size() - 1; i >= currentBatch; i--) { | 34 | + return intentData; |
63 | - batches.remove(i); | ||
64 | - } | ||
65 | - batches.addAll(intentManager.uninstallIntent(intent, installables)); | ||
66 | } | 35 | } |
67 | } | 36 | } | ... | ... |
-
Please register or login to post a comment