Sho SHIMIZU
Committed by Ray Milkey

Merge IntentInstaller's role into IntentCompiler

It resolves naming mismatch in naming of IntentProcessPhases and states
handled in the phases. It is described in ONOS-1064.

- Define FlowRuleIntent that enables flow rule level operation
  as an intent.
- Remove IntentInstaller interface
- Existing installable intents such as PathIntent, LinkCollectionIntent,
  OpticalPathIntent and MplsPathIntent now become non installable intents.
  Only FlowRuleIntent is categorized as installable intent now.
- Implement intent compilers for PathIntent, LinkCollectionIntent,
  OpticalPathIntent and MplsPathIntent. They generates FlowRuleIntents.
- Write unit tests for the newly created intent compilers according to
  the intent installers' unit tests
- Remove all intent installers and their unit tests

Change-Id: I22d6c7acb65a4c066145de0018bd0727f44bd54a
Showing 47 changed files with 1261 additions and 2317 deletions
/*
* 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;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.NetworkResource;
import org.onosproject.net.flow.FlowRule;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An intent that enables to tell flow level operation.
* This instance holds a collection of flow rules that may be executed in parallel.
*/
public class FlowRuleIntent extends Intent {
private final Collection<FlowRule> flowRules;
/**
* Creates an flow rule intent with the specified flow rules to be set.
*
* @param appId application id
* @param flowRules flow rules to be set.
*/
public FlowRuleIntent(ApplicationId appId, List<FlowRule> flowRules) {
this(appId, null, flowRules, Collections.emptyList());
}
/**
* Creates an flow rule intent with the specified key, flow rules to be set, and
* required network resources.
*
* @param appId application id
* @param key key
* @param flowRules flow rules
* @param resources network resources
*/
public FlowRuleIntent(ApplicationId appId, Key key, Collection<FlowRule> flowRules,
Collection<NetworkResource> resources) {
super(appId, key, resources, DEFAULT_INTENT_PRIORITY);
this.flowRules = ImmutableList.copyOf(checkNotNull(flowRules));
}
/**
* Returns a collection of flow rules to be set.
*
* @return a collection of flow rules
*/
public Collection<FlowRule> flowRules() {
return flowRules;
}
@Override
public boolean isInstallable() {
return true;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("id", id())
.add("key", key())
.add("appId", appId())
.add("resources", resources())
.add("flowRule", flowRules)
.toString();
}
}
......@@ -45,28 +45,4 @@ public interface IntentExtensionService {
* @return the set of compiler bindings
*/
Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> getCompilers();
/**
* 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);
/**
* 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);
/**
* Returns immutable set of bindings of currently registered intent installers.
*
* @return the set of installer bindings
*/
Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> getInstallers();
}
......
......@@ -222,11 +222,6 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
}
@Override
public boolean isInstallable() {
return true;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("id", id())
......
......@@ -154,11 +154,6 @@ public final class OpticalPathIntent extends Intent {
}
@Override
public boolean isInstallable() {
return true;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("id", id())
......
......@@ -184,12 +184,6 @@ public class PathIntent extends ConnectivityIntent {
}
@Override
public boolean isInstallable() {
return true;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("id", id())
......
......@@ -37,8 +37,6 @@ public class FakeIntentManager implements TestableIntentService {
private final Set<IntentListener> listeners = new HashSet<>();
private final Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> compilers = new HashMap<>();
private final Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> installers
= new HashMap<>();
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private final List<IntentException> exceptions = new ArrayList<>();
......@@ -88,16 +86,6 @@ public class FakeIntentManager implements TestableIntentService {
return compiler;
}
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;
}
private <T extends Intent> void executeCompilingPhase(T intent) {
setState(intent, IntentState.COMPILING);
try {
......@@ -118,10 +106,6 @@ public class FakeIntentManager implements TestableIntentService {
List<Intent> installable) {
setState(intent, IntentState.INSTALLING);
try {
for (Intent ii : installable) {
registerSubclassInstallerIfNeeded(ii);
getInstaller(ii).install(ii);
}
setState(intent, IntentState.INSTALLED);
putInstallable(intent.key(), installable);
dispatch(new IntentEvent(IntentEvent.Type.INSTALLED, intent));
......@@ -136,9 +120,6 @@ public class FakeIntentManager implements TestableIntentService {
List<Intent> installable) {
setState(intent, IntentState.WITHDRAWING);
try {
for (Intent ii : installable) {
getInstaller(ii).uninstall(ii);
}
removeInstallable(intent.key());
setState(intent, IntentState.WITHDRAWN);
dispatch(new IntentEvent(IntentEvent.Type.WITHDRAWN, intent));
......@@ -263,23 +244,6 @@ public class FakeIntentManager implements TestableIntentService {
return Collections.unmodifiableMap(compilers);
}
@Override
public <T extends Intent> void registerInstaller(Class<T> cls,
IntentInstaller<T> installer) {
installers.put(cls, installer);
}
@Override
public <T extends Intent> void unregisterInstaller(Class<T> cls) {
installers.remove(cls);
}
@Override
public Map<Class<? extends Intent>,
IntentInstaller<? extends Intent>> getInstallers() {
return Collections.unmodifiableMap(installers);
}
private void registerSubclassCompilerIfNeeded(Intent intent) {
if (!compilers.containsKey(intent.getClass())) {
Class<?> cls = intent.getClass();
......@@ -296,23 +260,4 @@ public class FakeIntentManager implements TestableIntentService {
}
}
}
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();
}
}
}
}
......
......@@ -19,12 +19,10 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.flow.FlowRuleOperation;
import org.onosproject.net.resource.LinkResourceAllocations;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
......@@ -76,7 +74,6 @@ public class IntentServiceTest {
// Register a compiler and an installer both setup for success.
service.registerCompiler(TestIntent.class, new TestCompiler(new TestInstallableIntent(INSTALLABLE_IID)));
service.registerInstaller(TestInstallableIntent.class, new TestInstaller(false));
final Intent intent = new TestIntent(IID);
service.submit(intent);
......@@ -143,29 +140,6 @@ public class IntentServiceTest {
validateEvents(intent, INSTALL_REQ, FAILED);
}
@Test
public void failedInstallation() {
// Register a compiler programmed for success and installer for failure
service.registerCompiler(TestIntent.class, new TestCompiler(new TestInstallableIntent(INSTALLABLE_IID)));
service.registerInstaller(TestInstallableIntent.class, new TestInstaller(true));
// Submit an intent
final Intent intent = new TestIntent(IID);
service.submit(intent);
// Allow a small window of time until the intent is in the expected state
TestTools.assertAfter(GRACE_MS, new Runnable() {
@Override
public void run() {
assertEquals("incorrect intent state", IntentState.FAILED,
service.getIntentState(intent.key()));
}
});
// Make sure that all expected events have been emitted
validateEvents(intent, INSTALL_REQ, FAILED);
}
/**
* Validates that the test event listener has received the following events
* for the specified intent. Events received for other intents will not be
......@@ -210,23 +184,6 @@ public class IntentServiceTest {
}
@Test
public void installerBasics() {
// Make sure there are no installers
assertEquals("incorrect installer count", 0, service.getInstallers().size());
// Add an installer and make sure that it appears in the map
IntentInstaller<TestInstallableIntent> installer = new TestInstaller(false);
service.registerInstaller(TestInstallableIntent.class, installer);
assertEquals("incorrect installer", installer,
service.getInstallers().get(TestInstallableIntent.class));
// Remove the same and make sure that it no longer appears in the map
service.unregisterInstaller(TestInstallableIntent.class);
assertNull("installer should not be registered",
service.getInstallers().get(TestInstallableIntent.class));
}
@Test
public void implicitRegistration() {
// Add a compiler and make sure that it appears in the map
IntentCompiler<TestIntent> compiler = new TestCompiler(new TestSubclassInstallableIntent(INSTALLABLE_IID));
......@@ -234,13 +191,6 @@ public class IntentServiceTest {
assertEquals("incorrect compiler", compiler,
service.getCompilers().get(TestIntent.class));
// Add a installer and make sure that it appears in the map
IntentInstaller<TestInstallableIntent> installer = new TestInstaller(false);
service.registerInstaller(TestInstallableIntent.class, installer);
assertEquals("incorrect installer", installer,
service.getInstallers().get(TestInstallableIntent.class));
// Submit an intent which is a subclass of the one we registered
final Intent intent = new TestSubclassIntent(IID);
service.submit(intent);
......@@ -259,11 +209,6 @@ public class IntentServiceTest {
assertEquals("incorrect compiler", compiler,
service.getCompilers().get(TestSubclassIntent.class));
// Make sure that now we have an implicit registration of the installer
// under the intent subclass
assertEquals("incorrect installer", installer,
service.getInstallers().get(TestSubclassInstallableIntent.class));
// TODO: discuss whether or if implicit registration should require implicit unregistration
// perhaps unregister by compiler or installer itself, rather than by class would be better
}
......@@ -304,36 +249,4 @@ public class IntentServiceTest {
return compiled;
}
}
// Controllable installer
private class TestInstaller implements IntentInstaller<TestInstallableIntent> {
private final boolean fail;
TestInstaller(boolean fail) {
this.fail = fail;
}
@Override
public List<Collection<FlowRuleOperation>> install(TestInstallableIntent intent) {
if (fail) {
throw new IntentException("install failed by design");
}
return null;
}
@Override
public List<Collection<FlowRuleOperation>> uninstall(TestInstallableIntent intent) {
if (fail) {
throw new IntentException("remove failed by design");
}
return null;
}
@Override
public List<Collection<FlowRuleOperation>> replace(TestInstallableIntent intent,
TestInstallableIntent newIntent) {
return null;
}
}
}
......
......@@ -113,7 +113,7 @@ public class LinkCollectionIntentTest extends IntentTest {
final Set<Link> createdLinks = collectionIntent.links();
assertThat(createdLinks, hasSize(1));
assertThat(collectionIntent.isInstallable(), is(true));
assertThat(collectionIntent.isInstallable(), is(false));
assertThat(collectionIntent.treatment(), is(treatment));
assertThat(collectionIntent.selector(), is(selector));
assertThat(collectionIntent.ingressPoints(), is(ImmutableSet.of(ingress)));
......@@ -147,7 +147,7 @@ public class LinkCollectionIntentTest extends IntentTest {
final Set<Link> createdLinks = collectionIntent.links();
assertThat(createdLinks, hasSize(1));
assertThat(collectionIntent.isInstallable(), is(true));
assertThat(collectionIntent.isInstallable(), is(false));
assertThat(collectionIntent.treatment(), is(treatment));
assertThat(collectionIntent.selector(), is(selector));
assertThat(collectionIntent.ingressPoints(), is(ImmutableSet.of(ingress)));
......@@ -169,7 +169,7 @@ public class LinkCollectionIntentTest extends IntentTest {
final Set<Link> createdLinks = collectionIntent.links();
assertThat(createdLinks, nullValue());
assertThat(collectionIntent.isInstallable(), is(true));
assertThat(collectionIntent.isInstallable(), is(false));
assertThat(collectionIntent.treatment(), nullValue());
assertThat(collectionIntent.selector(), nullValue());
assertThat(collectionIntent.ingressPoints(), nullValue());
......
......@@ -26,15 +26,17 @@ 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.FlowRule;
import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.flow.FlowRuleOperationsContext;
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.intent.FlowRuleIntent;
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.IntentExtensionService;
import org.onosproject.net.intent.IntentInstaller;
import org.onosproject.net.intent.IntentListener;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.IntentState;
......@@ -47,6 +49,7 @@ import org.onosproject.net.intent.impl.phase.IntentWorker;
import org.slf4j.Logger;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
......@@ -60,7 +63,9 @@ import static java.util.concurrent.Executors.newFixedThreadPool;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.net.intent.IntentState.FAILED;
import static org.onosproject.net.intent.IntentState.INSTALLED;
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.onosproject.net.intent.impl.phase.IntentProcessPhase.newInitialPhase;
import static org.slf4j.LoggerFactory.getLogger;
......@@ -105,7 +110,6 @@ public class IntentManager
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();
......@@ -215,21 +219,6 @@ public class IntentManager
}
@Override
public <T extends Intent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
installerRegistry.registerInstaller(cls, installer);
}
@Override
public <T extends Intent> void unregisterInstaller(Class<T> cls) {
installerRegistry.unregisterInstaller(cls);
}
@Override
public Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> getInstallers() {
return installerRegistry.getInstallers();
}
@Override
public Iterable<Intent> getPending() {
return store.getPending();
}
......@@ -370,18 +359,92 @@ public class IntentManager
}
@Override
public FlowRuleOperations coordinate(IntentData current, IntentData pending) {
return installerRegistry.coordinate(current, pending, store, trackerService);
public void install(IntentData data) {
IntentManager.this.install(data);
}
@Override
public FlowRuleOperations uninstallCoordinate(IntentData current, IntentData pending) {
return installerRegistry.uninstallCoordinate(current, pending, store, trackerService);
public void uninstall(IntentData data) {
IntentManager.this.uninstall(data);
}
@Override
public void applyFlowRules(FlowRuleOperations flowRules) {
flowRuleService.apply(flowRules);
}
private void install(IntentData data) {
// need to consider if FlowRuleIntent is only one as installable intent or not
List<Intent> installables = data.installables();
if (!installables.stream().allMatch(x -> x instanceof FlowRuleIntent)) {
throw new IllegalStateException("installable intents must be FlowRuleIntent");
}
installables.forEach(x -> trackerService.addTrackedResources(data.key(), x.resources()));
List<Collection<FlowRule>> stages = installables.stream()
.map(x -> (FlowRuleIntent) x)
.map(FlowRuleIntent::flowRules)
.collect(Collectors.toList());
FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
for (Collection<FlowRule> rules : stages) {
rules.forEach(builder::add);
builder.newStage();
}
FlowRuleOperations operations = builder.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.debug("Completed installing: {}", data.key());
data.setState(INSTALLED);
store.write(data);
}
@Override
public void onError(FlowRuleOperations ops) {
log.warn("Failed installation: {} {} on {}", data.key(), data.intent(), ops);
data.setState(FAILED);
store.write(data);
}
});
flowRuleService.apply(operations);
}
private void uninstall(IntentData data) {
List<Intent> installables = data.installables();
if (!installables.stream().allMatch(x -> x instanceof FlowRuleIntent)) {
throw new IllegalStateException("installable intents must be FlowRuleIntent");
}
installables.forEach(x -> trackerService.removeTrackedResources(data.intent().key(), x.resources()));
List<Collection<FlowRule>> stages = installables.stream()
.map(x -> (FlowRuleIntent) x)
.map(FlowRuleIntent::flowRules)
.collect(Collectors.toList());
FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
for (Collection<FlowRule> rules : stages) {
rules.forEach(builder::remove);
builder.newStage();
}
FlowRuleOperations operations = builder.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.debug("Completed withdrawing: {}", data.key());
data.setState(WITHDRAWN);
data.setInstallables(Collections.emptyList());
store.write(data);
}
@Override
public void onError(FlowRuleOperations ops) {
log.warn("Failed withdraw: {}", data.key());
data.setState(FAILED);
store.write(data);
}
});
flowRuleService.apply(operations);
}
}
......
......@@ -15,7 +15,6 @@
*/
package org.onosproject.net.intent.impl;
import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentData;
......@@ -39,30 +38,16 @@ public interface IntentProcessor {
List<Intent> compile(Intent intent, List<Intent> previousInstallables);
/**
* Generate a {@link FlowRuleOperations} instance from the specified intent data.
* Installs an intent included in the specified intent data.
*
* @param current intent data stored in the store
* @param pending intent data being processed
* @return flow rule operations
* @param data intent data containing an intent to be installed
*/
FlowRuleOperations coordinate(IntentData current, IntentData pending);
void install(IntentData data);
/**
* Generate a {@link FlowRuleOperations} instance from the specified intent data.
* Uninstalls an intent included in the specified intent data.
*
* @param current intent data stored in the store
* @param pending intent data being processed
* @return flow rule operations
* @param data intent data containing an intent to be uninstalled
*/
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);
void uninstall(IntentData data);
}
......
/*
* 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.compiler;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.SetMultimap;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.DefaultGroupId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentCompiler;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.LinkCollectionIntent;
import org.onosproject.net.resource.LinkResourceAllocations;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Component(immediate = true)
public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollectionIntent> {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentExtensionService intentManager;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
private ApplicationId appId;
@Activate
public void activate() {
appId = coreService.registerApplication("org.onosproject.net.intent");
intentManager.registerCompiler(LinkCollectionIntent.class, this);
}
@Deactivate
public void deactivate() {
intentManager.unregisterCompiler(LinkCollectionIntent.class);
}
@Override
public List<Intent> compile(LinkCollectionIntent intent, List<Intent> installable,
Set<LinkResourceAllocations> resources) {
SetMultimap<DeviceId, PortNumber> inputPorts = HashMultimap.create();
SetMultimap<DeviceId, PortNumber> outputPorts = HashMultimap.create();
for (Link link : intent.links()) {
inputPorts.put(link.dst().deviceId(), link.dst().port());
outputPorts.put(link.src().deviceId(), link.src().port());
}
for (ConnectPoint ingressPoint : intent.ingressPoints()) {
inputPorts.put(ingressPoint.deviceId(), ingressPoint.port());
}
for (ConnectPoint egressPoint : intent.egressPoints()) {
outputPorts.put(egressPoint.deviceId(), egressPoint.port());
}
List<FlowRule> rules = new ArrayList<>();
for (DeviceId deviceId: outputPorts.keys()) {
rules.addAll(createRules(intent, deviceId, inputPorts.get(deviceId), outputPorts.get(deviceId)));
}
return Arrays.asList(new FlowRuleIntent(appId, rules));
}
private List<FlowRule> createRules(LinkCollectionIntent intent, DeviceId deviceId,
Set<PortNumber> inPorts, Set<PortNumber> outPorts) {
Set<PortNumber> ingressPorts = intent.ingressPoints().stream()
.filter(point -> point.deviceId().equals(deviceId))
.map(ConnectPoint::port)
.collect(Collectors.toSet());
TrafficTreatment.Builder defaultTreatmentBuilder = DefaultTrafficTreatment.builder();
outPorts.stream()
.forEach(defaultTreatmentBuilder::setOutput);
TrafficTreatment defaultTreatment = defaultTreatmentBuilder.build();
TrafficTreatment.Builder ingressTreatmentBuilder = DefaultTrafficTreatment.builder(intent.treatment());
outPorts.stream()
.forEach(ingressTreatmentBuilder::setOutput);
TrafficTreatment ingressTreatment = ingressTreatmentBuilder.build();
List<FlowRule> rules = new ArrayList<>(inPorts.size());
for (PortNumber inPort: inPorts) {
TrafficSelector selector = DefaultTrafficSelector.builder(intent.selector()).matchInPort(inPort).build();
TrafficTreatment treatment;
if (ingressPorts.contains(inPort)) {
treatment = ingressTreatment;
} else {
treatment = defaultTreatment;
}
DefaultFlowRule rule = new DefaultFlowRule(deviceId, selector, treatment, 123, appId,
new DefaultGroupId((short) (intent.id().fingerprint() & 0xffff)), 0, true);
rules.add(rule);
}
return rules;
}
}
/*
* Copyright 2014 Open Networking Laboratory
* 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.
......@@ -13,10 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.intent.impl.installer;
package org.onosproject.net.intent.impl.compiler;
import com.google.common.collect.ImmutableSet;
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;
......@@ -30,13 +28,14 @@ import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleOperation;
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentCompiler;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.IntentInstaller;
import org.onosproject.net.intent.OpticalPathIntent;
import org.onosproject.net.intent.impl.IntentCompilationException;
import org.onosproject.net.resource.DefaultLinkResourceRequest;
import org.onosproject.net.resource.Lambda;
import org.onosproject.net.resource.LambdaResourceAllocation;
......@@ -46,28 +45,21 @@ import org.onosproject.net.resource.LinkResourceService;
import org.onosproject.net.resource.ResourceAllocation;
import org.onosproject.net.resource.ResourceType;
import org.onosproject.net.topology.TopologyService;
import org.slf4j.Logger;
import java.util.Collection;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import static org.onosproject.net.flow.DefaultTrafficTreatment.builder;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Installer for {@link org.onosproject.net.intent.OpticalPathIntent optical path connectivity intents}.
*/
@Component(immediate = true)
public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIntent> {
private final Logger log = getLogger(getClass());
public class OpticalPathIntentCompiler implements IntentCompiler<OpticalPathIntent> {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentExtensionService intentManager;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowRuleService flowRuleService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
......@@ -83,88 +75,60 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn
@Activate
public void activate() {
appId = coreService.registerApplication("org.onosproject.net.intent");
intentManager.registerInstaller(OpticalPathIntent.class, this);
intentManager.registerCompiler(OpticalPathIntent.class, this);
}
@Deactivate
public void deactivate() {
intentManager.unregisterInstaller(OpticalPathIntent.class);
intentManager.unregisterCompiler(OpticalPathIntent.class);
}
@Override
public List<Collection<FlowRuleOperation>> install(OpticalPathIntent intent) {
public List<Intent> compile(OpticalPathIntent intent, List<Intent> installable,
Set<LinkResourceAllocations> resources) {
LinkResourceAllocations allocations = assignWavelength(intent);
return generateRules(intent, allocations, FlowRuleOperation.Type.ADD);
}
@Override
public List<Collection<FlowRuleOperation>> uninstall(OpticalPathIntent intent) {
LinkResourceAllocations allocations = resourceService.getAllocations(intent.id());
List<Collection<FlowRuleOperation>> rules = generateRules(intent, allocations, FlowRuleOperation.Type.REMOVE);
log.info("uninstall rules: {}", rules);
return rules;
}
@Override
public List<Collection<FlowRuleOperation>> replace(OpticalPathIntent oldIntent,
OpticalPathIntent newIntent) {
// FIXME: implement this
List<Collection<FlowRuleOperation>> batches = Lists.newArrayList();
batches.addAll(uninstall(oldIntent));
batches.addAll(install(newIntent));
return batches;
return Arrays.asList(new FlowRuleIntent(appId, createRules(intent, allocations)));
}
private LinkResourceAllocations assignWavelength(OpticalPathIntent intent) {
LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(),
intent.path().links())
LinkResourceRequest.Builder request = DefaultLinkResourceRequest
.builder(intent.id(), intent.path().links())
.addLambdaRequest();
LinkResourceAllocations retLambda = resourceService.requestResources(request.build());
return retLambda;
return resourceService.requestResources(request.build());
}
private List<Collection<FlowRuleOperation>> generateRules(OpticalPathIntent intent,
LinkResourceAllocations allocations,
FlowRuleOperation.Type operation) {
private List<FlowRule> createRules(OpticalPathIntent intent, LinkResourceAllocations allocations) {
TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
selectorBuilder.matchInPort(intent.src().port());
List<FlowRuleOperation> rules = Lists.newLinkedList();
List<FlowRule> rules = new LinkedList<>();
ConnectPoint prev = intent.src();
//FIXME check for null allocations
//TODO throw exception if the lambda was not assigned successfully
for (Link link : intent.path().links()) {
Lambda la = null;
for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) {
if (allocation.type() == ResourceType.LAMBDA) {
la = ((LambdaResourceAllocation) allocation).lambda();
break;
}
}
if (la == null) {
log.info("Lambda was not assigned successfully");
return null;
}
ResourceAllocation allocation = allocations.getResourceAllocation(link).stream()
.filter(x -> x.type() == ResourceType.LAMBDA)
.findFirst()
.orElseThrow(() -> new IntentCompilationException("Lambda was not assigned successfully"));
Lambda la = ((LambdaResourceAllocation) allocation).lambda();
TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
treatmentBuilder.setLambda((short) la.toInt());
treatmentBuilder.setOutput(link.src().port());
FlowRule rule = new DefaultFlowRule(prev.deviceId(),
selectorBuilder.build(),
treatmentBuilder.build(),
100,
appId,
100,
true);
selectorBuilder.build(),
treatmentBuilder.build(),
100,
appId,
100,
true);
rules.add(new FlowRuleOperation(rule, operation));
rules.add(rule);
prev = link.dst();
selectorBuilder.matchInPort(link.dst().port());
selectorBuilder.matchOpticalSignalType(SIGNAL_TYPE); //todo
selectorBuilder.matchOpticalSignalType(SIGNAL_TYPE);
selectorBuilder.matchLambda((short) la.toInt());
}
......@@ -173,15 +137,14 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn
TrafficTreatment.Builder treatmentLast = builder();
treatmentLast.setOutput(intent.dst().port());
FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
selectorBuilder.build(),
treatmentLast.build(),
100,
appId,
100,
true);
rules.add(new FlowRuleOperation(rule, operation));
//FIXME change to new api
return Lists.newArrayList(ImmutableSet.of(rules));
selectorBuilder.build(),
treatmentLast.build(),
100,
appId,
100,
true);
rules.add(rule);
return rules;
}
}
......
/*
* 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.compiler;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Link;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentCompiler;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.PathIntent;
import org.onosproject.net.resource.LinkResourceAllocations;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@Component(immediate = true)
public class PathIntentCompiler implements IntentCompiler<PathIntent> {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentExtensionService intentManager;
private ApplicationId appId;
@Activate
public void activate() {
appId = coreService.registerApplication("org.onosproject.net.intent");
intentManager.registerCompiler(PathIntent.class, this);
}
@Deactivate
public void deactivate() {
intentManager.unregisterCompiler(PathIntent.class);
}
@Override
public List<Intent> compile(PathIntent intent, List<Intent> installable,
Set<LinkResourceAllocations> resources) {
// Note: right now recompile is not considered
// TODO: implement recompile behavior
List<Link> links = intent.path().links();
List<FlowRule> rules = new ArrayList<>(links.size() - 1);
for (int i = 0; i < links.size() - 1; i++) {
ConnectPoint ingress = links.get(i).dst();
ConnectPoint egress = links.get(i + 1).src();
FlowRule rule = createFlowRule(intent.selector(), intent.treatment(), ingress, egress, isLast(links, i));
rules.add(rule);
}
return Arrays.asList(new FlowRuleIntent(appId, rules));
}
private FlowRule createFlowRule(TrafficSelector originalSelector, TrafficTreatment originalTreatment,
ConnectPoint ingress, ConnectPoint egress, boolean last) {
TrafficSelector selector = DefaultTrafficSelector.builder(originalSelector)
.matchInPort(ingress.port())
.build();
TrafficTreatment.Builder treatmentBuilder;
if (last) {
treatmentBuilder = DefaultTrafficTreatment.builder(originalTreatment);
} else {
treatmentBuilder = DefaultTrafficTreatment.builder();
}
TrafficTreatment treatment = treatmentBuilder.setOutput(egress.port()).build();
return new DefaultFlowRule(ingress.deviceId(), selector, treatment, 123, appId, 0, true);
}
private boolean isLast(List<Link> links, int i) {
return i == links.size() - 2;
}
}
/*
* Copyright 2014 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.installer;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.SetMultimap;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.DefaultGroupId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleOperation;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.IntentInstaller;
import org.onosproject.net.intent.LinkCollectionIntent;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Installer for {@link org.onosproject.net.intent.LinkCollectionIntent} path
* segment intents.
*/
@Component(immediate = true)
public class LinkCollectionIntentInstaller
implements IntentInstaller<LinkCollectionIntent> {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentExtensionService intentManager;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
private ApplicationId appId;
@Activate
public void activate() {
appId = coreService.registerApplication("org.onosproject.net.intent");
intentManager.registerInstaller(LinkCollectionIntent.class, this);
}
@Deactivate
public void deactivate() {
intentManager.unregisterInstaller(LinkCollectionIntent.class);
}
@Override
public List<Collection<FlowRuleOperation>> install(LinkCollectionIntent intent) {
return generateBatchOperations(intent, FlowRuleOperation.Type.ADD);
}
@Override
public List<Collection<FlowRuleOperation>> uninstall(LinkCollectionIntent intent) {
return generateBatchOperations(intent, FlowRuleOperation.Type.REMOVE);
}
private List<Collection<FlowRuleOperation>> generateBatchOperations(
LinkCollectionIntent intent, FlowRuleOperation.Type operation) {
//TODO do we need a set here?
SetMultimap<DeviceId, PortNumber> inputPorts = HashMultimap.create();
SetMultimap<DeviceId, PortNumber> outputPorts = HashMultimap.create();
for (Link link : intent.links()) {
inputPorts.put(link.dst().deviceId(), link.dst().port());
outputPorts.put(link.src().deviceId(), link.src().port());
}
for (ConnectPoint ingressPoint : intent.ingressPoints()) {
inputPorts.put(ingressPoint.deviceId(), ingressPoint.port());
}
for (ConnectPoint egressPoint : intent.egressPoints()) {
outputPorts.put(egressPoint.deviceId(), egressPoint.port());
}
List<FlowRuleOperation> rules = Lists.newArrayList();
outputPorts.keys().stream()
.map(deviceId -> createBatchEntries(operation,
intent, deviceId,
inputPorts.get(deviceId),
outputPorts.get(deviceId)))
.forEach(rules::addAll);
return Lists.newArrayList(ImmutableSet.of(rules));
}
@Override
public List<Collection<FlowRuleOperation>> replace(LinkCollectionIntent oldIntent,
LinkCollectionIntent newIntent) {
// FIXME: implement this in a more intelligent/less brute force way
List<Collection<FlowRuleOperation>> batches = Lists.newArrayList();
batches.addAll(uninstall(oldIntent));
batches.addAll(install(newIntent));
return batches;
}
/**
* Creates a collection of FlowRuleOperation based on the provided
* parameters.
*
* @param operation the FlowRuleOperation type to use
* @param intent the link collection intent
* @param deviceId the device ID for the flow rule
* @param inPorts the logical input ports of the flow rule
* @param outPorts the set of output ports for the flow rule
* @return a collection with the new flow rule batch entries
*/
private Collection<FlowRuleOperation> createBatchEntries(
FlowRuleOperation.Type operation,
LinkCollectionIntent intent,
DeviceId deviceId,
Set<PortNumber> inPorts,
Set<PortNumber> outPorts) {
Collection<FlowRuleOperation> result = Lists.newLinkedList();
Set<PortNumber> ingressPorts = new HashSet<PortNumber>();
//
// Collect all ingress ports for this device.
// The intent treatment is applied only on those ports.
//
for (ConnectPoint cp : intent.ingressPoints()) {
if (cp.deviceId().equals(deviceId)) {
ingressPorts.add(cp.port());
}
}
//
// Create two treatments: one for setting the output ports,
// and a second one that applies the intent treatment and sets the
// output ports.
// NOTE: The second one is created only if there are ingress ports.
//
TrafficTreatment.Builder defaultTreatmentBuilder =
DefaultTrafficTreatment.builder();
for (PortNumber outPort : outPorts) {
defaultTreatmentBuilder.setOutput(outPort);
}
TrafficTreatment defaultTreatment = defaultTreatmentBuilder.build();
TrafficTreatment intentTreatment = null;
if (!ingressPorts.isEmpty()) {
TrafficTreatment.Builder intentTreatmentBuilder =
DefaultTrafficTreatment.builder(intent.treatment());
for (PortNumber outPort : outPorts) {
intentTreatmentBuilder.setOutput(outPort);
}
intentTreatment = intentTreatmentBuilder.build();
}
for (PortNumber inPort : inPorts) {
TrafficSelector selector = DefaultTrafficSelector
.builder(intent.selector()).matchInPort(inPort).build();
TrafficTreatment treatment = defaultTreatment;
if (ingressPorts.contains(inPort)) {
// Use the intent treatment if this is ingress port
treatment = intentTreatment;
}
FlowRule rule = new DefaultFlowRule(deviceId,
selector, treatment, intent.priority(), appId,
new DefaultGroupId((short) (intent.id().fingerprint() & 0xffff)),
0, true);
result.add(new FlowRuleOperation(rule, operation));
}
return result;
}
}
/*
* Copyright 2014 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.installer;
import com.google.common.collect.ImmutableSet;
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;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.DefaultGroupId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Link;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleOperation;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.IntentInstaller;
import org.onosproject.net.intent.PathIntent;
import org.onosproject.net.resource.DefaultLinkResourceRequest;
import org.onosproject.net.resource.LinkResourceAllocations;
import org.onosproject.net.resource.LinkResourceRequest;
import org.onosproject.net.resource.LinkResourceService;
import org.slf4j.Logger;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import static org.onosproject.net.flow.DefaultTrafficTreatment.builder;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Installer for {@link PathIntent packet path connectivity intents}.
*/
@Component(immediate = true)
public class PathIntentInstaller implements IntentInstaller<PathIntent> {
private final Logger log = getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentExtensionService intentManager;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LinkResourceService resourceService;
protected ApplicationId appId;
@Activate
public void activate() {
appId = coreService.registerApplication("org.onosproject.net.intent");
intentManager.registerInstaller(PathIntent.class, this);
}
@Deactivate
public void deactivate() {
intentManager.unregisterInstaller(PathIntent.class);
}
@Override
public List<Collection<FlowRuleOperation>> install(PathIntent intent) {
LinkResourceAllocations allocations = allocateResources(intent);
TrafficSelector.Builder builder =
DefaultTrafficSelector.builder(intent.selector());
Iterator<Link> links = intent.path().links().iterator();
ConnectPoint prev = links.next().dst();
List<FlowRuleOperation> rules = Lists.newLinkedList();
// TODO Generate multiple batches
while (links.hasNext()) {
builder.matchInPort(prev.port());
Link link = links.next();
// if this is the last flow rule, apply the intent's treatments
TrafficTreatment treatment =
(links.hasNext() ? builder() : builder(intent.treatment()))
.setOutput(link.src().port()).build();
FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
builder.build(), treatment, intent.priority(),
appId,
new DefaultGroupId((short) (intent.id().fingerprint() & 0xffff)),
0, true);
rules.add(new FlowRuleOperation(rule, FlowRuleOperation.Type.ADD));
prev = link.dst();
}
return Lists.newArrayList(ImmutableSet.of(rules));
}
@Override
public List<Collection<FlowRuleOperation>> uninstall(PathIntent intent) {
deallocateResources(intent);
TrafficSelector.Builder builder =
DefaultTrafficSelector.builder(intent.selector());
Iterator<Link> links = intent.path().links().iterator();
ConnectPoint prev = links.next().dst();
List<FlowRuleOperation> rules = Lists.newLinkedList();
// TODO Generate multiple batches
while (links.hasNext()) {
builder.matchInPort(prev.port());
Link link = links.next();
// if this is the last flow rule, apply the intent's treatments
TrafficTreatment treatment =
(links.hasNext() ? builder() : builder(intent.treatment()))
.setOutput(link.src().port()).build();
FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
builder.build(), treatment, intent.priority(), appId,
new DefaultGroupId((short) (intent.id().fingerprint() & 0xffff)),
0, true);
rules.add(new FlowRuleOperation(rule, FlowRuleOperation.Type.REMOVE));
prev = link.dst();
}
// FIXME this should change to new api
return Lists.newArrayList(ImmutableSet.of(rules));
}
@Override
public List<Collection<FlowRuleOperation>> replace(PathIntent oldIntent, PathIntent newIntent) {
// FIXME: implement this
List<Collection<FlowRuleOperation>> batches = Lists.newArrayList();
batches.addAll(uninstall(oldIntent));
batches.addAll(install(newIntent));
return batches;
}
/**
* Allocate resources required for an intent.
*
* @param intent intent to allocate resource for
* @return allocated resources if any are required, null otherwise
*/
private LinkResourceAllocations allocateResources(PathIntent intent) {
LinkResourceRequest.Builder builder =
DefaultLinkResourceRequest.builder(intent.id(), intent.path().links());
for (Constraint constraint : intent.constraints()) {
builder.addConstraint(constraint);
}
LinkResourceRequest request = builder.build();
return request.resources().isEmpty() ? null : resourceService.requestResources(request);
}
/**
* Deallocate resources held by an intent.
*
* @param intent intent to deallocate resources for
*/
private void deallocateResources(PathIntent intent) {
if (intent.constraints().isEmpty()) {
return;
}
LinkResourceAllocations allocatedResources = resourceService.getAllocations(intent.id());
if (allocatedResources != null) {
resourceService.releaseResources(allocatedResources);
}
}
}
......@@ -20,14 +20,14 @@ import org.onosproject.net.intent.IntentData;
/**
* Represents a phase where the compile has failed.
*/
public class CompilingFailed extends AbstractFailed {
public class CompileFailed extends AbstractFailed {
/**
* Create an instance with the specified data.
*
* @param intentData intentData
*/
public CompilingFailed(IntentData intentData) {
public CompileFailed(IntentData intentData) {
super(intentData);
}
}
......
......@@ -15,14 +15,12 @@
*/
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.IntentProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
......@@ -35,24 +33,27 @@ final class Compiling implements IntentProcessPhase {
private static final Logger log = LoggerFactory.getLogger(Compiling.class);
private final IntentProcessor processor;
private final IntentData pending;
private final IntentData current;
Compiling(IntentProcessor processor, IntentData pending, IntentData current) {
private final IntentData data;
/**
* Creates an compiling phase.
*
* @param processor intent processor that does work for compiling
* @param data intent data containing an intent to be compiled
*/
Compiling(IntentProcessor processor, IntentData data) {
this.processor = checkNotNull(processor);
this.pending = checkNotNull(pending);
this.current = current;
this.data = checkNotNull(data);
}
@Override
public Optional<IntentProcessPhase> execute() {
try {
List<Intent> installables = (current != null) ? current.installables() : null;
pending.setInstallables(processor.compile(pending.intent(), installables));
return Optional.of(new InstallCoordinating(processor, pending, current));
data.setInstallables(processor.compile(data.intent(), null));
return Optional.of(new Installing(processor, data));
} catch (IntentException e) {
log.debug("Unable to compile intent {} due to: {}", pending.intent(), e);
return Optional.of(new CompilingFailed(pending));
log.debug("Unable to compile intent {} due to: {}", data.intent(), e);
return Optional.of(new CompileFailed(data));
}
}
......
......@@ -26,8 +26,19 @@ public abstract class FinalIntentProcessPhase implements IntentProcessPhase {
@Override
public final Optional<IntentProcessPhase> execute() {
preExecute();
return Optional.empty();
}
/**
* Executes operations that must take place before the phase starts.
*/
protected void preExecute() {}
/**
* Returns the IntentData object being acted on by this phase.
*
* @return intent data object for the phase
*/
public abstract IntentData data();
}
......
......@@ -27,18 +27,30 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
final class InstallRequest implements IntentProcessPhase {
private final IntentProcessor intentManager;
private final IntentData pending;
private final Optional<IntentData> current;
private final IntentProcessor processor;
private final IntentData data;
private final Optional<IntentData> stored;
InstallRequest(IntentProcessor processor, IntentData intentData, Optional<IntentData> current) {
this.intentManager = checkNotNull(processor);
this.pending = checkNotNull(intentData);
this.current = checkNotNull(current);
/**
* Creates an install request phase.
*
* @param processor intent processor to be passed to intent process phases
* generated after this phase
* @param intentData intent data to be processed
* @param stored intent data stored in the store
*/
InstallRequest(IntentProcessor processor, IntentData intentData, Optional<IntentData> stored) {
this.processor = checkNotNull(processor);
this.data = checkNotNull(intentData);
this.stored = checkNotNull(stored);
}
@Override
public Optional<IntentProcessPhase> execute() {
return Optional.of(new Compiling(intentManager, pending, current.orElse(null)));
if (!stored.isPresent() || stored.get().installables() == null || stored.get().installables().isEmpty()) {
return Optional.of(new Compiling(processor, data));
} else {
return Optional.of(new Recompiling(processor, data, stored.get()));
}
}
}
......
/*
* 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.phase;
import org.onosproject.net.intent.IntentData;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.intent.IntentState.INSTALLING;
/**
* Represent a phase where an intent has been installed.
*/
class Installed extends FinalIntentProcessPhase {
private final IntentData intentData;
Installed(IntentData intentData) {
this.intentData = checkNotNull(intentData);
this.intentData.setState(INSTALLING);
}
@Override
public IntentData data() {
return intentData;
}
}
......@@ -15,45 +15,39 @@
*/
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.IntentProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.intent.IntentState.INSTALLING;
/**
* Represents a phase of installing an intent with calling
* {@link org.onosproject.net.flow.FlowRuleService}.
* Represents a phase where an intent is being installed.
*/
final class Installing implements IntentProcessPhase {
private static final Logger log = LoggerFactory.getLogger(Installing.class);
class Installing extends FinalIntentProcessPhase {
private final IntentProcessor processor;
private final IntentData pending;
private final FlowRuleOperations flowRules;
Installing(IntentProcessor processor, IntentData pending, FlowRuleOperations flowRules) {
private final IntentData data;
/**
* Create an installing phase.
*
* @param processor intent processor that does work for installing
* @param data intent data containing an intent to be installed
*/
Installing(IntentProcessor processor, IntentData data) {
this.processor = checkNotNull(processor);
this.pending = checkNotNull(pending);
this.flowRules = flowRules;
this.data = checkNotNull(data);
this.data.setState(INSTALLING);
}
@Override
public void preExecute() {
processor.install(data);
}
@Override
public Optional<IntentProcessPhase> execute() {
try {
processor.applyFlowRules(flowRules);
return Optional.of(new Installed(pending));
// What kinds of exceptions are thrown by FlowRuleService.apply()?
// Is IntentException a correct exception abstraction?
} catch (IntentException e) {
log.warn("Unable to install intent {} due to: {}", pending.intent().id(), e);
return Optional.of(new InstallingFailed(pending));
}
public IntentData data() {
return data;
}
}
......
......@@ -21,7 +21,6 @@ import org.onosproject.net.intent.impl.IntentProcessor;
import java.util.Optional;
import static org.onlab.util.Tools.isNullOrEmpty;
import static org.onosproject.net.intent.IntentState.WITHDRAWN;
/**
* Represents a phase of processing an intent.
......@@ -52,7 +51,7 @@ public interface IntentProcessPhase {
return new InstallRequest(processor, data, Optional.ofNullable(current));
case WITHDRAW_REQ:
if (current == null || isNullOrEmpty(current.installables())) {
return new Withdrawn(data, WITHDRAWN);
return new Withdrawn(data);
} else {
return new WithdrawRequest(processor, data, current);
}
......@@ -60,7 +59,7 @@ public interface IntentProcessPhase {
return new PurgeRequest(data, current);
default:
// illegal state
return new CompilingFailed(data);
return new CompileFailed(data);
}
}
......
......@@ -15,19 +15,41 @@
*/
package org.onosproject.net.intent.impl.phase;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentData;
import org.onosproject.net.intent.impl.IntentProcessor;
import java.util.List;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents a phase where the withdraw has failed.
* Represents a phase where an intent is being recompiled.
*/
final class WithdrawingFailed extends AbstractFailed {
class Recompiling implements IntentProcessPhase {
private final IntentProcessor processor;
private final IntentData data;
private final IntentData stored;
/**
* Create an instance with the specified data.
* Creates a intent recompiling phase.
*
* @param intentData intentData
* @param processor intent processor that does work for recompiling
* @param data intent data containing an intent to be recompiled
* @param stored intent data stored in the store
*/
WithdrawingFailed(IntentData intentData) {
super(intentData);
Recompiling(IntentProcessor processor, IntentData data, IntentData stored) {
this.processor = checkNotNull(processor);
this.data = checkNotNull(data);
this.stored = checkNotNull(stored);
}
@Override
public Optional<IntentProcessPhase> execute() {
List<Intent> compiled = processor.compile(data.intent(), stored.installables());
data.setInstallables(compiled);
return Optional.of(new Replacing(processor, data, stored));
}
}
......
......@@ -20,14 +20,14 @@ import org.onosproject.net.intent.IntentData;
/**
* Represent a phase where the install has failed.
*/
class InstallingFailed extends AbstractFailed {
class ReplaceFailed extends AbstractFailed {
/**
* Create an instance with the specified data.
*
* @param intentData intentData
*/
InstallingFailed(IntentData intentData) {
ReplaceFailed(IntentData intentData) {
super(intentData);
}
}
......
......@@ -15,7 +15,6 @@
*/
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.IntentProcessor;
......@@ -27,33 +26,37 @@ import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents a phase to create a {@link FlowRuleOperations} instance
* with using registered intent installers.
* Represents a phase to replace an intent.
*/
final class InstallCoordinating implements IntentProcessPhase {
final class Replacing implements IntentProcessPhase {
private static final Logger log = LoggerFactory.getLogger(InstallCoordinating.class);
private static final Logger log = LoggerFactory.getLogger(Replacing.class);
private final IntentProcessor processor;
private final IntentData pending;
private final IntentData current;
InstallCoordinating(IntentProcessor processor, IntentData pending, IntentData current) {
private final IntentData data;
private final IntentData stored;
/**
* Creates a replacing phase.
*
* @param processor intent processor that does work for replacing
* @param data intent data containing an intent to be replaced
* @param stored intent data stored in the store
*/
Replacing(IntentProcessor processor, IntentData data, IntentData stored) {
this.processor = checkNotNull(processor);
this.pending = checkNotNull(pending);
this.current = current;
this.data = checkNotNull(data);
this.stored = checkNotNull(stored);
}
@Override
public Optional<IntentProcessPhase> execute() {
try {
//FIXME we orphan flow rules that are currently on the data plane
// ... should either reuse them or remove them
FlowRuleOperations flowRules = processor.coordinate(current, pending);
return Optional.of(new Installing(processor, pending, flowRules));
processor.uninstall(stored);
return Optional.of(new Installing(processor, data));
} catch (IntentException e) {
log.warn("Unable to generate a FlowRuleOperations from intent {} due to:", pending.intent().id(), e);
return Optional.of(new InstallingFailed(pending));
log.warn("Unable to generate a FlowRuleOperations from intent {} due to:", data.intent().id(), e);
return Optional.of(new ReplaceFailed(data));
}
}
}
......
/*
* 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.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.IntentProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents a phase to create a {@link FlowRuleOperations} instance
* with using registered intent installers.
*/
final class WithdrawCoordinating implements IntentProcessPhase {
private static final Logger log = LoggerFactory.getLogger(WithdrawCoordinating.class);
private final IntentProcessor processor;
private final IntentData pending;
private final IntentData current;
WithdrawCoordinating(IntentProcessor processor, IntentData pending, IntentData current) {
this.processor = checkNotNull(processor);
this.pending = checkNotNull(pending);
this.current = checkNotNull(current);
}
@Override
public Optional<IntentProcessPhase> execute() {
try {
// Note: current.installables() are not null or empty due to createIntentUpdate check
FlowRuleOperations flowRules = processor.uninstallCoordinate(current, pending);
pending.setInstallables(current.installables());
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));
}
}
}
......@@ -28,13 +28,21 @@ import static com.google.common.base.Preconditions.checkNotNull;
final class WithdrawRequest implements IntentProcessPhase {
private final IntentProcessor processor;
private final IntentData pending;
private final IntentData current;
private final IntentData data;
private final IntentData stored;
WithdrawRequest(IntentProcessor processor, IntentData intentData, IntentData current) {
/**
* Creates a withdraw request phase.
*
* @param processor intent processor to be passed to intent process phases
* generated after this phase
* @param intentData intent data to be processed
* @param stored intent data stored in the store
*/
WithdrawRequest(IntentProcessor processor, IntentData intentData, IntentData stored) {
this.processor = checkNotNull(processor);
this.pending = checkNotNull(intentData);
this.current = checkNotNull(current);
this.data = checkNotNull(intentData);
this.stored = checkNotNull(stored);
}
@Override
......@@ -42,6 +50,7 @@ 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(processor, pending, current));
data.setInstallables(stored.installables());
return Optional.of(new Withdrawing(processor, data));
}
}
......
......@@ -15,33 +15,40 @@
*/
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.IntentProcessor;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.intent.IntentState.WITHDRAWING;
/**
* Represents a phase of withdrawing an intent with calling
* {@link org.onosproject.net.flow.FlowRuleService}.
* Represents a phase where an intent is withdrawing.
*/
class Withdrawing implements IntentProcessPhase {
class Withdrawing extends FinalIntentProcessPhase {
private final IntentProcessor processor;
private final IntentData pending;
private final FlowRuleOperations flowRules;
private final IntentData data;
Withdrawing(IntentProcessor processor, IntentData pending, FlowRuleOperations flowRules) {
/**
* Creates a withdrawing phase.
*
* @param processor intent processor that does work for withdrawing
* @param data intent data containing an intent to be withdrawn
*/
Withdrawing(IntentProcessor processor, IntentData data) {
this.processor = checkNotNull(processor);
this.pending = checkNotNull(pending);
this.flowRules = checkNotNull(flowRules);
this.data = checkNotNull(data);
this.data.setState(WITHDRAWING);
}
@Override
protected void preExecute() {
processor.uninstall(data);
}
@Override
public Optional<IntentProcessPhase> execute() {
processor.applyFlowRules(flowRules);
return Optional.of(new Withdrawn(pending));
public IntentData data() {
return data;
}
}
......
......@@ -16,29 +16,29 @@
package org.onosproject.net.intent.impl.phase;
import org.onosproject.net.intent.IntentData;
import org.onosproject.net.intent.IntentState;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.intent.IntentState.WITHDRAWING;
import static org.onosproject.net.intent.IntentState.WITHDRAWN;
/**
* Represents a phase where an intent has been withdrawn.
*/
final class Withdrawn extends FinalIntentProcessPhase {
private final IntentData intentData;
private final IntentData data;
Withdrawn(IntentData intentData) {
this(intentData, WITHDRAWING);
}
Withdrawn(IntentData intentData, IntentState newState) {
this.intentData = checkNotNull(intentData);
this.intentData.setState(newState);
/**
* Create a withdrawn phase.
*
* @param data intent data containing an intent to be withdrawn
*/
Withdrawn(IntentData data) {
this.data = checkNotNull(data);
this.data.setState(WITHDRAWN);
}
@Override
public IntentData data() {
return intentData;
return data;
}
}
......
......@@ -15,6 +15,7 @@
*/
package org.onosproject.net.intent.impl;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
......@@ -34,15 +35,13 @@ import org.onosproject.core.ApplicationId;
import org.onosproject.core.impl.TestCoreManager;
import org.onosproject.event.impl.TestEventDispatcher;
import org.onosproject.net.NetworkResource;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleOperation;
import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentCompiler;
import org.onosproject.net.intent.IntentEvent;
import org.onosproject.net.intent.IntentEvent.Type;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.IntentId;
import org.onosproject.net.intent.IntentInstaller;
import org.onosproject.net.intent.IntentListener;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.IntentState;
......@@ -51,7 +50,6 @@ import org.onosproject.net.resource.LinkResourceAllocations;
import org.onosproject.store.trivial.impl.SimpleIntentStore;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
......@@ -95,7 +93,6 @@ public class IntentManagerTest {
protected IntentExtensionService extensionService;
protected TestListener listener = new TestListener();
protected TestIntentCompiler compiler = new TestIntentCompiler();
protected TestIntentInstaller installer = new TestIntentInstaller();
private static class TestListener implements IntentListener {
final Multimap<IntentEvent.Type, IntentEvent> events = HashMultimap.create();
......@@ -152,14 +149,10 @@ public class IntentManagerTest {
}
}
private static class MockInstallableIntent extends MockIntent {
public MockInstallableIntent(Long number) {
super(number);
}
private static class MockInstallableIntent extends FlowRuleIntent {
@Override
public boolean isInstallable() {
return true;
public MockInstallableIntent() {
super(APPID, Arrays.asList(new MockFlowRule(100)));
}
}
......@@ -167,7 +160,7 @@ public class IntentManagerTest {
@Override
public List<Intent> compile(MockIntent intent, List<Intent> installable,
Set<LinkResourceAllocations> resources) {
return Lists.newArrayList(new MockInstallableIntent(intent.number()));
return Lists.newArrayList(new MockInstallableIntent());
}
}
......@@ -179,53 +172,6 @@ public class IntentManagerTest {
}
}
private static class TestIntentInstaller implements IntentInstaller<MockInstallableIntent> {
@Override
public List<Collection<org.onosproject.net.flow.FlowRuleOperation>> install(MockInstallableIntent intent) {
FlowRule fr = new MockFlowRule(intent.number().intValue());
Set<FlowRuleOperation> rules = ImmutableSet.of(
new FlowRuleOperation(fr, FlowRuleOperation.Type.ADD));
return Lists.newArrayList(ImmutableSet.of(rules));
}
@Override
public List<Collection<FlowRuleOperation>> uninstall(MockInstallableIntent intent) {
FlowRule fr = new MockFlowRule(intent.number().intValue());
Set<FlowRuleOperation> rules = ImmutableSet.of(
new FlowRuleOperation(fr, FlowRuleOperation.Type.REMOVE));
return Lists.newArrayList(ImmutableSet.of(rules));
}
@Override
public List<Collection<FlowRuleOperation>> replace(MockInstallableIntent oldIntent,
MockInstallableIntent newIntent) {
FlowRule fr = new MockFlowRule(oldIntent.number().intValue());
FlowRule fr2 = new MockFlowRule(newIntent.number().intValue());
Set<FlowRuleOperation> rules = ImmutableSet.of(
new FlowRuleOperation(fr, FlowRuleOperation.Type.REMOVE),
new FlowRuleOperation(fr2, FlowRuleOperation.Type.ADD));
return Lists.newArrayList(ImmutableSet.of(rules));
}
}
private static class TestIntentErrorInstaller implements IntentInstaller<MockInstallableIntent> {
@Override
public List<Collection<FlowRuleOperation>> install(MockInstallableIntent intent) {
throw new IntentInstallationException("install() always fails");
}
@Override
public List<Collection<FlowRuleOperation>> uninstall(MockInstallableIntent intent) {
throw new IntentRemovalException("uninstall() always fails");
}
@Override
public List<Collection<FlowRuleOperation>> replace(MockInstallableIntent oldIntent,
MockInstallableIntent newIntent) {
throw new IntentInstallationException("replace() always fails");
}
}
/**
* Hamcrest matcher to check that a conllection of Intents contains an
* Intent with the specified Intent Id.
......@@ -274,7 +220,6 @@ public class IntentManagerTest {
manager.activate();
service.addListener(listener);
extensionService.registerCompiler(MockIntent.class, compiler);
extensionService.registerInstaller(MockInstallableIntent.class, installer);
assertTrue("store should be empty",
Sets.newHashSet(service.getIntents()).isEmpty());
......@@ -307,7 +252,6 @@ public class IntentManagerTest {
@After
public void tearDown() {
extensionService.unregisterCompiler(MockIntent.class);
extensionService.unregisterInstaller(MockInstallableIntent.class);
service.removeListener(listener);
manager.deactivate();
// TODO null the other refs?
......@@ -428,22 +372,6 @@ public class IntentManagerTest {
}
/**
* Tests handling of an error that is generated by the intent installer.
*/
@Test
public void errorIntentInstallFromInstaller() {
final TestIntentErrorInstaller errorInstaller = new TestIntentErrorInstaller();
extensionService.registerInstaller(MockInstallableIntent.class, errorInstaller);
MockIntent intent = new MockIntent(MockIntent.nextId());
listener.setLatch(1, Type.INSTALL_REQ);
listener.setLatch(1, Type.FAILED);
service.submit(intent);
listener.await(Type.INSTALL_REQ);
listener.await(Type.FAILED);
verifyState();
}
/**
* Tests handling a future that contains an unresolvable error as a result of
* installing an intent.
*/
......@@ -521,9 +449,6 @@ public class IntentManagerTest {
*/
@Test
public void intentWithoutInstaller() {
extensionService.unregisterInstaller(MockInstallableIntent.class);
MockIntent intent = new MockIntent(MockIntent.nextId());
listener.setLatch(1, Type.INSTALL_REQ);
listener.setLatch(1, Type.FAILED);
......
/*
* 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.compiler;
import com.google.common.collect.ImmutableSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.Link;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.LinkCollectionIntent;
import org.onosproject.net.intent.MockIdGenerator;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.PID;
import static org.onosproject.net.NetTestTools.connectPoint;
public class LinkCollectionIntentCompilerTest {
private final ApplicationId appId = new TestApplicationId("test");
private final ConnectPoint d1p1 = connectPoint("s1", 0);
private final ConnectPoint d2p0 = connectPoint("s2", 0);
private final ConnectPoint d2p1 = connectPoint("s2", 1);
private final ConnectPoint d3p1 = connectPoint("s3", 1);
private final ConnectPoint d3p0 = connectPoint("s3", 10);
private final ConnectPoint d1p0 = connectPoint("s1", 10);
private final Set<Link> links = ImmutableSet.of(
new DefaultLink(PID, d1p1, d2p0, DIRECT),
new DefaultLink(PID, d2p1, d3p1, DIRECT),
new DefaultLink(PID, d1p1, d3p1, DIRECT));
private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
private CoreService coreService;
private IntentExtensionService intentExtensionService;
private IdGenerator idGenerator = new MockIdGenerator();
private LinkCollectionIntent intent;
private LinkCollectionIntentCompiler sut;
@Before
public void setUP() {
sut = new LinkCollectionIntentCompiler();
coreService = createMock(CoreService.class);
expect(coreService.registerApplication("org.onosproject.net.intent"))
.andReturn(appId);
sut.coreService = coreService;
Intent.bindIdGenerator(idGenerator);
intent = LinkCollectionIntent.builder()
.appId(APP_ID)
.selector(selector)
.treatment(treatment)
.links(links)
.ingressPoints(ImmutableSet.of(d1p1))
.egressPoints(ImmutableSet.of(d3p1))
.build();
intentExtensionService = createMock(IntentExtensionService.class);
intentExtensionService.registerCompiler(LinkCollectionIntent.class, sut);
intentExtensionService.unregisterCompiler(LinkCollectionIntent.class);
sut.intentManager = intentExtensionService;
replay(coreService, intentExtensionService);
}
@After
public void tearDown() {
Intent.unbindIdGenerator(idGenerator);
}
@Test
public void testCompile() {
sut.activate();
List<Intent> compiled = sut.compile(intent, Collections.emptyList(), Collections.emptySet());
assertThat(compiled, hasSize(1));
Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
assertThat(rules, hasSize(links.size()));
// if not found, get() raises an exception
FlowRule rule1 = rules.stream()
.filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
.findFirst()
.get();
assertThat(rule1.selector(), is(
DefaultTrafficSelector.builder(intent.selector()).matchInPort(d1p1.port()).build()
));
assertThat(rule1.treatment(), is(
DefaultTrafficTreatment.builder(intent.treatment()).setOutput(d1p1.port()).build()
));
FlowRule rule2 = rules.stream()
.filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
.findFirst()
.get();
assertThat(rule2.selector(), is(
DefaultTrafficSelector.builder(intent.selector()).matchInPort(d2p0.port()).build()
));
assertThat(rule2.treatment(), is(
DefaultTrafficTreatment.builder().setOutput(d2p1.port()).build()
));
FlowRule rule3 = rules.stream()
.filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
.findFirst()
.get();
assertThat(rule3.selector(), is(
DefaultTrafficSelector.builder(intent.selector()).matchInPort(d3p1.port()).build()
));
assertThat(rule3.treatment(), is(
DefaultTrafficTreatment.builder().setOutput(d3p1.port()).build()
));
sut.deactivate();
}
}
/*
* 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.compiler;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.MplsLabel;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.Link;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.IntentTestsMocks;
import org.onosproject.net.intent.MockIdGenerator;
import org.onosproject.net.intent.MplsPathIntent;
import org.onosproject.store.trivial.impl.SimpleLinkStore;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.PID;
import static org.onosproject.net.NetTestTools.connectPoint;
public class MplsPathIntentCompilerTest {
private final ApplicationId appId = new TestApplicationId("test");
private final ConnectPoint d1p1 = connectPoint("s1", 0);
private final ConnectPoint d2p0 = connectPoint("s2", 0);
private final ConnectPoint d2p1 = connectPoint("s2", 1);
private final ConnectPoint d3p1 = connectPoint("s3", 1);
private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
private final Optional<MplsLabel> ingressLabel =
Optional.of(MplsLabel.mplsLabel(10));
private final Optional<MplsLabel> egressLabel =
Optional.of(MplsLabel.mplsLabel(20));
private final List<Link> links = Arrays.asList(
new DefaultLink(PID, d1p1, d2p0, DIRECT),
new DefaultLink(PID, d2p1, d3p1, DIRECT)
);
private IdGenerator idGenerator = new MockIdGenerator();
private final int hops = links.size() - 1;
private MplsPathIntent intent;
private MplsPathIntentCompiler sut;
@Before
public void setUp() {
sut = new MplsPathIntentCompiler();
CoreService coreService = createMock(CoreService.class);
expect(coreService.registerApplication("org.onosproject.net.intent"))
.andReturn(appId);
sut.coreService = coreService;
sut.linkStore = new SimpleLinkStore();
sut.resourceService = new IntentTestsMocks.MockResourceService();
Intent.bindIdGenerator(idGenerator);
intent = MplsPathIntent.builder()
.appId(APP_ID)
.selector(selector)
.treatment(treatment)
.path(new DefaultPath(PID, links, hops))
.ingressLabel(ingressLabel)
.egressLabel(egressLabel)
.priority(55)
.build();
IntentExtensionService intentExtensionService = createMock(IntentExtensionService.class);
intentExtensionService.registerCompiler(MplsPathIntent.class, sut);
intentExtensionService.unregisterCompiler(MplsPathIntent.class);
sut.intentExtensionService = intentExtensionService;
replay(coreService, intentExtensionService);
}
@After
public void tearDown() {
Intent.unbindIdGenerator(idGenerator);
}
@Test
public void testCompile() {
sut.activate();
List<Intent> compiled = sut.compile(intent, Collections.emptyList(), Collections.emptySet());
assertThat(compiled, hasSize(1));
Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
assertThat(rules, hasSize(1));
FlowRule rule = rules.stream()
.filter(x -> x.deviceId().equals(d2p0.deviceId()))
.findFirst()
.get();
assertThat(rule.deviceId(), is(d2p0.deviceId()));
sut.deactivate();
}
}
/*
* 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.compiler;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.Link;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.IntentTestsMocks;
import org.onosproject.net.intent.MockIdGenerator;
import org.onosproject.net.intent.OpticalPathIntent;
import org.onosproject.net.provider.ProviderId;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.NetTestTools.PID;
import static org.onosproject.net.NetTestTools.connectPoint;
public class OpticalPathIntentCompilerTest {
private CoreService coreService;
private IntentExtensionService intentExtensionService;
private final IdGenerator idGenerator = new MockIdGenerator();
private OpticalPathIntentCompiler sut;
private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
private final ApplicationId appId = new TestApplicationId("test");
private final ProviderId pid = new ProviderId("of", "test");
private final ConnectPoint d1p1 = connectPoint("s1", 0);
private final ConnectPoint d2p0 = connectPoint("s2", 0);
private final ConnectPoint d2p1 = connectPoint("s2", 1);
private final ConnectPoint d3p1 = connectPoint("s3", 1);
private final ConnectPoint d3p0 = connectPoint("s3", 10);
private final ConnectPoint d1p0 = connectPoint("s1", 10);
private final List<Link> links = Arrays.asList(
new DefaultLink(PID, d1p1, d2p0, DIRECT),
new DefaultLink(PID, d2p1, d3p1, DIRECT)
);
private final int hops = links.size() + 1;
private OpticalPathIntent intent;
@Before
public void setUp() {
sut = new OpticalPathIntentCompiler();
coreService = createMock(CoreService.class);
expect(coreService.registerApplication("org.onosproject.net.intent"))
.andReturn(appId);
sut.coreService = coreService;
Intent.bindIdGenerator(idGenerator);
intent = OpticalPathIntent.builder()
.appId(appId)
.src(d1p1)
.dst(d3p1)
.path(new DefaultPath(PID, links, hops))
.build();
intentExtensionService = createMock(IntentExtensionService.class);
intentExtensionService.registerCompiler(OpticalPathIntent.class, sut);
intentExtensionService.unregisterCompiler(OpticalPathIntent.class);
sut.intentManager = intentExtensionService;
sut.resourceService = new IntentTestsMocks.MockResourceService();
replay(coreService, intentExtensionService);
}
@After
public void tearDown() {
Intent.unbindIdGenerator(idGenerator);
}
@Test
public void testCompiler() {
sut.activate();
List<Intent> compiled = sut.compile(intent, Collections.emptyList(), Collections.emptySet());
assertThat(compiled, hasSize(1));
Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
rules.stream()
.filter(x -> x.deviceId().equals(d1p1.deviceId()))
.findFirst()
.get();
rules.stream()
.filter(x -> x.deviceId().equals(d2p1.deviceId()))
.findFirst()
.get();
rules.stream()
.filter(x -> x.deviceId().equals(d3p1.deviceId()))
.findFirst()
.get();
sut.deactivate();
}
}
/*
* 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.compiler;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.Link;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.MockIdGenerator;
import org.onosproject.net.intent.PathIntent;
import org.onosproject.net.provider.ProviderId;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.PID;
import static org.onosproject.net.NetTestTools.connectPoint;
/**
* Unit tests for PathIntentCompiler.
*/
public class PathIntentCompilerTest {
private CoreService coreService;
private IntentExtensionService intentExtensionService;
private IdGenerator idGenerator = new MockIdGenerator();
private PathIntentCompiler sut;
private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
private final ApplicationId appId = new TestApplicationId("test");
private final ProviderId pid = new ProviderId("of", "test");
private final ConnectPoint d1p1 = connectPoint("s1", 0);
private final ConnectPoint d2p0 = connectPoint("s2", 0);
private final ConnectPoint d2p1 = connectPoint("s2", 1);
private final ConnectPoint d3p1 = connectPoint("s3", 1);
private final ConnectPoint d3p0 = connectPoint("s3", 10);
private final ConnectPoint d1p0 = connectPoint("s1", 10);
private final List<Link> links = Arrays.asList(
createEdgeLink(d1p0, true),
new DefaultLink(PID, d1p1, d2p0, DIRECT),
new DefaultLink(PID, d2p1, d3p1, DIRECT),
createEdgeLink(d3p0, false)
);
private final int hops = links.size() - 1;
private PathIntent intent;
/**
* Configures objects used in all the test cases.
*/
@Before
public void setUp() {
sut = new PathIntentCompiler();
coreService = createMock(CoreService.class);
expect(coreService.registerApplication("org.onosproject.net.intent"))
.andReturn(appId);
sut.coreService = coreService;
Intent.bindIdGenerator(idGenerator);
intent = PathIntent.builder()
.appId(APP_ID)
.selector(selector)
.treatment(treatment)
.path(new DefaultPath(pid, links, hops))
.build();
intentExtensionService = createMock(IntentExtensionService.class);
intentExtensionService.registerCompiler(PathIntent.class, sut);
intentExtensionService.unregisterCompiler(PathIntent.class);
sut.intentManager = intentExtensionService;
replay(coreService, intentExtensionService);
}
/**
* Tears down objects used in all the test cases.
*/
@After
public void tearDown() {
Intent.unbindIdGenerator(idGenerator);
}
/**
* Tests the compilation behavior of the path intent compiler.
*/
@Test
public void testCompile() {
sut.activate();
List<Intent> compiled = sut.compile(intent, Collections.emptyList(), Collections.emptySet());
assertThat(compiled, hasSize(1));
Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
FlowRule rule1 = rules.stream()
.filter(x -> x.deviceId().equals(d1p0.deviceId()))
.findFirst()
.get();
assertThat(rule1.deviceId(), is(d1p0.deviceId()));
assertThat(rule1.selector(),
is(DefaultTrafficSelector.builder(selector).matchInPort(d1p0.port()).build()));
assertThat(rule1.treatment(),
is(DefaultTrafficTreatment.builder().setOutput(d1p1.port()).build()));
FlowRule rule2 = rules.stream()
.filter(x -> x.deviceId().equals(d2p0.deviceId()))
.findFirst()
.get();
assertThat(rule2.deviceId(), is(d2p0.deviceId()));
assertThat(rule2.selector(),
is(DefaultTrafficSelector.builder(selector).matchInPort(d2p0.port()).build()));
assertThat(rule2.treatment(),
is(DefaultTrafficTreatment.builder().setOutput(d2p1.port()).build()));
FlowRule rule3 = rules.stream()
.filter(x -> x.deviceId().equals(d3p0.deviceId()))
.findFirst()
.get();
assertThat(rule3.deviceId(), is(d3p1.deviceId()));
assertThat(rule3.selector(),
is(DefaultTrafficSelector.builder(selector).matchInPort(d3p1.port()).build()));
assertThat(rule3.treatment(),
is(DefaultTrafficTreatment.builder(treatment).setOutput(d3p0.port()).build()));
sut.deactivate();
}
}
/*
* 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.installer;
import org.junit.After;
import org.junit.Before;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.flow.FlowRuleOperation;
import org.onosproject.net.intent.FakeIntentManager;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentInstaller;
import org.onosproject.net.intent.IntentTestsMocks;
import org.onosproject.net.intent.MockIdGenerator;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.connectPoint;
/**
* Base class for intent installer tests.
*/
public class IntentInstallerTest {
/**
* Mock for core service.
*/
static class TestCoreService extends CoreServiceAdapter {
String registeredId = "";
@Override
public ApplicationId registerApplication(String identifier) {
registeredId = identifier;
return APP_ID;
}
}
/**
* Mock for intent manager service. Checks that the PathIntent
* installer installs and uninstalls properly.
*/
static class MockIntentManager extends FakeIntentManager {
boolean installerRegistered = false;
final Class expectedClass;
private MockIntentManager() {
expectedClass = null;
}
MockIntentManager(Class expectedInstaller) {
this.expectedClass = expectedInstaller;
}
@Override
public <T extends Intent> void registerInstaller(
Class<T> cls,
IntentInstaller<T> installer) {
assertThat(cls, equalTo(expectedClass));
installerRegistered = true;
}
@Override
public <T extends Intent> void unregisterInstaller(Class<T> cls) {
assertThat(cls, equalTo(expectedClass));
assertThat(installerRegistered, is(true));
}
}
CoreService testCoreService;
IdGenerator idGenerator = new MockIdGenerator();
IntentInstaller installer;
final IntentTestsMocks.MockSelector selector = new IntentTestsMocks.MockSelector();
final IntentTestsMocks.MockTreatment treatment = new IntentTestsMocks.MockTreatment();
final ConnectPoint d1p1 = connectPoint("s1", 0);
final ConnectPoint d2p0 = connectPoint("s2", 0);
final ConnectPoint d2p1 = connectPoint("s2", 1);
final ConnectPoint d3p1 = connectPoint("s3", 1);
final ConnectPoint d3p0 = connectPoint("s3", 10);
final ConnectPoint d1p0 = connectPoint("s1", 10);
/**
* Configures objects used in all the test cases.
*/
@Before
public void setUp() {
testCoreService = new TestCoreService();
Intent.bindIdGenerator(idGenerator);
}
/**
* Tears down objects used in all the test cases.
*/
@After
public void tearDown() {
Intent.unbindIdGenerator(idGenerator);
}
/**
* Checks that a flow operation contains the correct values.
*
* @param op flow rule operation to check
* @param type type the flow rule operation should have
* @param deviceId device id the flow rule operation should have
*/
void checkFlowOperation(FlowRuleOperation op,
FlowRuleOperation.Type type,
DeviceId deviceId) {
assertThat(op.type(), is(type));
assertThat(op.rule().deviceId(), equalTo(deviceId));
}
}
/*
* 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.installer;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.flow.FlowRuleOperation;
import org.onosproject.net.intent.LinkCollectionIntent;
import com.google.common.collect.ImmutableSet;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.PID;
public class LinkCollectionIntentInstallerTest extends IntentInstallerTest {
LinkCollectionIntentInstaller installer;
private final Set<Link> links = ImmutableSet.of(
new DefaultLink(PID, d1p1, d2p0, DIRECT),
new DefaultLink(PID, d2p1, d3p1, DIRECT),
new DefaultLink(PID, d1p1, d3p1, DIRECT));
private LinkCollectionIntent intent;
/**
* Configures objects used in all the test cases.
*/
@Before
public void localSetUp() {
installer = new LinkCollectionIntentInstaller();
installer.coreService = testCoreService;
installer.intentManager =
new IntentInstallerTest.MockIntentManager(LinkCollectionIntent.class);
intent = LinkCollectionIntent.builder()
.appId(APP_ID)
.selector(selector)
.treatment(treatment)
.links(links)
.ingressPoints(ImmutableSet.of(d1p1))
.egressPoints(ImmutableSet.of(d3p1))
.build();
}
private FlowRuleOperation findOperation(Collection<FlowRuleOperation> ops,
DeviceId deviceId) {
for (FlowRuleOperation op : ops) {
if (op.rule().deviceId().equals(deviceId)) {
return op;
}
}
return null;
}
/**
* Tests activation and deactivation of the installer.
*/
@Test
public void activateDeactivate() {
installer.activate();
installer.deactivate();
}
/**
* Tests installation operation of the path intent installer.
*/
@Test
public void install() {
installer.activate();
List<Collection<FlowRuleOperation>> operations =
installer.install(intent);
assertThat(operations, notNullValue());
assertThat(operations, hasSize(1));
Collection<FlowRuleOperation> flowRuleOpsCollection = operations.get(0);
assertThat(flowRuleOpsCollection, hasSize(links.size()));
FlowRuleOperation op0 = findOperation(flowRuleOpsCollection,
d1p0.deviceId());
checkFlowOperation(op0, FlowRuleOperation.Type.ADD, d1p0.deviceId());
FlowRuleOperation op1 = findOperation(flowRuleOpsCollection,
d2p0.deviceId());
checkFlowOperation(op1, FlowRuleOperation.Type.ADD, d2p0.deviceId());
FlowRuleOperation op2 = findOperation(flowRuleOpsCollection,
d3p0.deviceId());
checkFlowOperation(op2, FlowRuleOperation.Type.ADD, d3p0.deviceId());
installer.deactivate();
}
/**
* Checks the uninstall operation of the path intent installer.
*/
@Test
public void uninstall() {
installer.activate();
List<Collection<FlowRuleOperation>> operations =
installer.uninstall(intent);
assertThat(operations, notNullValue());
assertThat(operations, hasSize(1));
Collection<FlowRuleOperation> flowRuleOpsCollection = operations.get(0);
assertThat(flowRuleOpsCollection, hasSize(links.size()));
FlowRuleOperation op0 = findOperation(flowRuleOpsCollection,
d1p0.deviceId());
checkFlowOperation(op0, FlowRuleOperation.Type.REMOVE, d1p0.deviceId());
FlowRuleOperation op1 = findOperation(flowRuleOpsCollection,
d2p0.deviceId());
checkFlowOperation(op1, FlowRuleOperation.Type.REMOVE, d2p0.deviceId());
FlowRuleOperation op2 = findOperation(flowRuleOpsCollection,
d3p0.deviceId());
checkFlowOperation(op2, FlowRuleOperation.Type.REMOVE, d3p0.deviceId());
installer.deactivate();
}
}
/*
* 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.installer;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.MplsLabel;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.Link;
import org.onosproject.net.flow.FlowRuleOperation;
import org.onosproject.net.intent.IntentTestsMocks;
import org.onosproject.net.intent.MplsPathIntent;
import org.onosproject.store.trivial.impl.SimpleLinkStore;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.PID;
/**
* Unit tests for path intent installer.
*/
public class MplsPathIntentInstallerTest extends IntentInstallerTest {
MplsPathIntentInstaller installer;
private final Optional<MplsLabel> ingressLabel =
Optional.of(MplsLabel.mplsLabel(10));
private final Optional<MplsLabel> egressLabel =
Optional.of(MplsLabel.mplsLabel(20));
private final List<Link> links = Arrays.asList(
new DefaultLink(PID, d1p1, d2p0, DIRECT),
new DefaultLink(PID, d2p1, d3p1, DIRECT)
);
private final int hops = links.size() - 1;
private MplsPathIntent intent;
/**
* Configures objects used in all the test cases.
*/
@Before
public void localSetUp() {
installer = new MplsPathIntentInstaller();
installer.coreService = testCoreService;
installer.intentManager = new MockIntentManager(MplsPathIntent.class);
installer.linkStore = new SimpleLinkStore();
installer.resourceService = new IntentTestsMocks.MockResourceService();
intent = MplsPathIntent.builder()
.appId(APP_ID)
.selector(selector)
.treatment(treatment)
.path(new DefaultPath(PID, links, hops))
.ingressLabel(ingressLabel)
.egressLabel(egressLabel)
.priority(55)
.build();
}
/**
* Tests activation and deactivation of the installer.
*/
@Test
public void activateDeactivate() {
installer.activate();
installer.deactivate();
}
/**
* Tests installation operation of the MPLS path intent installer.
*/
@Test
public void install() {
installer.activate();
List<Collection<FlowRuleOperation>> operations =
installer.install(intent);
assertThat(operations, notNullValue());
assertThat(operations, hasSize(1));
Collection<FlowRuleOperation> flowRuleOpsCollection = operations.get(0);
assertThat(flowRuleOpsCollection, hasSize(hops));
FlowRuleOperation[] flowRuleOps =
flowRuleOpsCollection.toArray(new FlowRuleOperation[hops]);
FlowRuleOperation op0 = flowRuleOps[0];
checkFlowOperation(op0, FlowRuleOperation.Type.ADD, d2p0.deviceId());
installer.deactivate();
}
/**
* Checks the uninstall operation of the path intent installer.
*/
@Test
public void uninstall() {
installer.activate();
List<Collection<FlowRuleOperation>> operations =
installer.uninstall(intent);
assertThat(operations, notNullValue());
assertThat(operations, hasSize(1));
Collection<FlowRuleOperation> flowRuleOpsCollection = operations.get(0);
assertThat(flowRuleOpsCollection, hasSize(hops));
FlowRuleOperation[] flowRuleOps =
flowRuleOpsCollection.toArray(new FlowRuleOperation[hops]);
FlowRuleOperation op0 = flowRuleOps[0];
checkFlowOperation(op0, FlowRuleOperation.Type.REMOVE, d2p0.deviceId());
installer.deactivate();
}
}
/*
* 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.installer;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.Link;
import org.onosproject.net.flow.FlowRuleOperation;
import org.onosproject.net.intent.IntentTestsMocks;
import org.onosproject.net.intent.OpticalPathIntent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.PID;
public class OpticalPathIntentInstallerTest extends IntentInstallerTest {
OpticalPathIntentInstaller installer;
private final List<Link> links = Arrays.asList(
new DefaultLink(PID, d1p1, d2p0, DIRECT),
new DefaultLink(PID, d2p1, d3p1, DIRECT)
);
private final int hops = links.size() + 1;
private OpticalPathIntent intent;
/**
* Configures objects used in all the test cases.
*/
@Before
public void localSetUp() {
installer = new OpticalPathIntentInstaller();
installer.coreService = testCoreService;
installer.intentManager =
new IntentInstallerTest.MockIntentManager(OpticalPathIntent.class);
installer.resourceService = new IntentTestsMocks.MockResourceService();
intent = OpticalPathIntent.builder().appId(APP_ID)
.src(d1p1)
.dst(d3p1)
.path(new DefaultPath(PID, links, hops))
.build();
}
/**
* Tests activation and deactivation of the installer.
*/
@Test
public void activateDeactivate() {
installer.activate();
installer.deactivate();
}
/**
* Tests installation operation of the optical path intent installer.
*/
@Test
public void install() {
installer.activate();
List<Collection<FlowRuleOperation>> operations =
installer.install(intent);
assertThat(operations, notNullValue());
assertThat(operations, hasSize(1));
Collection<FlowRuleOperation> flowRuleOpsCollection = operations.get(0);
assertThat(flowRuleOpsCollection, hasSize(hops));
FlowRuleOperation[] flowRuleOps =
flowRuleOpsCollection.toArray(new FlowRuleOperation[hops]);
FlowRuleOperation op0 = flowRuleOps[0];
checkFlowOperation(op0, FlowRuleOperation.Type.ADD, d1p1.deviceId());
FlowRuleOperation op1 = flowRuleOps[1];
checkFlowOperation(op1, FlowRuleOperation.Type.ADD, d2p1.deviceId());
FlowRuleOperation op2 = flowRuleOps[2];
checkFlowOperation(op2, FlowRuleOperation.Type.ADD, d3p1.deviceId());
installer.deactivate();
}
/**
* Checks the uninstall operation of the optical path intent installer.
*/
@Test
public void uninstall() {
installer.activate();
List<Collection<FlowRuleOperation>> operations =
installer.uninstall(intent);
assertThat(operations, notNullValue());
assertThat(operations, hasSize(1));
Collection<FlowRuleOperation> flowRuleOpsCollection = operations.get(0);
assertThat(flowRuleOpsCollection, hasSize(hops));
FlowRuleOperation[] flowRuleOps =
flowRuleOpsCollection.toArray(new FlowRuleOperation[hops]);
FlowRuleOperation op0 = flowRuleOps[0];
checkFlowOperation(op0, FlowRuleOperation.Type.REMOVE, d1p1.deviceId());
FlowRuleOperation op1 = flowRuleOps[1];
checkFlowOperation(op1, FlowRuleOperation.Type.REMOVE, d2p1.deviceId());
FlowRuleOperation op2 = flowRuleOps[2];
checkFlowOperation(op2, FlowRuleOperation.Type.REMOVE, d3p1.deviceId());
installer.deactivate();
}
}
/*
* Copyright 2014 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.installer;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.Link;
import org.onosproject.net.flow.FlowRuleOperation;
import org.onosproject.net.intent.AbstractIntentTest;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.IntentTestsMocks;
import org.onosproject.net.intent.PathIntent;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.onosproject.net.intent.constraint.LambdaConstraint;
import org.onosproject.net.resource.Bandwidth;
import org.onosproject.net.resource.Lambda;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.fail;
import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.PID;
import static org.onosproject.net.NetTestTools.connectPoint;
import static org.onosproject.net.intent.IntentTestsMocks.MockResourceService.makeBandwidthResourceService;
import static org.onosproject.net.intent.IntentTestsMocks.MockResourceService.makeLambdaResourceService;
/**
* Unit tests for calculating paths for intents with constraints.
*/
public class PathConstraintCalculationTest extends AbstractIntentTest {
private final IntentTestsMocks.MockSelector selector = new IntentTestsMocks.MockSelector();
private final IntentTestsMocks.MockTreatment treatment = new IntentTestsMocks.MockTreatment();
private final ConnectPoint d1p1 = connectPoint("s1", 0);
private final ConnectPoint d2p0 = connectPoint("s2", 0);
private final ConnectPoint d2p1 = connectPoint("s2", 1);
private final ConnectPoint d3p1 = connectPoint("s3", 1);
private final ConnectPoint d3p0 = connectPoint("s3", 10);
private final ConnectPoint d1p0 = connectPoint("s1", 10);
private PathIntentInstaller sut;
@Before
public void setUpIntentInstaller() {
sut = new PathIntentInstaller();
sut.appId = APP_ID;
}
private PathIntent createPathIntent(List<Link> links, List<Constraint> constraints) {
int hops = links.size() - 1;
return PathIntent.builder()
.appId(APP_ID)
.selector(selector)
.treatment(treatment)
.path(new DefaultPath(PID, links, hops))
.constraints(constraints)
.priority(333)
.build();
}
/**
* Tests that installation of bandwidth constrained path intents are
* successful.
*/
@Test
public void testInstallBandwidthConstrainedIntentSuccess() {
final Constraint constraint = new BandwidthConstraint(Bandwidth.bps(100.0));
List<Link> links = Arrays.asList(
createEdgeLink(d1p0, true),
new DefaultLink(PID, d1p1, d2p0, DIRECT),
new DefaultLink(PID, d2p1, d3p1, DIRECT),
createEdgeLink(d3p0, false)
);
PathIntent installable = createPathIntent(links, Arrays.asList(constraint));
sut.resourceService = makeBandwidthResourceService(1000.0);
final List<Collection<FlowRuleOperation>> flowOperations = sut.install(installable);
assertThat(flowOperations, notNullValue());
assertThat(flowOperations, hasSize(1));
}
/**
* Tests that installation of bandwidth constrained path intents fail
* if there are no available resources.
*/
@Test
public void testInstallBandwidthConstrainedIntentFailure() {
final Constraint constraint = new BandwidthConstraint(Bandwidth.bps(100.0));
List<Link> links = Arrays.asList(
createEdgeLink(d1p0, true),
new DefaultLink(PID, d1p1, d2p0, DIRECT),
new DefaultLink(PID, d2p1, d3p1, DIRECT),
createEdgeLink(d3p0, false)
);
PathIntent installable = createPathIntent(links, Arrays.asList(constraint));
// Make it look like the available bandwidth was consumed
final IntentTestsMocks.MockResourceService resourceService = makeBandwidthResourceService(1000.0);
resourceService.setAvailableBandwidth(1.0);
sut.resourceService = resourceService;
try {
sut.install(installable);
fail("Bandwidth request with no available bandwidth did not fail.");
} catch (IntentTestsMocks.MockedAllocationFailure failure) {
assertThat(failure,
instanceOf(IntentTestsMocks.MockedAllocationFailure.class));
}
}
/**
* Tests that installation of lambda constrained path intents are
* successful.
*/
@Test
public void testInstallLambdaConstrainedIntentSuccess() {
final Constraint constraint = new LambdaConstraint(Lambda.valueOf(1));
List<Link> links = Arrays.asList(
createEdgeLink(d1p0, true),
new DefaultLink(PID, d1p1, d2p0, DIRECT),
new DefaultLink(PID, d2p1, d3p1, DIRECT),
createEdgeLink(d3p0, false)
);
PathIntent installable = createPathIntent(links, Arrays.asList(constraint));
sut.resourceService = makeLambdaResourceService(1);
final List<Collection<FlowRuleOperation>> flowOperations = sut.install(installable);
assertThat(flowOperations, notNullValue());
assertThat(flowOperations, hasSize(1));
}
/**
* Tests that installation of lambda constrained path intents fail
* if there are no available resources.
*/
@Test
public void testInstallLambdaConstrainedIntentFailure() {
final Constraint constraint = new LambdaConstraint(Lambda.valueOf(1));
List<Link> links = Arrays.asList(
createEdgeLink(d1p0, true),
new DefaultLink(PID, d1p1, d2p0, DIRECT),
new DefaultLink(PID, d2p1, d3p1, DIRECT),
createEdgeLink(d3p0, false)
);
PathIntent installable = createPathIntent(links, Arrays.asList(constraint));
// Make it look like the available lambda was consumed
final IntentTestsMocks.MockResourceService resourceService = makeLambdaResourceService(1);
resourceService.setAvailableLambda(0);
sut.resourceService = resourceService;
try {
sut.install(installable);
fail("Lambda request with no available lambda did not fail.");
} catch (IntentTestsMocks.MockedAllocationFailure failure) {
assertThat(failure,
instanceOf(IntentTestsMocks.MockedAllocationFailure.class));
}
}
}
/*
* 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.installer;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.Link;
import org.onosproject.net.flow.FlowRuleOperation;
import org.onosproject.net.intent.PathIntent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.PID;
/**
* Unit tests for path intent installer.
*/
public class PathIntentInstallerTest extends IntentInstallerTest {
PathIntentInstaller installer;
private final List<Link> links = Arrays.asList(
createEdgeLink(d1p0, true),
new DefaultLink(PID, d1p1, d2p0, DIRECT),
new DefaultLink(PID, d2p1, d3p1, DIRECT),
createEdgeLink(d3p0, false)
);
private final int hops = links.size() - 1;
private PathIntent intent;
/**
* Configures objects used in all the test cases.
*/
@Before
public void localSetUp() {
installer = new PathIntentInstaller();
installer.coreService = testCoreService;
installer.intentManager = new MockIntentManager(PathIntent.class);
intent = PathIntent.builder()
.appId(APP_ID)
.selector(selector)
.treatment(treatment)
.path(new DefaultPath(PID, links, hops))
.priority(77)
.build();
}
/**
* Tests activation and deactivation of the installer.
*/
@Test
public void activateDeactivate() {
installer.activate();
installer.deactivate();
}
/**
* Tests installation operation of the path intent installer.
*/
@Test
public void install() {
installer.activate();
List<Collection<FlowRuleOperation>> operations =
installer.install(intent);
assertThat(operations, notNullValue());
assertThat(operations, hasSize(1));
Collection<FlowRuleOperation> flowRuleOpsCollection = operations.get(0);
assertThat(flowRuleOpsCollection, hasSize(hops));
FlowRuleOperation[] flowRuleOps =
flowRuleOpsCollection.toArray(new FlowRuleOperation[hops]);
FlowRuleOperation op0 = flowRuleOps[0];
checkFlowOperation(op0, FlowRuleOperation.Type.ADD, d1p0.deviceId());
FlowRuleOperation op1 = flowRuleOps[1];
checkFlowOperation(op1, FlowRuleOperation.Type.ADD, d2p0.deviceId());
FlowRuleOperation op2 = flowRuleOps[2];
checkFlowOperation(op2, FlowRuleOperation.Type.ADD, d3p0.deviceId());
installer.deactivate();
}
/**
* Checks the uninstall operation of the path intent installer.
*/
@Test
public void uninstall() {
installer.activate();
List<Collection<FlowRuleOperation>> operations =
installer.uninstall(intent);
assertThat(operations, notNullValue());
assertThat(operations, hasSize(1));
Collection<FlowRuleOperation> flowRuleOpsCollection = operations.get(0);
assertThat(flowRuleOpsCollection, hasSize(hops));
FlowRuleOperation[] flowRuleOps =
flowRuleOpsCollection.toArray(new FlowRuleOperation[hops]);
FlowRuleOperation op0 = flowRuleOps[0];
checkFlowOperation(op0, FlowRuleOperation.Type.REMOVE, d1p0.deviceId());
FlowRuleOperation op1 = flowRuleOps[1];
checkFlowOperation(op1, FlowRuleOperation.Type.REMOVE, d2p0.deviceId());
FlowRuleOperation op2 = flowRuleOps[2];
checkFlowOperation(op2, FlowRuleOperation.Type.REMOVE, d3p0.deviceId());
installer.deactivate();
}
}
......@@ -121,12 +121,12 @@ public class CompilingTest {
expect(processor.compile(input, null)).andReturn(Arrays.asList(compiled));
replay(processor);
Compiling sut = new Compiling(processor, pending, null);
Compiling sut = new Compiling(processor, pending);
Optional<IntentProcessPhase> output = sut.execute();
verify(processor);
assertThat(output.get(), is(instanceOf(InstallCoordinating.class)));
assertThat(output.get(), is(instanceOf(Installing.class)));
}
/**
......@@ -139,11 +139,11 @@ public class CompilingTest {
expect(processor.compile(input, null)).andThrow(new IntentCompilationException());
replay(processor);
Compiling sut = new Compiling(processor, pending, null);
Compiling sut = new Compiling(processor, pending);
Optional<IntentProcessPhase> output = sut.execute();
verify(processor);
assertThat(output.get(), is(instanceOf(CompilingFailed.class)));
assertThat(output.get(), is(instanceOf(CompileFailed.class)));
}
}
......
/*
* 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.phase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentData;
import org.onosproject.net.intent.MockIdGenerator;
import org.onosproject.net.intent.PathIntent;
import org.onosproject.net.intent.PointToPointIntent;
import org.onosproject.net.intent.impl.IntentInstallationException;
import org.onosproject.net.intent.impl.IntentProcessor;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.store.Timestamp;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.PortNumber.portNumber;
import static org.onosproject.net.intent.IntentState.INSTALL_REQ;
/**
* Unit tests for Installing phase.
*/
public class InstallingTest {
private final ApplicationId appId = new TestApplicationId("test");
private final ProviderId pid = new ProviderId("of", "test");
private final TrafficSelector selector = DefaultTrafficSelector.emptySelector();
private final TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
private final ConnectPoint cp1 = new ConnectPoint(deviceId("1"), portNumber(1));
private final ConnectPoint cp2 = new ConnectPoint(deviceId("1"), portNumber(2));
private final ConnectPoint cp3 = new ConnectPoint(deviceId("2"), portNumber(1));
private final ConnectPoint cp4 = new ConnectPoint(deviceId("2"), portNumber(2));
private final List<Link> links = Arrays.asList(new DefaultLink(pid, cp2, cp4, DIRECT));
private final Path path = new DefaultPath(pid, links, 10);
private PointToPointIntent input;
private PathIntent compiled;
private IdGenerator idGenerator;
private IntentProcessor processor;
private Timestamp version;
@Before
public void setUp() {
processor = createMock(IntentProcessor.class);
version = createMock(Timestamp.class);
idGenerator = new MockIdGenerator();
Intent.bindIdGenerator(idGenerator);
// Intent creation should be placed after binding an ID generator
input = PointToPointIntent.builder()
.appId(appId)
.selector(selector)
.treatment(treatment)
.ingressPoint(cp1)
.egressPoint(cp3)
.build();
compiled = PathIntent.builder()
.appId(appId)
.selector(selector)
.treatment(treatment)
.path(path)
.build();
}
@After
public void tearDown() {
Intent.unbindIdGenerator(idGenerator);
}
/**
* Tests a next phase when no exception occurs.
*/
@Test
public void testMoveToNextPhaseWithoutError() {
IntentData pending = new IntentData(input, INSTALL_REQ, version);
pending.setInstallables(Arrays.asList(compiled));
FlowRuleOperations operations = createMock(FlowRuleOperations.class);
processor.applyFlowRules(operations);
replay(processor);
Installing sut = new Installing(processor, pending, operations);
Optional<IntentProcessPhase> executed = sut.execute();
verify(processor);
assertThat(executed.get(), is(instanceOf(Installed.class)));
}
/**
* Test a next phase when IntentInstallationException occurs.
*/
@Test
public void testWhenIntentInstallationExceptionOccurs() {
IntentData pending = new IntentData(input, INSTALL_REQ, version);
pending.setInstallables(Arrays.asList(compiled));
FlowRuleOperations operations = createMock(FlowRuleOperations.class);
processor.applyFlowRules(operations);
expectLastCall().andThrow(new IntentInstallationException());
replay(processor);
Installing sut = new Installing(processor, pending, operations);
Optional<IntentProcessPhase> executed = sut.execute();
verify(processor);
assertThat(executed.get(), is(instanceOf(InstallingFailed.class)));
}
}
......@@ -28,7 +28,6 @@ import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.Intent;
......@@ -46,7 +45,7 @@ import java.util.List;
import java.util.Optional;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.hamcrest.Matchers.instanceOf;
......@@ -55,12 +54,13 @@ import static org.junit.Assert.assertThat;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.PortNumber.portNumber;
import static org.onosproject.net.intent.IntentState.INSTALLED;
import static org.onosproject.net.intent.IntentState.INSTALL_REQ;
/**
* Unit tests for InstallingCoordinating phase.
*/
public class InstallCoordinatingTest {
public class ReplacingTest {
private final ApplicationId appId = new TestApplicationId("test");
private final ProviderId pid = new ProviderId("of", "test");
......@@ -120,12 +120,13 @@ public class InstallCoordinatingTest {
IntentData pending = new IntentData(input, INSTALL_REQ, version);
pending.setInstallables(Arrays.asList(compiled));
FlowRuleOperations operations = createMock(FlowRuleOperations.class);
IntentData current = new IntentData(input, INSTALLED, version);
current.setInstallables(Arrays.asList(compiled));
expect(processor.coordinate(null, pending)).andReturn(operations);
processor.uninstall(current);
replay(processor);
InstallCoordinating sut = new InstallCoordinating(processor, pending, null);
Replacing sut = new Replacing(processor, pending, current);
Optional<IntentProcessPhase> executed = sut.execute();
......@@ -141,14 +142,17 @@ public class InstallCoordinatingTest {
IntentData pending = new IntentData(input, INSTALL_REQ, version);
pending.setInstallables(Arrays.asList(compiled));
expect(processor.coordinate(null, pending)).andThrow(new IntentInstallationException());
IntentData current = new IntentData(input, INSTALLED, version);
processor.uninstall(current);
expectLastCall().andThrow(new IntentInstallationException());
replay(processor);
InstallCoordinating sut = new InstallCoordinating(processor, pending, null);
Replacing sut = new Replacing(processor, pending, current);
Optional<IntentProcessPhase> executed = sut.execute();
verify(processor);
assertThat(executed.get(), is(instanceOf(InstallingFailed.class)));
assertThat(executed.get(), is(instanceOf(ReplaceFailed.class)));
}
}
......
/*
* 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.phase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentData;
import org.onosproject.net.intent.MockIdGenerator;
import org.onosproject.net.intent.PathIntent;
import org.onosproject.net.intent.PointToPointIntent;
import org.onosproject.net.intent.impl.IntentProcessor;
import org.onosproject.net.intent.impl.IntentRemovalException;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.store.Timestamp;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.PortNumber.portNumber;
import static org.onosproject.net.intent.IntentState.INSTALLED;
import static org.onosproject.net.intent.IntentState.WITHDRAW_REQ;
/**
* Unit tests for WithdrawCoordinating phase.
*/
public class WithdrawCoordinatingTest {
private final ApplicationId appId = new TestApplicationId("test");
private final ProviderId pid = new ProviderId("of", "test");
private final TrafficSelector selector = DefaultTrafficSelector.emptySelector();
private final TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
private final ConnectPoint cp1 = new ConnectPoint(deviceId("1"), portNumber(1));
private final ConnectPoint cp2 = new ConnectPoint(deviceId("1"), portNumber(2));
private final ConnectPoint cp3 = new ConnectPoint(deviceId("2"), portNumber(1));
private final ConnectPoint cp4 = new ConnectPoint(deviceId("2"), portNumber(2));
private final List<Link> links = Arrays.asList(new DefaultLink(pid, cp2, cp4, DIRECT));
private final Path path = new DefaultPath(pid, links, 10);
private PointToPointIntent input;
private PathIntent compiled;
private IdGenerator idGenerator;
private IntentProcessor processor;
private Timestamp version;
@Before
public void setUp() {
processor = createMock(IntentProcessor.class);
version = createMock(Timestamp.class);
idGenerator = new MockIdGenerator();
Intent.bindIdGenerator(idGenerator);
// Intent creation should be placed after binding an ID generator
input = PointToPointIntent.builder()
.appId(appId)
.selector(selector)
.treatment(treatment)
.ingressPoint(cp1)
.egressPoint(cp3)
.build();
compiled = PathIntent.builder()
.appId(appId)
.selector(selector)
.treatment(treatment)
.path(path)
.build();
}
@After
public void tearDown() {
Intent.unbindIdGenerator(idGenerator);
}
/**
* Tests a next phase when no exception occurs.
*/
@Test
public void testMoveToNextPhaseWithoutError() {
IntentData pending = new IntentData(input, WITHDRAW_REQ, version);
IntentData current = new IntentData(input, INSTALLED, version);
current.setInstallables(Arrays.asList(compiled));
FlowRuleOperations operations = createMock(FlowRuleOperations.class);
expect(processor.uninstallCoordinate(current, pending)).andReturn(operations);
replay(processor);
WithdrawCoordinating sut = new WithdrawCoordinating(processor, pending, current);
Optional<IntentProcessPhase> executed = sut.execute();
verify(processor);
assertThat(executed.get(), is(instanceOf(Withdrawing.class)));
}
/**
* Tests a next phase when IntentRemovalExceptionOccurs.
*/
@Test
public void testWhenIntentRemovalExceptionOccurs() {
IntentData pending = new IntentData(input, WITHDRAW_REQ, version);
IntentData current = new IntentData(input, INSTALLED, version);
current.setInstallables(Arrays.asList(compiled));
expect(processor.uninstallCoordinate(current, pending)).andThrow(new IntentRemovalException());
replay(processor);
WithdrawCoordinating sut = new WithdrawCoordinating(processor, pending, current);
Optional<IntentProcessPhase> executed = sut.execute();
verify(processor);
assertThat(executed.get(), is(instanceOf(WithdrawingFailed.class)));
}
}
/*
* 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.phase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentData;
import org.onosproject.net.intent.MockIdGenerator;
import org.onosproject.net.intent.PathIntent;
import org.onosproject.net.intent.PointToPointIntent;
import org.onosproject.net.intent.impl.IntentProcessor;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.store.Timestamp;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.PortNumber.portNumber;
import static org.onosproject.net.intent.IntentState.INSTALLED;
import static org.onosproject.net.intent.IntentState.WITHDRAW_REQ;
/**
* Unit tests for Withdrawing phase.
*/
public class WithdrawingTest {
private final ApplicationId appId = new TestApplicationId("test");
private final ProviderId pid = new ProviderId("of", "test");
private final TrafficSelector selector = DefaultTrafficSelector.emptySelector();
private final TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
private final ConnectPoint cp1 = new ConnectPoint(deviceId("1"), portNumber(1));
private final ConnectPoint cp2 = new ConnectPoint(deviceId("1"), portNumber(2));
private final ConnectPoint cp3 = new ConnectPoint(deviceId("2"), portNumber(1));
private final ConnectPoint cp4 = new ConnectPoint(deviceId("2"), portNumber(2));
private final List<Link> links = Arrays.asList(new DefaultLink(pid, cp2, cp4, DIRECT));
private final Path path = new DefaultPath(pid, links, 10);
private PointToPointIntent input;
private PathIntent compiled;
private IdGenerator idGenerator;
private IntentProcessor processor;
private Timestamp version;
@Before
public void setUp() {
processor = createMock(IntentProcessor.class);
version = createMock(Timestamp.class);
idGenerator = new MockIdGenerator();
Intent.bindIdGenerator(idGenerator);
// Intent creation should be placed after binding an ID generator
input = PointToPointIntent.builder()
.appId(appId)
.selector(selector)
.treatment(treatment)
.ingressPoint(cp1)
.egressPoint(cp3)
.build();
compiled = PathIntent.builder()
.appId(appId)
.selector(selector)
.treatment(treatment)
.path(path)
.build();
}
@After
public void tearDown() {
Intent.unbindIdGenerator(idGenerator);
}
/**
* Tests a next phase when no exception occurs.
*/
@Test
public void testMoveToNextPhaseWithoutError() {
IntentData pending = new IntentData(input, WITHDRAW_REQ, version);
IntentData current = new IntentData(input, INSTALLED, version);
current.setInstallables(Arrays.asList(compiled));
FlowRuleOperations operations = createMock(FlowRuleOperations.class);
processor.applyFlowRules(operations);
replay(processor);
Withdrawing sut = new Withdrawing(processor, pending, operations);
Optional<IntentProcessPhase> executed = sut.execute();
verify(processor);
assertThat(executed.get(), is(instanceOf(Withdrawn.class)));
}
}