Refactored intermediate IntentUpdate classes
Change-Id: I3d4a435ef4aa97559d5407d49f45519098c3f193
diff --git a/core/api/src/main/java/org/onosproject/net/intent/IntentInstaller.java b/core/api/src/main/java/org/onosproject/net/intent/IntentInstaller.java
index 6b9e35d..50c609a 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/IntentInstaller.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/IntentInstaller.java
@@ -15,7 +15,10 @@
*/
package org.onosproject.net.intent;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleBatchEntry;
import org.onosproject.net.flow.FlowRuleBatchOperation;
+import org.onosproject.net.flow.FlowRuleOperations;
import java.util.List;
@@ -30,7 +33,32 @@
* @return flow rule operations to complete install
* @throws IntentException if issues are encountered while installing the intent
*/
+ @Deprecated
List<FlowRuleBatchOperation> install(T intent);
+ // FIXME
+ default FlowRuleOperations.Builder install2(T intent) {
+ FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
+ for (FlowRuleBatchOperation batch : install(intent)) {
+ for (FlowRuleBatchEntry entry : batch.getOperations()) {
+ FlowRule rule = entry.target();
+ switch (entry.operator()) {
+ case ADD:
+ builder.add(rule);
+ break;
+ case REMOVE:
+ builder.remove(rule);
+ break;
+ case MODIFY:
+ builder.modify(rule);
+ break;
+ default:
+ break;
+ }
+ }
+ builder.newStage();
+ }
+ return builder;
+ }
/**
* Uninstalls the specified intent from the environment.
@@ -39,7 +67,32 @@
* @return flow rule operations to complete uninstall
* @throws IntentException if issues are encountered while uninstalling the intent
*/
+ @Deprecated
List<FlowRuleBatchOperation> uninstall(T intent);
+ // FIXME
+ default FlowRuleOperations.Builder uninstall2(T intent) {
+ FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
+ for (FlowRuleBatchOperation batch : uninstall(intent)) {
+ for (FlowRuleBatchEntry entry : batch.getOperations()) {
+ FlowRule rule = entry.target();
+ switch (entry.operator()) {
+ case ADD:
+ builder.add(rule);
+ break;
+ case REMOVE:
+ builder.remove(rule);
+ break;
+ case MODIFY:
+ builder.modify(rule);
+ break;
+ default:
+ break;
+ }
+ }
+ builder.newStage();
+ }
+ return builder;
+ }
/**
* Replaces the specified intent with a new one in the environment.
@@ -49,6 +102,31 @@
* @return flow rule operations to complete the replace
* @throws IntentException if issues are encountered while uninstalling the intent
*/
+ @Deprecated
List<FlowRuleBatchOperation> replace(T oldIntent, T newIntent);
+ // FIXME
+ default FlowRuleOperations.Builder replace2(T oldIntent, T newIntent) {
+ FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
+ for (FlowRuleBatchOperation batch : replace(oldIntent, newIntent)) {
+ for (FlowRuleBatchEntry entry : batch.getOperations()) {
+ FlowRule rule = entry.target();
+ switch (entry.operator()) {
+ case ADD:
+ builder.add(rule);
+ break;
+ case REMOVE:
+ builder.remove(rule);
+ break;
+ case MODIFY:
+ builder.modify(rule);
+ break;
+ default:
+ break;
+ }
+ }
+ builder.newStage();
+ }
+ return builder;
+ }
}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/Compiling.java b/core/net/src/main/java/org/onosproject/net/intent/impl/Compiling.java
index 5b7953c..e784621 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/Compiling.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/Compiling.java
@@ -16,10 +16,12 @@
package org.onosproject.net.intent.impl;
import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
import org.onosproject.net.intent.IntentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.List;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -30,25 +32,29 @@
// TODO: define an interface and use it, instead of IntentManager
private final IntentManager intentManager;
- private final Intent intent;
+ private final IntentData pending;
+ private final IntentData current;
- Compiling(IntentManager intentManager, Intent intent) {
+ Compiling(IntentManager intentManager, IntentData pending, IntentData current) {
this.intentManager = checkNotNull(intentManager);
- this.intent = checkNotNull(intent);
+ this.pending = checkNotNull(pending);
+ this.current = current;
}
@Override
public Optional<IntentUpdate> execute() {
try {
- return Optional.of(new Installing(intentManager, intent, intentManager.compileIntent(intent, null)));
+ List<Intent> installables = (current != null) ? current.installables() : null;
+ pending.setInstallables(intentManager.compileIntent(pending.intent(), installables));
+ return Optional.of(new Installing(intentManager, pending, current));
} catch (PathNotFoundException e) {
- log.debug("Path not found for intent {}", intent);
+ log.debug("Path not found for intent {}", pending.intent());
// TODO: revisit to implement failure handling
- return Optional.of(new DoNothing());
+ return Optional.of(new CompilingFailed(pending)); //FIXME failed state transition
} catch (IntentException e) {
- log.warn("Unable to compile intent {} due to:", intent.id(), e);
+ log.warn("Unable to compile intent {} due to:", pending.intent().id(), e);
// TODO: revisit to implement failure handling
- return Optional.of(new DoNothing());
+ return Optional.of(new CompilingFailed(pending)); //FIXME failed state transition
}
}
}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/CompilingFailed.java b/core/net/src/main/java/org/onosproject/net/intent/impl/CompilingFailed.java
new file mode 100644
index 0000000..f7c25ca
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/CompilingFailed.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.intent.impl;
+
+import org.onosproject.net.intent.IntentData;
+
+import static org.onosproject.net.intent.IntentState.FAILED;
+
+/**
+ * Represents a phase where the compile has failed.
+ */
+class CompilingFailed implements CompletedIntentUpdate {
+
+ private final IntentData intentData;
+
+ CompilingFailed(IntentData intentData) {
+ this.intentData = intentData;
+ this.intentData.setState(FAILED);
+ }
+
+ @Override
+ public IntentData data() {
+ return intentData;
+ }
+
+ //FIXME we also need to decide what to do with the current intent's resources i.e. cleanup or revert
+}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/CompletedIntentUpdate.java b/core/net/src/main/java/org/onosproject/net/intent/impl/CompletedIntentUpdate.java
index caddab1..60dc334 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/CompletedIntentUpdate.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/CompletedIntentUpdate.java
@@ -15,11 +15,8 @@
*/
package org.onosproject.net.intent.impl;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
-import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
-import java.util.Collections;
-import java.util.List;
import java.util.Optional;
/**
@@ -27,38 +24,10 @@
*/
interface CompletedIntentUpdate extends IntentUpdate {
- /**
- * Moves forward with the contained current batch.
- * This method is invoked when the batch is successfully completed.
- */
- default void batchSuccess() {}
-
- /**
- * Reverts the contained batches.
- * This method is invoked when the batch results in failure.
- */
- default void batchFailed() {}
-
- /**
- * Returns the current FlowRuleBatchOperation.
- *
- * @return current FlowRuleBatchOperation
- */
- default FlowRuleBatchOperation currentBatch() {
- return null;
- }
-
- /**
- * Returns all of installable intents this instance holds.
- *
- * @return all of installable intents
- */
- default List<Intent> allInstallables() {
- return Collections.emptyList();
- }
-
@Override
default Optional<IntentUpdate> execute() {
return Optional.empty();
}
+
+ IntentData data();
}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/DoNothing.java b/core/net/src/main/java/org/onosproject/net/intent/impl/DoNothing.java
deleted file mode 100644
index caf64c1..0000000
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/DoNothing.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.net.intent.impl;
-
-/**
- * Represents a phase doing nothing.
- */
-class DoNothing implements CompletedIntentUpdate {
-}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/InstallRequest.java b/core/net/src/main/java/org/onosproject/net/intent/impl/InstallRequest.java
index 42b9e1d..c22cd35 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/InstallRequest.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/InstallRequest.java
@@ -15,7 +15,6 @@
*/
package org.onosproject.net.intent.impl;
-import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentData;
import java.util.Optional;
@@ -27,17 +26,17 @@
// TODO: define an interface and use it, instead of IntentManager
private final IntentManager intentManager;
- private final Intent intent;
- private final IntentData currentState;
+ private final IntentData pending;
- InstallRequest(IntentManager intentManager, Intent intent, IntentData currentState) {
+ InstallRequest(IntentManager intentManager, IntentData intentData) {
this.intentManager = checkNotNull(intentManager);
- this.intent = checkNotNull(intent);
- this.currentState = currentState;
+ this.pending = checkNotNull(intentData);
}
@Override
public Optional<IntentUpdate> execute() {
- return Optional.of(new Compiling(intentManager, intent)); //FIXME
+ //FIXME... store hack
+ IntentData current = intentManager.store.getIntentData(pending.key());
+ return Optional.of(new Compiling(intentManager, pending, current));
}
}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/Installed.java b/core/net/src/main/java/org/onosproject/net/intent/impl/Installed.java
index 316821b..a3a7e1d 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/Installed.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/Installed.java
@@ -15,60 +15,21 @@
*/
package org.onosproject.net.intent.impl;
-import com.google.common.collect.ImmutableList;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentState;
-
-import java.util.LinkedList;
-import java.util.List;
+import org.onosproject.net.intent.IntentData;
import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.net.intent.IntentState.FAILED;
import static org.onosproject.net.intent.IntentState.INSTALLING;
class Installed implements CompletedIntentUpdate {
- // TODO: define an interface and use it, instead of IntentManager
- private final IntentManager intentManager;
- private final Intent intent;
- private final List<Intent> installables;
- private IntentState intentState;
- private final List<FlowRuleBatchOperation> batches;
- private int currentBatch = 0;
+ private final IntentData intentData;
- Installed(IntentManager intentManager,
- Intent intent, List<Intent> installables, List<FlowRuleBatchOperation> batches) {
- this.intentManager = checkNotNull(intentManager);
- this.intent = checkNotNull(intent);
- this.installables = ImmutableList.copyOf(checkNotNull(installables));
- this.batches = new LinkedList<>(checkNotNull(batches));
- this.intentState = INSTALLING;
+ Installed(IntentData intentData) {
+ this.intentData = checkNotNull(intentData);
+ this.intentData.setState(INSTALLING);
}
- @Override
- public void batchSuccess() {
- currentBatch++;
- }
-
- @Override
- public List<Intent> allInstallables() {
- return installables;
- }
-
- @Override
- public FlowRuleBatchOperation currentBatch() {
- return currentBatch < batches.size() ? batches.get(currentBatch) : null;
- }
-
- @Override
- public void batchFailed() {
- for (int i = batches.size() - 1; i >= currentBatch; i--) {
- batches.remove(i);
- }
- intentState = FAILED;
- batches.addAll(intentManager.uninstallIntent(intent, installables));
-
- // TODO we might want to try to recompile the new intent
+ public IntentData data() {
+ return intentData;
}
}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/Installing.java b/core/net/src/main/java/org/onosproject/net/intent/impl/Installing.java
index fae62e1..0d9ce36 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/Installing.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/Installing.java
@@ -15,13 +15,11 @@
*/
package org.onosproject.net.intent.impl;
-import com.google.common.collect.ImmutableList;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
-import org.onosproject.net.intent.Intent;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.intent.IntentData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.List;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -32,26 +30,27 @@
private static final Logger log = LoggerFactory.getLogger(Installing.class);
private final IntentManager intentManager;
- private final Intent intent;
- private final List<Intent> installables;
+ private final IntentData pending;
+ private final IntentData current;
// TODO: define an interface and use it, instead of IntentManager
- Installing(IntentManager intentManager, Intent intent, List<Intent> installables) {
+ Installing(IntentManager intentManager, IntentData pending, IntentData current) {
this.intentManager = checkNotNull(intentManager);
- this.intent = checkNotNull(intent);
- this.installables = ImmutableList.copyOf(checkNotNull(installables));
+ this.pending = checkNotNull(pending);
+ this.current = current;
}
@Override
public Optional<IntentUpdate> execute() {
try {
- List<FlowRuleBatchOperation> converted = intentManager.convert(installables);
+ FlowRuleOperations flowRules = intentManager.coordinate(pending.installables());
// TODO: call FlowRuleService API to push FlowRules and track resources,
// which the submitted intent will use.
- return Optional.of(new Installed(intentManager, intent, installables, converted));
+ intentManager.flowRuleService.apply(flowRules);
+ return Optional.of(new Installed(pending));
} catch (FlowRuleBatchOperationConversionException e) {
- log.warn("Unable to install intent {} due to:", intent.id(), e.getCause());
- return Optional.of(new InstallingFailed(intentManager, intent, installables, e.converted()));
+ log.warn("Unable to install intent {} due to:", pending.intent().id(), e.getCause());
+ return Optional.of(new InstallingFailed(pending));
}
}
}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/InstallingFailed.java b/core/net/src/main/java/org/onosproject/net/intent/impl/InstallingFailed.java
index 0a7a5c4..48e836e 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/InstallingFailed.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/InstallingFailed.java
@@ -15,53 +15,23 @@
*/
package org.onosproject.net.intent.impl;
-import com.google.common.collect.ImmutableList;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
-import org.onosproject.net.intent.Intent;
-
-import java.util.LinkedList;
-import java.util.List;
+import org.onosproject.net.intent.IntentData;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.intent.IntentState.FAILED;
class InstallingFailed implements CompletedIntentUpdate {
- private IntentManager intentManager;
- private final Intent intent;
- private final List<Intent> installables;
- private final List<FlowRuleBatchOperation> batches;
- private int currentBatch = 0;
+ private final IntentData intentData;
- InstallingFailed(IntentManager intentManager,
- Intent intent, List<Intent> installables, List<FlowRuleBatchOperation> batches) {
- this.intentManager = intentManager;
- this.intent = checkNotNull(intent);
- this.installables = ImmutableList.copyOf(checkNotNull(installables));
- this.batches = new LinkedList<>(checkNotNull(batches));
+ InstallingFailed(IntentData intentData) {
+ this.intentData = checkNotNull(intentData);
+ this.intentData.setState(FAILED); //FIXME maybe should be "BROKEN"
+ //TODO consider adding the flow rule operations here
}
@Override
- public List<Intent> allInstallables() {
- return installables;
- }
-
- @Override
- public void batchSuccess() {
- currentBatch++;
- }
-
- @Override
- public FlowRuleBatchOperation currentBatch() {
- return currentBatch < batches.size() ? batches.get(currentBatch) : null;
- }
-
- @Override
- public void batchFailed() {
- for (int i = batches.size() - 1; i >= currentBatch; i--) {
- batches.remove(i);
- }
- batches.addAll(intentManager.uninstallIntent(intent, installables));
-
- // TODO we might want to try to recompile the new intent
+ public IntentData data() {
+ return intentData;
}
}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
index 373b629..7325dd5 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
@@ -15,23 +15,9 @@
*/
package org.onosproject.net.intent.impl;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.stream.Collectors;
-
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -42,8 +28,8 @@
import org.onosproject.core.IdGenerator;
import org.onosproject.event.AbstractListenerRegistry;
import org.onosproject.event.EventDeliveryService;
-import org.onosproject.net.flow.CompletedBatchOperation;
import org.onosproject.net.flow.FlowRuleBatchOperation;
+import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentBatchDelegate;
@@ -61,17 +47,25 @@
import org.onosproject.net.intent.IntentStoreDelegate;
import org.slf4j.Logger;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.Executors.newFixedThreadPool;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.namedThreads;
-import static org.onosproject.net.intent.IntentState.FAILED;
-import static org.onosproject.net.intent.IntentState.INSTALL_REQ;
-import static org.onosproject.net.intent.IntentState.WITHDRAW_REQ;
+import static org.onosproject.net.intent.IntentState.*;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -285,6 +279,23 @@
return installable;
}
+ //TODO javadoc
+ //FIXME
+ FlowRuleOperations coordinate(List<Intent> installables) {
+ //List<FlowRuleBatchOperation> batches = new ArrayList<>(installables.size());
+ for (Intent installable : installables) {
+ try {
+ registerSubclassInstallerIfNeeded(installable);
+ //FIXME need to migrate installers to FlowRuleOperations
+ // FIXME need to aggregate the FlowRuleOperations across installables
+ getInstaller(installable).install2(installable).build(null/*FIXME*/);
+ } catch (Exception e) { // TODO this should be IntentException
+ throw new FlowRuleBatchOperationConversionException(null/*FIXME*/, e);
+ }
+ }
+ return null;
+ }
+
/**
* Uninstalls all installable intents associated with the given intent.
*
@@ -292,19 +303,21 @@
* @param installables installable intents
* @return list of batches to uninstall intent
*/
- List<FlowRuleBatchOperation> uninstallIntent(Intent intent, List<Intent> installables) {
+ //FIXME
+ FlowRuleOperations uninstallIntent(Intent intent, List<Intent> installables) {
List<FlowRuleBatchOperation> batches = Lists.newArrayList();
for (Intent installable : installables) {
trackerService.removeTrackedResources(intent.id(),
installable.resources());
try {
- batches.addAll(getInstaller(installable).uninstall(installable));
+ // FIXME need to aggregate the FlowRuleOperations across installables
+ getInstaller(installable).uninstall2(installable).build(null/*FIXME*/);
} catch (IntentException e) {
log.warn("Unable to uninstall intent {} due to:", intent.id(), e);
// TODO: this should never happen. but what if it does?
}
}
- return batches;
+ return null; //FIXME
}
/**
@@ -414,12 +427,11 @@
// TODO: simplify the branching statements
private IntentUpdate createIntentUpdate(IntentData intentData) {
- IntentData currentState = store.getIntentData(intentData.key());
switch (intentData.state()) {
case INSTALL_REQ:
- return new InstallRequest(this, intentData.intent(), currentState);
+ return new InstallRequest(this, intentData);
case WITHDRAW_REQ:
- return new WithdrawRequest(this, intentData.intent(), currentState);
+ return new WithdrawRequest(this, intentData);
// fallthrough
case COMPILING:
case INSTALLING:
@@ -430,21 +442,12 @@
case FAILED:
default:
// illegal state
- return new DoNothing();
+ return new CompilingFailed(intentData);
}
}
- List<FlowRuleBatchOperation> convert(List<Intent> installables) {
- List<FlowRuleBatchOperation> batches = new ArrayList<>(installables.size());
- for (Intent installable : installables) {
- try {
- registerSubclassInstallerIfNeeded(installable);
- batches.addAll(getInstaller(installable).install(installable));
- } catch (Exception e) { // TODO this should be IntentException
- throw new FlowRuleBatchOperationConversionException(batches, e);
- }
- }
- return batches;
+ private Future<CompletedIntentUpdate> submitIntentData(IntentData data) {
+ return workerExecutor.submit(new IntentWorker(data));
}
private class IntentBatchPreprocess implements Runnable {
@@ -476,15 +479,13 @@
@Override
public void run() {
try {
- // 1. wrap each intentdata in a runnable and submit
- List<Future<IntentUpdate>> updates = createIntentUpdates();
- // TODO
- // 2. wait for completion of all the work
- // 3. accumulate results and submit batch write of IntentData to store
- // (we can also try to update these individually)
-
-
- //new IntentBatchApplyFirst(data, processIntentUpdates(updates), endTime, 0, null).run();
+ /*
+ 1. wrap each intentdata in a runnable and submit
+ 2. wait for completion of all the work
+ 3. accumulate results and submit batch write of IntentData to store
+ (we can also try to update these individually)
+ */
+ submitUpdates(waitForFutures(createIntentUpdates()));
} catch (Exception e) {
log.error("Error submitting batches:", e);
// FIXME incomplete Intents should be cleaned up
@@ -498,18 +499,33 @@
}
}
- private List<Future<IntentUpdate>> createIntentUpdates() {
+ private List<Future<CompletedIntentUpdate>> createIntentUpdates() {
return data.stream()
- .map(IntentManager.this::submitIntentData)
- .collect(Collectors.toList());
+ .map(IntentManager.this::submitIntentData)
+ .collect(Collectors.toList());
+ }
+
+ private List<CompletedIntentUpdate> waitForFutures(List<Future<CompletedIntentUpdate>> futures) {
+ ImmutableList.Builder<CompletedIntentUpdate> updateBuilder = ImmutableList.builder();
+ for (Future<CompletedIntentUpdate> future : futures) {
+ try {
+ updateBuilder.add(future.get());
+ } catch (InterruptedException | ExecutionException e) {
+ //FIXME
+ log.warn("Future failed: {}", e);
+ }
+ }
+ return updateBuilder.build();
+ }
+
+ private void submitUpdates(List<CompletedIntentUpdate> updates) {
+ store.batchWrite(updates.stream()
+ .map(CompletedIntentUpdate::data)
+ .collect(Collectors.toList()));
}
}
- private Future<IntentUpdate> submitIntentData(IntentData data) {
- return workerExecutor.submit(new IntentWorker(data));
- }
-
- private class IntentWorker implements Callable<IntentUpdate> {
+ private final class IntentWorker implements Callable<CompletedIntentUpdate> {
private final IntentData data;
@@ -518,7 +534,7 @@
}
@Override
- public IntentUpdate call() throws Exception {
+ public CompletedIntentUpdate call() throws Exception {
IntentUpdate update = createIntentUpdate(data);
Optional<IntentUpdate> currentPhase = Optional.of(update);
IntentUpdate previousPhase = update;
@@ -527,167 +543,7 @@
previousPhase = currentPhase.get();
currentPhase = previousPhase.execute();
}
- return previousPhase;
- }
- }
-
-
- // TODO: better naming
- private class IntentBatchApplyFirst extends IntentBatchPreprocess {
-
- protected final List<CompletedIntentUpdate> intentUpdates;
- protected final int installAttempt;
- protected Future<CompletedBatchOperation> future;
-
- IntentBatchApplyFirst(Collection<IntentData> operations, List<CompletedIntentUpdate> intentUpdates,
- long endTime, int installAttempt, Future<CompletedBatchOperation> future) {
- super(operations, endTime);
- this.intentUpdates = ImmutableList.copyOf(intentUpdates);
- this.future = future;
- this.installAttempt = installAttempt;
- }
-
- @Override
- public void run() {
- Future<CompletedBatchOperation> future = applyNextBatch(intentUpdates);
- new IntentBatchProcessFutures(data, intentUpdates, endTime, installAttempt, future).run();
- }
-
- /**
- * Builds and applies the next batch, and returns the future.
- *
- * @return Future for next batch
- */
- protected Future<CompletedBatchOperation> applyNextBatch(List<CompletedIntentUpdate> updates) {
- //TODO test this. (also, maybe save this batch)
-
- FlowRuleBatchOperation batch = createFlowRuleBatchOperation(updates);
- if (batch.size() > 0) {
- //FIXME apply batch might throw an exception
- return flowRuleService.applyBatch(batch);
- } else {
- return null;
- }
- }
-
- private FlowRuleBatchOperation createFlowRuleBatchOperation(List<CompletedIntentUpdate> intentUpdates) {
- FlowRuleBatchOperation batch = new FlowRuleBatchOperation(Collections.emptyList(), null, 0);
- for (CompletedIntentUpdate update : intentUpdates) {
- FlowRuleBatchOperation currentBatch = update.currentBatch();
- if (currentBatch != null) {
- batch.addAll(currentBatch);
- }
- }
- return batch;
- }
-
- protected void abandonShip() {
- // the batch has failed
- // TODO: maybe we should do more?
- log.error("Walk the plank, matey...");
- future = null;
- //FIXME
-// batchService.removeIntentOperations(data);
- }
- }
-
- // TODO: better naming
- private class IntentBatchProcessFutures extends IntentBatchApplyFirst {
-
- IntentBatchProcessFutures(Collection<IntentData> operations, List<CompletedIntentUpdate> intentUpdates,
- long endTime, int installAttempt, Future<CompletedBatchOperation> future) {
- super(operations, intentUpdates, endTime, installAttempt, future);
- }
-
- @Override
- public void run() {
- try {
- Future<CompletedBatchOperation> future = processFutures();
- if (future == null) {
- // there are no outstanding batches; we are done
- //FIXME
- return; //?
-// batchService.removeIntentOperations(data);
- } else if (System.currentTimeMillis() > endTime) {
- // - cancel current FlowRuleBatch and resubmit again
- retry();
- } else {
- // we are not done yet, yield the thread by resubmitting ourselves
- batchExecutor.submit(new IntentBatchProcessFutures(data, intentUpdates, endTime,
- installAttempt, future));
- }
- } catch (Exception e) {
- log.error("Error submitting batches:", e);
- // FIXME incomplete Intents should be cleaned up
- // (transition to FAILED, etc.)
- abandonShip();
- }
- }
-
- /**
- * Iterate through the pending futures, and remove them when they have completed.
- */
- private Future<CompletedBatchOperation> processFutures() {
- try {
- CompletedBatchOperation completed = future.get(100, TimeUnit.NANOSECONDS);
- updateBatches(completed);
- return applyNextBatch(intentUpdates);
- } catch (TimeoutException | InterruptedException te) {
- log.trace("Installation of intents are still pending: {}", data);
- return future;
- } catch (ExecutionException e) {
- log.warn("Execution of batch failed: {}", data, e);
- abandonShip();
- return future;
- }
- }
-
- private void updateBatches(CompletedBatchOperation completed) {
- if (completed.isSuccess()) {
- for (CompletedIntentUpdate update : intentUpdates) {
- update.batchSuccess();
- }
- } else {
- // entire batch has been reverted...
- log.debug("Failed items: {}", completed.failedItems());
- log.debug("Failed ids: {}", completed.failedIds());
-
- for (Long id : completed.failedIds()) {
- IntentId targetId = IntentId.valueOf(id);
- for (CompletedIntentUpdate update : intentUpdates) {
- for (Intent intent : update.allInstallables()) {
- if (intent.id().equals(targetId)) {
- update.batchFailed();
- break;
- }
- }
- }
- // don't increment the non-failed items, as they have been reverted.
- }
- }
- }
-
- private void retry() {
- log.debug("Execution timed out, retrying.");
- if (future.cancel(true)) { // cancel success; batch is reverted
- // reset the timer
- long timeLimit = calculateTimeoutLimit();
- int attempts = installAttempt + 1;
- if (attempts == MAX_ATTEMPTS) {
- log.warn("Install request timed out: {}", data);
- for (CompletedIntentUpdate update : intentUpdates) {
- update.batchFailed();
- }
- } else if (attempts > MAX_ATTEMPTS) {
- abandonShip();
- return;
- }
- Future<CompletedBatchOperation> future = applyNextBatch(intentUpdates);
- batchExecutor.submit(new IntentBatchProcessFutures(data, intentUpdates, timeLimit, attempts, future));
- } else {
- log.error("Cancelling FlowRuleBatch failed.");
- abandonShip();
- }
+ return (CompletedIntentUpdate) previousPhase;
}
}
@@ -700,4 +556,166 @@
// TODO ensure that only one batch is in flight at a time
}
}
+
+// /////////**************************///////////////////
+// FIXME Need to build and monitor contexts from FlowRuleService
+//
+// // TODO: better naming
+// private class IntentBatchApplyFirst extends IntentBatchPreprocess {
+//
+// protected final List<CompletedIntentUpdate> intentUpdates;
+// protected final int installAttempt;
+// protected Future<CompletedBatchOperation> future;
+//
+// IntentBatchApplyFirst(Collection<IntentData> operations, List<CompletedIntentUpdate> intentUpdates,
+// long endTime, int installAttempt, Future<CompletedBatchOperation> future) {
+// super(operations, endTime);
+// this.intentUpdates = ImmutableList.copyOf(intentUpdates);
+// this.future = future;
+// this.installAttempt = installAttempt;
+// }
+//
+// @Override
+// public void run() {
+// Future<CompletedBatchOperation> future = applyNextBatch(intentUpdates);
+// new IntentBatchProcessFutures(data, intentUpdates, endTime, installAttempt, future).run();
+// }
+//
+// /**
+// * Builds and applies the next batch, and returns the future.
+// *
+// * @return Future for next batch
+// */
+// protected Future<CompletedBatchOperation> applyNextBatch(List<CompletedIntentUpdate> updates) {
+// //TODO test this. (also, maybe save this batch)
+//
+// FlowRuleBatchOperation batch = createFlowRuleBatchOperation(updates);
+// if (batch.size() > 0) {
+// //FIXME apply batch might throw an exception
+// return flowRuleService.applyBatch(batch);
+// } else {
+// return null;
+// }
+// }
+//
+// private FlowRuleBatchOperation createFlowRuleBatchOperation(List<CompletedIntentUpdate> intentUpdates) {
+// FlowRuleBatchOperation batch = new FlowRuleBatchOperation(Collections.emptyList(), null, 0);
+// for (CompletedIntentUpdate update : intentUpdates) {
+// FlowRuleBatchOperation currentBatch = update.currentBatch();
+// if (currentBatch != null) {
+// batch.addAll(currentBatch);
+// }
+// }
+// return batch;
+// }
+//
+// protected void abandonShip() {
+// // the batch has failed
+// // TODO: maybe we should do more?
+// log.error("Walk the plank, matey...");
+// future = null;
+// //FIXME
+// //batchService.removeIntentOperations(data);
+// }
+// }
+//
+// // TODO: better naming
+// private class IntentBatchProcessFutures extends IntentBatchApplyFirst {
+//
+// IntentBatchProcessFutures(Collection<IntentData> operations, List<CompletedIntentUpdate> intentUpdates,
+// long endTime, int installAttempt, Future<CompletedBatchOperation> future) {
+// super(operations, intentUpdates, endTime, installAttempt, future);
+// }
+//
+// @Override
+// public void run() {
+// try {
+// Future<CompletedBatchOperation> future = processFutures();
+// if (future == null) {
+// // there are no outstanding batches; we are done
+// //FIXME
+// return; //?
+// //batchService.removeIntentOperations(data);
+// } else if (System.currentTimeMillis() > endTime) {
+// // - cancel current FlowRuleBatch and resubmit again
+// retry();
+// } else {
+// // we are not done yet, yield the thread by resubmitting ourselves
+// batchExecutor.submit(new IntentBatchProcessFutures(data, intentUpdates, endTime,
+// installAttempt, future));
+// }
+// } catch (Exception e) {
+// log.error("Error submitting batches:", e);
+// // FIXME incomplete Intents should be cleaned up
+// // (transition to FAILED, etc.)
+// abandonShip();
+// }
+// }
+//
+// /**
+// * Iterate through the pending futures, and remove them when they have completed.
+// */
+// private Future<CompletedBatchOperation> processFutures() {
+// try {
+// CompletedBatchOperation completed = future.get(100, TimeUnit.NANOSECONDS);
+// updateBatches(completed);
+// return applyNextBatch(intentUpdates);
+// } catch (TimeoutException | InterruptedException te) {
+// log.trace("Installation of intents are still pending: {}", data);
+// return future;
+// } catch (ExecutionException e) {
+// log.warn("Execution of batch failed: {}", data, e);
+// abandonShip();
+// return future;
+// }
+// }
+//
+// private void updateBatches(CompletedBatchOperation completed) {
+// if (completed.isSuccess()) {
+// for (CompletedIntentUpdate update : intentUpdates) {
+// update.batchSuccess();
+// }
+// } else {
+// // entire batch has been reverted...
+// log.debug("Failed items: {}", completed.failedItems());
+// log.debug("Failed ids: {}", completed.failedIds());
+//
+// for (Long id : completed.failedIds()) {
+// IntentId targetId = IntentId.valueOf(id);
+// for (CompletedIntentUpdate update : intentUpdates) {
+// for (Intent intent : update.allInstallables()) {
+// if (intent.id().equals(targetId)) {
+// update.batchFailed();
+// break;
+// }
+// }
+// }
+// // don't increment the non-failed items, as they have been reverted.
+// }
+// }
+// }
+//
+// private void retry() {
+// log.debug("Execution timed out, retrying.");
+// if (future.cancel(true)) { // cancel success; batch is reverted
+// // reset the timer
+// long timeLimit = calculateTimeoutLimit();
+// int attempts = installAttempt + 1;
+// if (attempts == MAX_ATTEMPTS) {
+// log.warn("Install request timed out: {}", data);
+// for (CompletedIntentUpdate update : intentUpdates) {
+// update.batchFailed();
+// }
+// } else if (attempts > MAX_ATTEMPTS) {
+// abandonShip();
+// return;
+// }
+// Future<CompletedBatchOperation> future = applyNextBatch(intentUpdates);
+// batchExecutor.submit(new IntentBatchProcessFutures(data, intentUpdates, timeLimit, attempts, future));
+// } else {
+// log.error("Cancelling FlowRuleBatch failed.");
+// abandonShip();
+// }
+// }
+// }
}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/WithdrawRequest.java b/core/net/src/main/java/org/onosproject/net/intent/impl/WithdrawRequest.java
index dee793b..1a2da58 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/WithdrawRequest.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/WithdrawRequest.java
@@ -15,7 +15,6 @@
*/
package org.onosproject.net.intent.impl;
-import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentData;
import java.util.Optional;
@@ -26,17 +25,20 @@
// TODO: define an interface and use it, instead of IntentManager
private final IntentManager intentManager;
- private final Intent intent;
- private final IntentData currentState;
+ private final IntentData pending;
- WithdrawRequest(IntentManager intentManager, Intent intent, IntentData currentState) {
+ WithdrawRequest(IntentManager intentManager, IntentData intentData) {
this.intentManager = checkNotNull(intentManager);
- this.intent = checkNotNull(intent);
- this.currentState = currentState;
+ this.pending = checkNotNull(intentData);
}
@Override
public Optional<IntentUpdate> execute() {
- return Optional.of(new Withdrawing(intentManager, intent, currentState.installables())); //FIXME
+ //FIXME... store hack
+ IntentData current = intentManager.store.getIntentData(pending.key());
+ //TODO perhaps we want to validate that the pending and current are the
+ // same version i.e. they are the same
+ // Note: this call is not just the symmetric version of submit
+ return Optional.of(new Withdrawing(intentManager, pending, current));
}
}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/Withdrawing.java b/core/net/src/main/java/org/onosproject/net/intent/impl/Withdrawing.java
index c1da0ad..de91bc2 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/Withdrawing.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/Withdrawing.java
@@ -15,11 +15,9 @@
*/
package org.onosproject.net.intent.impl;
-import com.google.common.collect.ImmutableList;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
-import org.onosproject.net.intent.Intent;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.intent.IntentData;
-import java.util.List;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -28,19 +26,21 @@
// TODO: define an interface and use it, instead of IntentManager
private final IntentManager intentManager;
- private final Intent intent;
- private final List<Intent> installables;
+ private final IntentData pending;
+ private final IntentData current;
- Withdrawing(IntentManager intentManager, Intent intent, List<Intent> installables) {
+ Withdrawing(IntentManager intentManager, IntentData pending, IntentData current) {
this.intentManager = checkNotNull(intentManager);
- this.intent = checkNotNull(intent);
- this.installables = ImmutableList.copyOf(installables);
+ this.pending = checkNotNull(pending);
+ this.current = checkNotNull(current);
}
@Override
public Optional<IntentUpdate> execute() {
- List<FlowRuleBatchOperation> batches = intentManager.uninstallIntent(intent, installables);
+ FlowRuleOperations flowRules
+ = intentManager.uninstallIntent(current.intent(), current.installables());
+ intentManager.flowRuleService.apply(flowRules); //FIXME
- return Optional.of(new Withdrawn(intentManager, intent, installables, batches));
+ return Optional.of(new Withdrawn(pending));
}
}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/Withdrawn.java b/core/net/src/main/java/org/onosproject/net/intent/impl/Withdrawn.java
index a313fea..6ea20ae 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/Withdrawn.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/Withdrawn.java
@@ -15,53 +15,22 @@
*/
package org.onosproject.net.intent.impl;
-import com.google.common.collect.ImmutableList;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
-import org.onosproject.net.intent.Intent;
-
-import java.util.LinkedList;
-import java.util.List;
+import org.onosproject.net.intent.IntentData;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.intent.IntentState.WITHDRAWING;
class Withdrawn implements CompletedIntentUpdate {
- // TODO: define an interface and use it, instead of IntentManager
- private final IntentManager intentManager;
- private final Intent intent;
- private final List<Intent> installables;
- private final List<FlowRuleBatchOperation> batches;
- private int currentBatch;
+ private final IntentData intentData;
- Withdrawn(IntentManager intentManager,
- Intent intent, List<Intent> installables, List<FlowRuleBatchOperation> batches) {
- this.intentManager = checkNotNull(intentManager);
- this.intent = checkNotNull(intent);
- this.installables = ImmutableList.copyOf(installables);
- this.batches = new LinkedList<>(batches);
- this.currentBatch = 0;
+ Withdrawn(IntentData intentData) {
+ this.intentData = checkNotNull(intentData);
+ this.intentData.setState(WITHDRAWING);
}
@Override
- public List<Intent> allInstallables() {
- return installables;
- }
-
- @Override
- public void batchSuccess() {
- currentBatch++;
- }
-
- @Override
- public FlowRuleBatchOperation currentBatch() {
- return currentBatch < batches.size() ? batches.get(currentBatch) : null;
- }
-
- @Override
- public void batchFailed() {
- for (int i = batches.size() - 1; i >= currentBatch; i--) {
- batches.remove(i);
- }
- batches.addAll(intentManager.uninstallIntent(intent, installables));
+ public IntentData data() {
+ return intentData;
}
}