Ray Milkey
Committed by Brian O'Connor

Add path intent compiler that generates flow objective intents

Change-Id: I11bee398d927f0e3f32b7cf81d98cfe5816db477
......@@ -17,19 +17,25 @@
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.DeviceId;
import org.onosproject.net.NetworkResource;
import org.onosproject.net.flowobjective.Objective;
import java.util.Collection;
import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
/**
* Intent expressed as (and backed by) a collection of flow objectives through
* which the intent is to be accomplished.
*/
public class FlowObjectiveIntent extends Intent {
public final class FlowObjectiveIntent extends Intent {
private final Collection<Objective> objectives;
private final List<Objective> objectives;
private final List<DeviceId> devices;
/**
* Constructor for serialization.
......@@ -37,6 +43,7 @@ public class FlowObjectiveIntent extends Intent {
protected FlowObjectiveIntent() {
super();
this.objectives = null;
this.devices = null;
}
/**
......@@ -44,13 +51,15 @@ public class FlowObjectiveIntent extends Intent {
* resources.
*
* @param appId application id
* @param devices list of target devices; in same order as the objectives
* @param objectives backing flow objectives
* @param resources backing network resources
*/
public FlowObjectiveIntent(ApplicationId appId,
Collection<Objective> objectives,
List<DeviceId> devices,
List<Objective> objectives,
Collection<NetworkResource> resources) {
this(appId, null, objectives, resources);
this(appId, null, devices, objectives, resources);
}
/**
......@@ -59,14 +68,20 @@ public class FlowObjectiveIntent extends Intent {
*
* @param appId application id
* @param key intent key
* @param devices list of target devices; in same order as the objectives
* @param objectives backing flow objectives
* @param resources backing network resources
*/
public FlowObjectiveIntent(ApplicationId appId, Key key,
Collection<Objective> objectives,
public FlowObjectiveIntent(ApplicationId appId,
Key key,
List<DeviceId> devices,
List<Objective> objectives,
Collection<NetworkResource> resources) {
super(appId, key, resources, DEFAULT_INTENT_PRIORITY);
this.objectives = objectives;
checkArgument(devices.size() == objectives.size(),
"Number of devices and objectives does not match");
this.objectives = ImmutableList.copyOf(objectives);
this.devices = ImmutableList.copyOf(devices);
}
/**
......@@ -74,10 +89,19 @@ public class FlowObjectiveIntent extends Intent {
*
* @return flow objectives
*/
Collection<Objective> objectives() {
public List<Objective> objectives() {
return objectives;
}
/**
* Returns the list of devices for the flow objectives.
*
* @return devices
*/
public List<DeviceId> devices() {
return devices;
}
@Override
public boolean isInstallable() {
......@@ -91,7 +115,8 @@ public class FlowObjectiveIntent extends Intent {
.add("key", key())
.add("appId", appId())
.add("resources", resources())
.add("objectives", objectives)
.add("device", devices())
.add("objectives", objectives())
.toString();
}
}
......
......@@ -16,11 +16,13 @@
package org.onosproject.net.intent;
import com.google.common.collect.ImmutableSet;
import com.google.common.testing.EqualsTester;
import java.util.Collection;
import java.util.List;
import org.junit.Test;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.NetworkResource;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
......@@ -30,7 +32,9 @@ import org.onosproject.net.flowobjective.DefaultForwardingObjective;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.Objective;
import java.util.Collection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.testing.EqualsTester;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
......@@ -52,8 +56,9 @@ public class FlowObjectiveIntentTest extends IntentTest {
.withSelector(DefaultTrafficSelector.builder().matchEthType((short) 123).build())
.withTreatment(DefaultTrafficTreatment.emptyTreatment())
.withFlag(ForwardingObjective.Flag.VERSATILE).add();
private static final Collection<Objective> OBJECTIVES = ImmutableSet.of(FO1, FO2);
private static final List<Objective> OBJECTIVES = ImmutableList.of(FO1, FO2);
private static final Collection<NetworkResource> RESOURCES = ImmutableSet.of();
private static final List<DeviceId> DEVICE = ImmutableList.of(DeviceId.NONE, DeviceId.NONE);
/**
* Tests basics of construction and getters.
......@@ -61,7 +66,7 @@ public class FlowObjectiveIntentTest extends IntentTest {
@Test
public void basics() {
FlowObjectiveIntent intent =
new FlowObjectiveIntent(APP_ID, KEY, OBJECTIVES, RESOURCES);
new FlowObjectiveIntent(APP_ID, KEY, DEVICE, OBJECTIVES, RESOURCES);
assertEquals("incorrect app id", APP_ID, intent.appId());
assertEquals("incorrect key", KEY, intent.key());
assertEquals("incorrect objectives", OBJECTIVES, intent.objectives());
......@@ -89,11 +94,11 @@ public class FlowObjectiveIntentTest extends IntentTest {
@Override
protected Intent createOne() {
return new FlowObjectiveIntent(APP_ID, OBJECTIVES, RESOURCES);
return new FlowObjectiveIntent(APP_ID, DEVICE, OBJECTIVES, RESOURCES);
}
@Override
protected Intent createAnother() {
return new FlowObjectiveIntent(APP_ID, OBJECTIVES, RESOURCES);
return new FlowObjectiveIntent(APP_ID, DEVICE, OBJECTIVES, RESOURCES);
}
}
\ No newline at end of file
}
......
/*
* Copyright 2016 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.LinkedList;
import java.util.List;
import java.util.Set;
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.DeviceId;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flowobjective.DefaultForwardingObjective;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.intent.FlowObjectiveIntent;
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.newresource.ResourceService;
import org.onosproject.net.resource.link.LinkResourceAllocations;
import org.slf4j.Logger;
import com.google.common.collect.ImmutableList;
import static org.slf4j.LoggerFactory.getLogger;
@Component(immediate = true)
public class PathIntentFlowObjectiveCompiler
extends PathCompiler<Objective>
implements IntentCompiler<PathIntent>,
PathCompiler.PathCompilerCreateFlow<Objective> {
private final Logger log = getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentExtensionService intentManager;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ResourceService resourceService;
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) {
List<Objective> objectives = new LinkedList<>();
List<DeviceId> devices = new LinkedList<>();
compile(this, intent, objectives, devices);
return ImmutableList.of(new FlowObjectiveIntent(appId, devices, objectives, intent.resources()));
}
@Override
public Logger log() {
return log;
}
@Override
public ResourceService resourceService() {
return resourceService;
}
@Override
public void createFlow(TrafficSelector originalSelector, TrafficTreatment originalTreatment,
ConnectPoint ingress, ConnectPoint egress,
int priority, boolean applyTreatment,
List<Objective> objectives,
List<DeviceId> devices) {
TrafficSelector selector = DefaultTrafficSelector.builder(originalSelector)
.matchInPort(ingress.port())
.build();
TrafficTreatment.Builder treatmentBuilder;
if (applyTreatment) {
treatmentBuilder = DefaultTrafficTreatment.builder(originalTreatment);
} else {
treatmentBuilder = DefaultTrafficTreatment.builder();
}
TrafficTreatment treatment = treatmentBuilder.setOutput(egress.port()).build();
objectives.add(DefaultForwardingObjective.builder()
.withSelector(selector)
.withTreatment(treatment)
.withPriority(priority)
.fromApp(appId)
.makePermanent()
.withFlag(ForwardingObjective.Flag.SPECIFIC)
.add());
devices.add(ingress.deviceId());
}
}