mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-23 21:31:00 +02:00
ONOS-1048 - Define interfaces instead of using IntentManager
- Define IntentProcessor interface containing methods to process an intent - Pull out IntentCompiler related tasks to CompilerRegistry - Pull out IntentInstaller related tasks to InstallerRegistry - Create an IntentProcessor subclass as inner class in IntentManager Change-Id: Ia3e8d574a1053e7ddc9b961873ef758c9e0b1b26
This commit is contained in:
parent
054da97e83
commit
b0a47d41c8
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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 com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.onosproject.net.intent.Intent;
|
||||
import org.onosproject.net.intent.IntentCompiler;
|
||||
import org.onosproject.net.intent.IntentException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
// TODO: consider a better name
|
||||
class CompilerRegistry {
|
||||
|
||||
private final ConcurrentMap<Class<? extends Intent>,
|
||||
IntentCompiler<? extends Intent>> compilers = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Registers the specified compiler for the given intent class.
|
||||
*
|
||||
* @param cls intent class
|
||||
* @param compiler intent compiler
|
||||
* @param <T> the type of intent
|
||||
*/
|
||||
public <T extends Intent> void registerCompiler(Class<T> cls, IntentCompiler<T> compiler) {
|
||||
compilers.put(cls, compiler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the compiler for the specified intent class.
|
||||
*
|
||||
* @param cls intent class
|
||||
* @param <T> the type of intent
|
||||
*/
|
||||
public <T extends Intent> void unregisterCompiler(Class<T> cls) {
|
||||
compilers.remove(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns immutable set of bindings of currently registered intent compilers.
|
||||
*
|
||||
* @return the set of compiler bindings
|
||||
*/
|
||||
public Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> getCompilers() {
|
||||
return ImmutableMap.copyOf(compilers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles an intent recursively.
|
||||
*
|
||||
* @param intent intent
|
||||
* @param previousInstallables previous intent installables
|
||||
* @return result of compilation
|
||||
*/
|
||||
List<Intent> compile(Intent intent, List<Intent> previousInstallables) {
|
||||
if (intent.isInstallable()) {
|
||||
return ImmutableList.of(intent);
|
||||
}
|
||||
|
||||
registerSubclassCompilerIfNeeded(intent);
|
||||
// FIXME: get previous resources
|
||||
List<Intent> installable = new ArrayList<>();
|
||||
for (Intent compiled : getCompiler(intent).compile(intent, previousInstallables, null)) {
|
||||
installable.addAll(compile(compiled, previousInstallables));
|
||||
}
|
||||
return installable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the corresponding intent compiler to the specified intent.
|
||||
*
|
||||
* @param intent intent
|
||||
* @param <T> the type of intent
|
||||
* @return intent compiler corresponding to the specified intent
|
||||
*/
|
||||
private <T extends Intent> IntentCompiler<T> getCompiler(T intent) {
|
||||
@SuppressWarnings("unchecked")
|
||||
IntentCompiler<T> compiler = (IntentCompiler<T>) compilers.get(intent.getClass());
|
||||
if (compiler == null) {
|
||||
throw new IntentException("no compiler for class " + intent.getClass());
|
||||
}
|
||||
return compiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an intent compiler of the specified intent if an intent compiler
|
||||
* for the intent is not registered. This method traverses the class hierarchy of
|
||||
* the intent. Once an intent compiler for a parent type is found, this method
|
||||
* registers the found intent compiler.
|
||||
*
|
||||
* @param intent intent
|
||||
*/
|
||||
private void registerSubclassCompilerIfNeeded(Intent intent) {
|
||||
if (!compilers.containsKey(intent.getClass())) {
|
||||
Class<?> cls = intent.getClass();
|
||||
while (cls != Object.class) {
|
||||
// As long as we're within the Intent class descendants
|
||||
if (Intent.class.isAssignableFrom(cls)) {
|
||||
IntentCompiler<?> compiler = compilers.get(cls);
|
||||
if (compiler != null) {
|
||||
compilers.put(intent.getClass(), compiler);
|
||||
return;
|
||||
}
|
||||
}
|
||||
cls = cls.getSuperclass();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* 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 com.google.common.collect.ImmutableMap;
|
||||
import org.onosproject.net.flow.FlowRuleOperation;
|
||||
import org.onosproject.net.flow.FlowRuleOperations;
|
||||
import org.onosproject.net.flow.FlowRuleOperationsContext;
|
||||
import org.onosproject.net.intent.Intent;
|
||||
import org.onosproject.net.intent.IntentData;
|
||||
import org.onosproject.net.intent.IntentException;
|
||||
import org.onosproject.net.intent.IntentInstaller;
|
||||
import org.onosproject.net.intent.IntentStore;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.onlab.util.Tools.isNullOrEmpty;
|
||||
import static org.onosproject.net.intent.IntentState.FAILED;
|
||||
import static org.onosproject.net.intent.IntentState.INSTALLED;
|
||||
import static org.onosproject.net.intent.IntentState.WITHDRAWN;
|
||||
|
||||
// TODO: consider a better name
|
||||
class InstallerRegistry {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(InstallerRegistry.class);
|
||||
|
||||
private final ConcurrentMap<Class<? extends Intent>,
|
||||
IntentInstaller<? extends Intent>> installers = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* Registers the specified installer for the given installable intent class.
|
||||
*
|
||||
* @param cls installable intent class
|
||||
* @param installer intent installer
|
||||
* @param <T> the type of installable intent
|
||||
*/
|
||||
<T extends Intent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
|
||||
installers.put(cls, installer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the installer for the given installable intent class.
|
||||
*
|
||||
* @param cls installable intent class
|
||||
* @param <T> the type of installable intent
|
||||
*/
|
||||
<T extends Intent> void unregisterInstaller(Class<T> cls) {
|
||||
installers.remove(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns immutable set of bindings of currently registered intent installers.
|
||||
*
|
||||
* @return the set of installer bindings
|
||||
*/
|
||||
Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> getInstallers() {
|
||||
return ImmutableMap.copyOf(installers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the corresponding intent installer to the specified installable intent.
|
||||
*
|
||||
* @param intent intent
|
||||
* @param <T> the type of installable intent
|
||||
* @return intent installer corresponding to the specified installable intent
|
||||
*/
|
||||
private <T extends Intent> IntentInstaller<T> getInstaller(T intent) {
|
||||
@SuppressWarnings("unchecked")
|
||||
IntentInstaller<T> installer = (IntentInstaller<T>) installers.get(intent.getClass());
|
||||
if (installer == null) {
|
||||
throw new IntentException("no installer for class " + intent.getClass());
|
||||
}
|
||||
return installer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an intent installer of the specified intent if an intent installer
|
||||
* for the intent is not registered. This method traverses the class hierarchy of
|
||||
* the intent. Once an intent installer for a parent type is found, this method
|
||||
* registers the found intent installer.
|
||||
*
|
||||
* @param intent intent
|
||||
*/
|
||||
private void registerSubclassInstallerIfNeeded(Intent intent) {
|
||||
if (!installers.containsKey(intent.getClass())) {
|
||||
Class<?> cls = intent.getClass();
|
||||
while (cls != Object.class) {
|
||||
// As long as we're within the Intent class descendants
|
||||
if (Intent.class.isAssignableFrom(cls)) {
|
||||
IntentInstaller<?> installer = installers.get(cls);
|
||||
if (installer != null) {
|
||||
installers.put(intent.getClass(), installer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
cls = cls.getSuperclass();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a {@link FlowRuleOperations} instance from the specified intent data.
|
||||
*
|
||||
* @param current intent data stored in the store
|
||||
* @param pending intent data being processed
|
||||
* @param store intent store saving the intent state in this method
|
||||
* @param trackerService objective tracker that is used in this method
|
||||
* @return flow rule operations
|
||||
*/
|
||||
public FlowRuleOperations coordinate(IntentData current, IntentData pending,
|
||||
IntentStore store, ObjectiveTrackerService trackerService) {
|
||||
List<Intent> oldInstallables = (current != null) ? current.installables() : null;
|
||||
List<Intent> newInstallables = pending.installables();
|
||||
|
||||
checkState(isNullOrEmpty(oldInstallables) ||
|
||||
oldInstallables.size() == newInstallables.size(),
|
||||
"Old and New Intent must have equivalent installable intents.");
|
||||
|
||||
List<List<Collection<FlowRuleOperation>>> plans = new ArrayList<>();
|
||||
for (int i = 0; i < newInstallables.size(); i++) {
|
||||
Intent newInstallable = newInstallables.get(i);
|
||||
registerSubclassInstallerIfNeeded(newInstallable);
|
||||
//TODO consider migrating installers to FlowRuleOperations
|
||||
/* FIXME
|
||||
- we need to do another pass on this method about that doesn't
|
||||
require the length of installables to be equal, and also doesn't
|
||||
depend on ordering
|
||||
- we should also reconsider when to start/stop tracking resources
|
||||
*/
|
||||
if (isNullOrEmpty(oldInstallables)) {
|
||||
plans.add(getInstaller(newInstallable).install(newInstallable));
|
||||
} else {
|
||||
Intent oldInstallable = oldInstallables.get(i);
|
||||
checkState(oldInstallable.getClass().equals(newInstallable.getClass()),
|
||||
"Installable Intent type mismatch.");
|
||||
trackerService.removeTrackedResources(pending.key(), oldInstallable.resources());
|
||||
plans.add(getInstaller(newInstallable).replace(oldInstallable, newInstallable));
|
||||
}
|
||||
trackerService.addTrackedResources(pending.key(), newInstallable.resources());
|
||||
// } catch (IntentException e) {
|
||||
// log.warn("Unable to update intent {} due to:", oldIntent.id(), e);
|
||||
// //FIXME... we failed. need to uninstall (if same) or revert (if different)
|
||||
// trackerService.removeTrackedResources(newIntent.id(), newInstallable.resources());
|
||||
// exception = e;
|
||||
// batches = uninstallIntent(oldIntent, oldInstallables);
|
||||
// }
|
||||
}
|
||||
|
||||
return merge(plans).build(new FlowRuleOperationsContext() { // TODO move this out
|
||||
@Override
|
||||
public void onSuccess(FlowRuleOperations ops) {
|
||||
log.debug("Completed installing: {}", pending.key());
|
||||
pending.setState(INSTALLED);
|
||||
store.write(pending);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(FlowRuleOperations ops) {
|
||||
log.warn("Failed installation: {} {} on {}", pending.key(),
|
||||
pending.intent(), ops);
|
||||
//TODO store.write(pending.setState(BROKEN));
|
||||
pending.setState(FAILED);
|
||||
store.write(pending);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a {@link FlowRuleOperations} instance from the specified intent data.
|
||||
*
|
||||
* @param current intent data stored in the store
|
||||
* @param pending intent date being processed
|
||||
* @param store intent store saving the intent state in this method
|
||||
* @param trackerService objective tracker that is used in this method
|
||||
* @return flow rule operations
|
||||
*/
|
||||
FlowRuleOperations uninstallCoordinate(IntentData current, IntentData pending,
|
||||
IntentStore store, ObjectiveTrackerService trackerService) {
|
||||
List<Intent> installables = current.installables();
|
||||
List<List<Collection<FlowRuleOperation>>> plans = new ArrayList<>();
|
||||
for (Intent installable : installables) {
|
||||
plans.add(getInstaller(installable).uninstall(installable));
|
||||
trackerService.removeTrackedResources(pending.key(), installable.resources());
|
||||
}
|
||||
|
||||
return merge(plans).build(new FlowRuleOperationsContext() {
|
||||
@Override
|
||||
public void onSuccess(FlowRuleOperations ops) {
|
||||
log.debug("Completed withdrawing: {}", pending.key());
|
||||
pending.setState(WITHDRAWN);
|
||||
pending.setInstallables(Collections.emptyList());
|
||||
store.write(pending);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(FlowRuleOperations ops) {
|
||||
log.warn("Failed withdraw: {}", pending.key());
|
||||
pending.setState(FAILED);
|
||||
store.write(pending);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// TODO needs tests... or maybe it's just perfect
|
||||
private FlowRuleOperations.Builder merge(List<List<Collection<FlowRuleOperation>>> plans) {
|
||||
FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
|
||||
// Build a batch one stage at a time
|
||||
for (int stageNumber = 0;; stageNumber++) {
|
||||
// Get the sub-stage from each plan (List<Set<FlowRuleOperation>)
|
||||
for (Iterator<List<Collection<FlowRuleOperation>>> itr = plans.iterator(); itr.hasNext();) {
|
||||
List<Collection<FlowRuleOperation>> plan = itr.next();
|
||||
if (plan.size() <= stageNumber) {
|
||||
// we have consumed all stages from this plan, so remove it
|
||||
itr.remove();
|
||||
continue;
|
||||
}
|
||||
// write operations from this sub-stage into the builder
|
||||
Collection<FlowRuleOperation> stage = plan.get(stageNumber);
|
||||
for (FlowRuleOperation entry : stage) {
|
||||
builder.operation(entry);
|
||||
}
|
||||
}
|
||||
// we are done with the stage, start the next one...
|
||||
if (plans.isEmpty()) {
|
||||
break; // we don't need to start a new stage, we are done.
|
||||
}
|
||||
builder.newStage();
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,6 @@
|
||||
package org.onosproject.net.intent.impl;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.apache.felix.scr.annotations.Activate;
|
||||
import org.apache.felix.scr.annotations.Component;
|
||||
import org.apache.felix.scr.annotations.Deactivate;
|
||||
@ -27,16 +26,13 @@ import org.onosproject.core.CoreService;
|
||||
import org.onosproject.core.IdGenerator;
|
||||
import org.onosproject.event.AbstractListenerRegistry;
|
||||
import org.onosproject.event.EventDeliveryService;
|
||||
import org.onosproject.net.flow.FlowRuleOperation;
|
||||
import org.onosproject.net.flow.FlowRuleOperations;
|
||||
import org.onosproject.net.flow.FlowRuleOperationsContext;
|
||||
import org.onosproject.net.flow.FlowRuleService;
|
||||
import org.onosproject.net.intent.Intent;
|
||||
import org.onosproject.net.intent.IntentBatchDelegate;
|
||||
import org.onosproject.net.intent.IntentCompiler;
|
||||
import org.onosproject.net.intent.IntentData;
|
||||
import org.onosproject.net.intent.IntentEvent;
|
||||
import org.onosproject.net.intent.IntentException;
|
||||
import org.onosproject.net.intent.IntentExtensionService;
|
||||
import org.onosproject.net.intent.IntentInstaller;
|
||||
import org.onosproject.net.intent.IntentListener;
|
||||
@ -53,29 +49,26 @@ import org.onosproject.net.intent.impl.phase.WithdrawRequest;
|
||||
import org.onosproject.net.intent.impl.phase.Withdrawn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
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 com.google.common.base.Preconditions.checkState;
|
||||
import static java.util.concurrent.Executors.newFixedThreadPool;
|
||||
import static java.util.concurrent.Executors.newSingleThreadExecutor;
|
||||
import static org.onlab.util.Tools.groupedThreads;
|
||||
import static org.onlab.util.Tools.isNullOrEmpty;
|
||||
import static org.onosproject.net.intent.IntentState.*;
|
||||
import static org.onosproject.net.intent.IntentState.FAILED;
|
||||
import static org.onosproject.net.intent.IntentState.INSTALL_REQ;
|
||||
import static org.onosproject.net.intent.IntentState.WITHDRAWN;
|
||||
import static org.onosproject.net.intent.IntentState.WITHDRAW_REQ;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
/**
|
||||
@ -95,12 +88,6 @@ public class IntentManager
|
||||
private static final EnumSet<IntentState> RECOMPILE
|
||||
= EnumSet.of(INSTALL_REQ, FAILED, WITHDRAW_REQ);
|
||||
|
||||
// Collections for compiler, installer, and listener are ONOS instance local
|
||||
private final ConcurrentMap<Class<? extends Intent>,
|
||||
IntentCompiler<? extends Intent>> compilers = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<Class<? extends Intent>,
|
||||
IntentInstaller<? extends Intent>> installers = new ConcurrentHashMap<>();
|
||||
|
||||
private final AbstractListenerRegistry<IntentEvent, IntentListener>
|
||||
listenerRegistry = new AbstractListenerRegistry<>();
|
||||
|
||||
@ -124,6 +111,9 @@ public class IntentManager
|
||||
private ExecutorService batchExecutor;
|
||||
private ExecutorService workerExecutor;
|
||||
|
||||
private final CompilerRegistry compilerRegistry = new CompilerRegistry();
|
||||
private final InstallerRegistry installerRegistry = new InstallerRegistry();
|
||||
private final InternalIntentProcessor processor = new InternalIntentProcessor();
|
||||
private final IntentStoreDelegate delegate = new InternalStoreDelegate();
|
||||
private final TopologyChangeDelegate topoDelegate = new InternalTopoChangeDelegate();
|
||||
private final IntentBatchDelegate batchDelegate = new InternalBatchDelegate();
|
||||
@ -211,259 +201,32 @@ public class IntentManager
|
||||
|
||||
@Override
|
||||
public <T extends Intent> void registerCompiler(Class<T> cls, IntentCompiler<T> compiler) {
|
||||
compilers.put(cls, compiler);
|
||||
compilerRegistry.registerCompiler(cls, compiler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Intent> void unregisterCompiler(Class<T> cls) {
|
||||
compilers.remove(cls);
|
||||
compilerRegistry.unregisterCompiler(cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> getCompilers() {
|
||||
return ImmutableMap.copyOf(compilers);
|
||||
return compilerRegistry.getCompilers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Intent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
|
||||
installers.put(cls, installer);
|
||||
installerRegistry.registerInstaller(cls, installer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Intent> void unregisterInstaller(Class<T> cls) {
|
||||
installers.remove(cls);
|
||||
installerRegistry.unregisterInstaller(cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> getInstallers() {
|
||||
return ImmutableMap.copyOf(installers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the corresponding intent compiler to the specified intent.
|
||||
*
|
||||
* @param intent intent
|
||||
* @param <T> the type of intent
|
||||
* @return intent compiler corresponding to the specified intent
|
||||
*/
|
||||
private <T extends Intent> IntentCompiler<T> getCompiler(T intent) {
|
||||
@SuppressWarnings("unchecked")
|
||||
IntentCompiler<T> compiler = (IntentCompiler<T>) compilers.get(intent.getClass());
|
||||
if (compiler == null) {
|
||||
throw new IntentException("no compiler for class " + intent.getClass());
|
||||
}
|
||||
return compiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the corresponding intent installer to the specified installable intent.
|
||||
*
|
||||
* @param intent intent
|
||||
* @param <T> the type of installable intent
|
||||
* @return intent installer corresponding to the specified installable intent
|
||||
*/
|
||||
private <T extends Intent> IntentInstaller<T> getInstaller(T intent) {
|
||||
@SuppressWarnings("unchecked")
|
||||
IntentInstaller<T> installer = (IntentInstaller<T>) installers.get(intent.getClass());
|
||||
if (installer == null) {
|
||||
throw new IntentException("no installer for class " + intent.getClass());
|
||||
}
|
||||
return installer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles an intent recursively.
|
||||
*
|
||||
* @param intent intent
|
||||
* @param previousInstallables previous intent installables
|
||||
* @return result of compilation
|
||||
*/
|
||||
// TODO: make this non-public due to short term hack for ONOS-1051
|
||||
public List<Intent> compileIntent(Intent intent, List<Intent> previousInstallables) {
|
||||
if (intent.isInstallable()) {
|
||||
return ImmutableList.of(intent);
|
||||
}
|
||||
|
||||
registerSubclassCompilerIfNeeded(intent);
|
||||
// FIXME: get previous resources
|
||||
List<Intent> installable = new ArrayList<>();
|
||||
for (Intent compiled : getCompiler(intent).compile(intent, previousInstallables, null)) {
|
||||
installable.addAll(compileIntent(compiled, previousInstallables));
|
||||
}
|
||||
return installable;
|
||||
}
|
||||
|
||||
//TODO javadoc
|
||||
//FIXME
|
||||
// TODO: make this non-public due to short term hack for ONOS-1051
|
||||
public FlowRuleOperations coordinate(IntentData current, IntentData pending) {
|
||||
List<Intent> oldInstallables = (current != null) ? current.installables() : null;
|
||||
List<Intent> newInstallables = pending.installables();
|
||||
|
||||
checkState(isNullOrEmpty(oldInstallables) ||
|
||||
oldInstallables.size() == newInstallables.size(),
|
||||
"Old and New Intent must have equivalent installable intents.");
|
||||
|
||||
List<List<Collection<FlowRuleOperation>>> plans = new ArrayList<>();
|
||||
for (int i = 0; i < newInstallables.size(); i++) {
|
||||
Intent newInstallable = newInstallables.get(i);
|
||||
registerSubclassInstallerIfNeeded(newInstallable);
|
||||
//TODO consider migrating installers to FlowRuleOperations
|
||||
/* FIXME
|
||||
- we need to do another pass on this method about that doesn't
|
||||
require the length of installables to be equal, and also doesn't
|
||||
depend on ordering
|
||||
- we should also reconsider when to start/stop tracking resources
|
||||
*/
|
||||
if (isNullOrEmpty(oldInstallables)) {
|
||||
plans.add(getInstaller(newInstallable).install(newInstallable));
|
||||
} else {
|
||||
Intent oldInstallable = oldInstallables.get(i);
|
||||
checkState(oldInstallable.getClass().equals(newInstallable.getClass()),
|
||||
"Installable Intent type mismatch.");
|
||||
trackerService.removeTrackedResources(pending.key(), oldInstallable.resources());
|
||||
plans.add(getInstaller(newInstallable).replace(oldInstallable, newInstallable));
|
||||
}
|
||||
trackerService.addTrackedResources(pending.key(), newInstallable.resources());
|
||||
// } catch (IntentException e) {
|
||||
// log.warn("Unable to update intent {} due to:", oldIntent.id(), e);
|
||||
// //FIXME... we failed. need to uninstall (if same) or revert (if different)
|
||||
// trackerService.removeTrackedResources(newIntent.id(), newInstallable.resources());
|
||||
// exception = e;
|
||||
// batches = uninstallIntent(oldIntent, oldInstallables);
|
||||
// }
|
||||
}
|
||||
|
||||
return merge(plans).build(new FlowRuleOperationsContext() { // TODO move this out
|
||||
@Override
|
||||
public void onSuccess(FlowRuleOperations ops) {
|
||||
log.debug("Completed installing: {}", pending.key());
|
||||
pending.setState(INSTALLED);
|
||||
store.write(pending);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(FlowRuleOperations ops) {
|
||||
log.warn("Failed installation: {} {} on {}", pending.key(),
|
||||
pending.intent(), ops);
|
||||
//TODO store.write(pending.setState(BROKEN));
|
||||
pending.setState(FAILED);
|
||||
store.write(pending);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a {@link FlowRuleOperations} instance from the specified intent data.
|
||||
*
|
||||
* @param current intent data stored in the store
|
||||
* @param pending intent data that is pending
|
||||
* @return flow rule operations
|
||||
*/
|
||||
// TODO: make this non-public due to short term hack for ONOS-1051
|
||||
public FlowRuleOperations uninstallCoordinate(IntentData current, IntentData pending) {
|
||||
List<Intent> installables = current.installables();
|
||||
List<List<Collection<FlowRuleOperation>>> plans = new ArrayList<>();
|
||||
for (Intent installable : installables) {
|
||||
plans.add(getInstaller(installable).uninstall(installable));
|
||||
trackerService.removeTrackedResources(pending.key(), installable.resources());
|
||||
}
|
||||
|
||||
return merge(plans).build(new FlowRuleOperationsContext() {
|
||||
@Override
|
||||
public void onSuccess(FlowRuleOperations ops) {
|
||||
log.debug("Completed withdrawing: {}", pending.key());
|
||||
pending.setState(WITHDRAWN);
|
||||
pending.setInstallables(Collections.emptyList());
|
||||
store.write(pending);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(FlowRuleOperations ops) {
|
||||
log.warn("Failed withdraw: {}", pending.key());
|
||||
pending.setState(FAILED);
|
||||
store.write(pending);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// TODO needs tests... or maybe it's just perfect
|
||||
private FlowRuleOperations.Builder merge(List<List<Collection<FlowRuleOperation>>> plans) {
|
||||
FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
|
||||
// Build a batch one stage at a time
|
||||
for (int stageNumber = 0;; stageNumber++) {
|
||||
// Get the sub-stage from each plan (List<Set<FlowRuleOperation>)
|
||||
for (Iterator<List<Collection<FlowRuleOperation>>> itr = plans.iterator(); itr.hasNext();) {
|
||||
List<Collection<FlowRuleOperation>> plan = itr.next();
|
||||
if (plan.size() <= stageNumber) {
|
||||
// we have consumed all stages from this plan, so remove it
|
||||
itr.remove();
|
||||
continue;
|
||||
}
|
||||
// write operations from this sub-stage into the builder
|
||||
Collection<FlowRuleOperation> stage = plan.get(stageNumber);
|
||||
for (FlowRuleOperation entry : stage) {
|
||||
builder.operation(entry);
|
||||
}
|
||||
}
|
||||
// we are done with the stage, start the next one...
|
||||
if (plans.isEmpty()) {
|
||||
break; // we don't need to start a new stage, we are done.
|
||||
}
|
||||
builder.newStage();
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an intent compiler of the specified intent if an intent compiler
|
||||
* for the intent is not registered. This method traverses the class hierarchy of
|
||||
* the intent. Once an intent compiler for a parent type is found, this method
|
||||
* registers the found intent compiler.
|
||||
*
|
||||
* @param intent intent
|
||||
*/
|
||||
private void registerSubclassCompilerIfNeeded(Intent intent) {
|
||||
if (!compilers.containsKey(intent.getClass())) {
|
||||
Class<?> cls = intent.getClass();
|
||||
while (cls != Object.class) {
|
||||
// As long as we're within the Intent class descendants
|
||||
if (Intent.class.isAssignableFrom(cls)) {
|
||||
IntentCompiler<?> compiler = compilers.get(cls);
|
||||
if (compiler != null) {
|
||||
compilers.put(intent.getClass(), compiler);
|
||||
return;
|
||||
}
|
||||
}
|
||||
cls = cls.getSuperclass();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an intent installer of the specified intent if an intent installer
|
||||
* for the intent is not registered. This method traverses the class hierarchy of
|
||||
* the intent. Once an intent installer for a parent type is found, this method
|
||||
* registers the found intent installer.
|
||||
*
|
||||
* @param intent intent
|
||||
*/
|
||||
private void registerSubclassInstallerIfNeeded(Intent intent) {
|
||||
if (!installers.containsKey(intent.getClass())) {
|
||||
Class<?> cls = intent.getClass();
|
||||
while (cls != Object.class) {
|
||||
// As long as we're within the Intent class descendants
|
||||
if (Intent.class.isAssignableFrom(cls)) {
|
||||
IntentInstaller<?> installer = installers.get(cls);
|
||||
if (installer != null) {
|
||||
installers.put(intent.getClass(), installer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
cls = cls.getSuperclass();
|
||||
}
|
||||
}
|
||||
return installerRegistry.getInstallers();
|
||||
}
|
||||
|
||||
// Store delegate to re-post events emitted from the store.
|
||||
@ -525,12 +288,12 @@ public class IntentManager
|
||||
IntentData current = store.getIntentData(intentData.key());
|
||||
switch (intentData.state()) {
|
||||
case INSTALL_REQ:
|
||||
return new InstallRequest(this, intentData, Optional.ofNullable(current));
|
||||
return new InstallRequest(processor, intentData, Optional.ofNullable(current));
|
||||
case WITHDRAW_REQ:
|
||||
if (current == null || isNullOrEmpty(current.installables())) {
|
||||
return new Withdrawn(intentData, WITHDRAWN);
|
||||
} else {
|
||||
return new WithdrawRequest(this, intentData, current);
|
||||
return new WithdrawRequest(processor, intentData, current);
|
||||
}
|
||||
default:
|
||||
// illegal state
|
||||
@ -648,4 +411,26 @@ public class IntentManager
|
||||
// TODO ensure that only one batch is in flight at a time
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalIntentProcessor implements IntentProcessor {
|
||||
@Override
|
||||
public List<Intent> compile(Intent intent, List<Intent> previousInstallables) {
|
||||
return compilerRegistry.compile(intent, previousInstallables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlowRuleOperations coordinate(IntentData current, IntentData pending) {
|
||||
return installerRegistry.coordinate(current, pending, store, trackerService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlowRuleOperations uninstallCoordinate(IntentData current, IntentData pending) {
|
||||
return installerRegistry.uninstallCoordinate(current, pending, store, trackerService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFlowRules(FlowRuleOperations flowRules) {
|
||||
flowRuleService.apply(flowRules);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.flow.FlowRuleOperations;
|
||||
import org.onosproject.net.intent.Intent;
|
||||
import org.onosproject.net.intent.IntentData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A collection of methods to process an intent.
|
||||
*
|
||||
* This interface is public, but intended to be used only by IntentManager and
|
||||
* IntentProcessPhase subclasses stored under phase package.
|
||||
*/
|
||||
public interface IntentProcessor {
|
||||
|
||||
/**
|
||||
* Compiles an intent recursively.
|
||||
*
|
||||
* @param intent intent
|
||||
* @param previousInstallables previous intent installables
|
||||
* @return result of compilation
|
||||
*/
|
||||
List<Intent> compile(Intent intent, List<Intent> previousInstallables);
|
||||
|
||||
/**
|
||||
* Generate a {@link FlowRuleOperations} instance from the specified intent data.
|
||||
*
|
||||
* @param current intent data stored in the store
|
||||
* @param pending intent data being processed
|
||||
* @return flow rule operations
|
||||
*/
|
||||
FlowRuleOperations coordinate(IntentData current, IntentData pending);
|
||||
|
||||
/**
|
||||
* Generate a {@link FlowRuleOperations} instance from the specified intent data.
|
||||
*
|
||||
* @param current intent data stored in the store
|
||||
* @param pending intent data being processed
|
||||
* @return flow rule operations
|
||||
*/
|
||||
FlowRuleOperations uninstallCoordinate(IntentData current, IntentData pending);
|
||||
|
||||
/**
|
||||
* Applies a batch operation of FlowRules.
|
||||
*
|
||||
* @param flowRules batch operation to apply
|
||||
*/
|
||||
// TODO: consider a better name
|
||||
// This methods gives strangeness a bit because
|
||||
// it doesn't receive/return intent related information
|
||||
void applyFlowRules(FlowRuleOperations flowRules);
|
||||
}
|
||||
@ -18,7 +18,7 @@ package org.onosproject.net.intent.impl.phase;
|
||||
import org.onosproject.net.intent.Intent;
|
||||
import org.onosproject.net.intent.IntentData;
|
||||
import org.onosproject.net.intent.IntentException;
|
||||
import org.onosproject.net.intent.impl.IntentManager;
|
||||
import org.onosproject.net.intent.impl.IntentProcessor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -34,13 +34,12 @@ final class Compiling implements IntentProcessPhase {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(Compiling.class);
|
||||
|
||||
// TODO: define an interface and use it, instead of IntentManager
|
||||
private final IntentManager intentManager;
|
||||
private final IntentProcessor processor;
|
||||
private final IntentData pending;
|
||||
private final IntentData current;
|
||||
|
||||
Compiling(IntentManager intentManager, IntentData pending, IntentData current) {
|
||||
this.intentManager = checkNotNull(intentManager);
|
||||
Compiling(IntentProcessor processor, IntentData pending, IntentData current) {
|
||||
this.processor = checkNotNull(processor);
|
||||
this.pending = checkNotNull(pending);
|
||||
this.current = current;
|
||||
}
|
||||
@ -49,11 +48,12 @@ final class Compiling implements IntentProcessPhase {
|
||||
public Optional<IntentProcessPhase> execute() {
|
||||
try {
|
||||
List<Intent> installables = (current != null) ? current.installables() : null;
|
||||
pending.setInstallables(intentManager.compileIntent(pending.intent(), installables));
|
||||
return Optional.of(new InstallCoordinating(intentManager, pending, current));
|
||||
pending.setInstallables(processor.compile(pending.intent(), installables));
|
||||
return Optional.of(new InstallCoordinating(processor, pending, current));
|
||||
} catch (IntentException e) {
|
||||
log.debug("Unable to compile intent {} due to: {}", pending.intent(), e);
|
||||
return Optional.of(new CompilingFailed(pending));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ package org.onosproject.net.intent.impl.phase;
|
||||
import org.onosproject.net.flow.FlowRuleOperations;
|
||||
import org.onosproject.net.intent.IntentData;
|
||||
import org.onosproject.net.intent.IntentException;
|
||||
import org.onosproject.net.intent.impl.IntentManager;
|
||||
import org.onosproject.net.intent.impl.IntentProcessor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -34,13 +34,13 @@ final class InstallCoordinating implements IntentProcessPhase {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(InstallCoordinating.class);
|
||||
|
||||
private final IntentManager intentManager;
|
||||
private final IntentProcessor processor;
|
||||
private final IntentData pending;
|
||||
private final IntentData current;
|
||||
|
||||
// TODO: define an interface and use it, instead of IntentManager
|
||||
InstallCoordinating(IntentManager intentManager, IntentData pending, IntentData current) {
|
||||
this.intentManager = checkNotNull(intentManager);
|
||||
InstallCoordinating(IntentProcessor processor, IntentData pending, IntentData current) {
|
||||
this.processor = checkNotNull(processor);
|
||||
this.pending = checkNotNull(pending);
|
||||
this.current = current;
|
||||
}
|
||||
@ -50,8 +50,8 @@ final class InstallCoordinating implements IntentProcessPhase {
|
||||
try {
|
||||
//FIXME we orphan flow rules that are currently on the data plane
|
||||
// ... should either reuse them or remove them
|
||||
FlowRuleOperations flowRules = intentManager.coordinate(current, pending);
|
||||
return Optional.of(new Installing(intentManager, pending, flowRules));
|
||||
FlowRuleOperations flowRules = processor.coordinate(current, pending);
|
||||
return Optional.of(new Installing(processor, pending, flowRules));
|
||||
} catch (IntentException e) {
|
||||
log.warn("Unable to generate a FlowRuleOperations from intent {} due to:", pending.intent().id(), e);
|
||||
return Optional.of(new InstallingFailed(pending));
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
package org.onosproject.net.intent.impl.phase;
|
||||
|
||||
import org.onosproject.net.intent.IntentData;
|
||||
import org.onosproject.net.intent.impl.IntentManager;
|
||||
import org.onosproject.net.intent.impl.IntentProcessor;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@ -27,13 +27,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
*/
|
||||
public final class InstallRequest implements IntentProcessPhase {
|
||||
|
||||
// TODO: define an interface and use it, instead of IntentManager
|
||||
private final IntentManager intentManager;
|
||||
private final IntentProcessor intentManager;
|
||||
private final IntentData pending;
|
||||
private final Optional<IntentData> current;
|
||||
|
||||
public InstallRequest(IntentManager intentManager, IntentData intentData, Optional<IntentData> current) {
|
||||
this.intentManager = checkNotNull(intentManager);
|
||||
public InstallRequest(IntentProcessor processor, IntentData intentData, Optional<IntentData> current) {
|
||||
this.intentManager = checkNotNull(processor);
|
||||
this.pending = checkNotNull(intentData);
|
||||
this.current = checkNotNull(current);
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ package org.onosproject.net.intent.impl.phase;
|
||||
import org.onosproject.net.flow.FlowRuleOperations;
|
||||
import org.onosproject.net.intent.IntentData;
|
||||
import org.onosproject.net.intent.IntentException;
|
||||
import org.onosproject.net.intent.impl.IntentManager;
|
||||
import org.onosproject.net.intent.impl.IntentProcessor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -34,13 +34,12 @@ final class Installing implements IntentProcessPhase {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(Installing.class);
|
||||
|
||||
private final IntentManager intentManager;
|
||||
private final IntentProcessor processor;
|
||||
private final IntentData pending;
|
||||
private final FlowRuleOperations flowRules;
|
||||
|
||||
// TODO: define an interface and use it, instead of IntentManager
|
||||
Installing(IntentManager intentManager, IntentData pending, FlowRuleOperations flowRules) {
|
||||
this.intentManager = checkNotNull(intentManager);
|
||||
Installing(IntentProcessor processor, IntentData pending, FlowRuleOperations flowRules) {
|
||||
this.processor = checkNotNull(processor);
|
||||
this.pending = checkNotNull(pending);
|
||||
this.flowRules = flowRules;
|
||||
}
|
||||
@ -48,7 +47,7 @@ final class Installing implements IntentProcessPhase {
|
||||
@Override
|
||||
public Optional<IntentProcessPhase> execute() {
|
||||
try {
|
||||
intentManager.flowRuleService.apply(flowRules); // FIXME we need to provide a context
|
||||
processor.applyFlowRules(flowRules);
|
||||
return Optional.of(new Installed(pending));
|
||||
// What kinds of exceptions are thrown by FlowRuleService.apply()?
|
||||
// Is IntentException a correct exception abstraction?
|
||||
|
||||
@ -18,7 +18,7 @@ package org.onosproject.net.intent.impl.phase;
|
||||
import org.onosproject.net.flow.FlowRuleOperations;
|
||||
import org.onosproject.net.intent.IntentData;
|
||||
import org.onosproject.net.intent.IntentException;
|
||||
import org.onosproject.net.intent.impl.IntentManager;
|
||||
import org.onosproject.net.intent.impl.IntentProcessor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -34,13 +34,12 @@ final class WithdrawCoordinating implements IntentProcessPhase {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(WithdrawCoordinating.class);
|
||||
|
||||
// TODO: define an interface and use it, instead of IntentManager
|
||||
private final IntentManager intentManager;
|
||||
private final IntentProcessor processor;
|
||||
private final IntentData pending;
|
||||
private final IntentData current;
|
||||
|
||||
WithdrawCoordinating(IntentManager intentManager, IntentData pending, IntentData current) {
|
||||
this.intentManager = checkNotNull(intentManager);
|
||||
WithdrawCoordinating(IntentProcessor processor, IntentData pending, IntentData current) {
|
||||
this.processor = checkNotNull(processor);
|
||||
this.pending = checkNotNull(pending);
|
||||
this.current = checkNotNull(current);
|
||||
}
|
||||
@ -49,9 +48,9 @@ final class WithdrawCoordinating implements IntentProcessPhase {
|
||||
public Optional<IntentProcessPhase> execute() {
|
||||
try {
|
||||
// Note: current.installables() are not null or empty due to createIntentUpdate check
|
||||
FlowRuleOperations flowRules = intentManager.uninstallCoordinate(current, pending);
|
||||
FlowRuleOperations flowRules = processor.uninstallCoordinate(current, pending);
|
||||
pending.setInstallables(current.installables());
|
||||
return Optional.of(new Withdrawing(intentManager, pending, flowRules));
|
||||
return Optional.of(new Withdrawing(processor, pending, flowRules));
|
||||
} catch (IntentException e) {
|
||||
log.warn("Unable to generate generate a FlowRuleOperations from intent {} due to:", pending.intent(), e);
|
||||
return Optional.of(new WithdrawingFailed(pending));
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
package org.onosproject.net.intent.impl.phase;
|
||||
|
||||
import org.onosproject.net.intent.IntentData;
|
||||
import org.onosproject.net.intent.impl.IntentManager;
|
||||
import org.onosproject.net.intent.impl.IntentProcessor;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@ -27,13 +27,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
*/
|
||||
public final class WithdrawRequest implements IntentProcessPhase {
|
||||
|
||||
// TODO: define an interface and use it, instead of IntentManager
|
||||
private final IntentManager intentManager;
|
||||
private final IntentProcessor processor;
|
||||
private final IntentData pending;
|
||||
private final IntentData current;
|
||||
|
||||
public WithdrawRequest(IntentManager intentManager, IntentData intentData, IntentData current) {
|
||||
this.intentManager = checkNotNull(intentManager);
|
||||
public WithdrawRequest(IntentProcessor processor, IntentData intentData, IntentData current) {
|
||||
this.processor = checkNotNull(processor);
|
||||
this.pending = checkNotNull(intentData);
|
||||
this.current = checkNotNull(current);
|
||||
}
|
||||
@ -43,6 +42,6 @@ public final class WithdrawRequest implements IntentProcessPhase {
|
||||
//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 WithdrawCoordinating(intentManager, pending, current));
|
||||
return Optional.of(new WithdrawCoordinating(processor, pending, current));
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ package org.onosproject.net.intent.impl.phase;
|
||||
|
||||
import org.onosproject.net.flow.FlowRuleOperations;
|
||||
import org.onosproject.net.intent.IntentData;
|
||||
import org.onosproject.net.intent.impl.IntentManager;
|
||||
import org.onosproject.net.intent.impl.IntentProcessor;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@ -29,20 +29,19 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
*/
|
||||
class Withdrawing implements IntentProcessPhase {
|
||||
|
||||
// TODO: define an interface and use it, instead of IntentManager
|
||||
private final IntentManager intentManager;
|
||||
private final IntentProcessor processor;
|
||||
private final IntentData pending;
|
||||
private final FlowRuleOperations flowRules;
|
||||
|
||||
Withdrawing(IntentManager intentManager, IntentData pending, FlowRuleOperations flowRules) {
|
||||
this.intentManager = checkNotNull(intentManager);
|
||||
Withdrawing(IntentProcessor processor, IntentData pending, FlowRuleOperations flowRules) {
|
||||
this.processor = checkNotNull(processor);
|
||||
this.pending = checkNotNull(pending);
|
||||
this.flowRules = checkNotNull(flowRules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IntentProcessPhase> execute() {
|
||||
intentManager.flowRuleService.apply(flowRules);
|
||||
processor.applyFlowRules(flowRules);
|
||||
return Optional.of(new Withdrawn(pending));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user