optical intent module
Change-Id: Ifa405ab1d883b293d349f1b66d26a05a0724691f
diff --git a/apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java b/apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java
index 95b5041..e91235c 100644
--- a/apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java
+++ b/apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java
@@ -1,7 +1,10 @@
package org.onlab.onos.optical.provisioner;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
-
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import org.apache.felix.scr.annotations.Activate;
@@ -9,25 +12,25 @@
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
-
import org.onlab.onos.ApplicationId;
import org.onlab.onos.CoreService;
import org.onlab.onos.net.ConnectPoint;
-
import org.onlab.onos.net.Link;
+import org.onlab.onos.net.Path;
import org.onlab.onos.net.device.DeviceService;
-
-import org.onlab.onos.net.intent.IdGenerator;
import org.onlab.onos.net.intent.Intent;
-
import org.onlab.onos.net.intent.IntentEvent;
import org.onlab.onos.net.intent.IntentExtensionService;
-import org.onlab.onos.net.intent.IntentId;
import org.onlab.onos.net.intent.IntentListener;
import org.onlab.onos.net.intent.IntentService;
import org.onlab.onos.net.intent.OpticalConnectivityIntent;
import org.onlab.onos.net.intent.PointToPointIntent;
import org.onlab.onos.net.link.LinkService;
+import org.onlab.onos.net.resource.LinkResourceService;
+import org.onlab.onos.net.topology.LinkWeight;
+import org.onlab.onos.net.topology.Topology;
+import org.onlab.onos.net.topology.TopologyEdge;
+import org.onlab.onos.net.topology.TopologyGraph;
import org.onlab.onos.net.topology.TopologyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -63,12 +66,12 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
- // protected LinkResourceService resourceService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LinkResourceService resourceService;
private ApplicationId appId;
- private static long intentId = 0x9000000;
- protected IdGenerator<IntentId> intentIdGenerator;
+ //protected <IntentId> intentIdGenerator;
private final InternalOpticalPathProvisioner pathProvisioner = new InternalOpticalPathProvisioner();
@@ -106,7 +109,7 @@
}
private void setuplightpath(Intent intent) {
- // TODO: considering user policies and optical reach, may generate more OpticalConnectivityIntents
+ // TODO: considering user policies and optical reach
if (!intent.equals(PointToPointIntent.class)) {
return;
}
@@ -116,35 +119,103 @@
return;
}
- // Set<Port> port1 = deviceService.getPorts(pktIntent.ingressPoint().deviceId());
+ Topology topology = topologyService.currentTopology();
+ TopologyGraph graph = topologyService.getGraph(topology);
- Set<Link> srcLink = linkService.getLinks(pktIntent.ingressPoint());
- Set<Link> dstLink = linkService.getLinks(pktIntent.egressPoint());
+ LinkWeight weight = new LinkWeight() {
+ @Override
+ public double weight(TopologyEdge edge) {
+ boolean isOptical = false;
+ String t = edge.link().annotations().value("linkType");
+ if (t.equals("WDM")) {
+ isOptical = true;
+ }
+ if (isOptical) {
+ return 1000; // optical links
+ } else {
+ return 10; // packet links
+ }
+ }
+ };
- if (srcLink.isEmpty() || dstLink.isEmpty()) {
+ Set<Path> paths = topologyService.getPaths(topology,
+ pktIntent.ingressPoint().deviceId(),
+ pktIntent.egressPoint().deviceId(),
+ weight);
+
+ if (paths.isEmpty()) {
return;
}
- Iterator<Link> itrSrc = srcLink.iterator();
- Iterator<Link> itrDst = dstLink.iterator();
+ ConnectPoint srcWdmPoint = null;
+ ConnectPoint dstWdmPoint = null;
+ Iterator<Path> itrPath = paths.iterator();
+ Path firstPath = itrPath.next();
+ log.info(firstPath.toString());
- if (!itrSrc.next().annotations().value("linkType").equals("PktOptLink")) {
- return;
- }
- if (!itrDst.next().annotations().value("linkType").equals("PktOptLink")) {
- return;
+ ArrayList<Map<ConnectPoint, ConnectPoint>> connectionList = new ArrayList<>();
+
+ Iterator<Link> itrLink = firstPath.links().iterator();
+ while (itrLink.hasNext()) {
+ Link link1 = itrLink.next();
+ if (!isOpticalLink(link1)) {
+ continue;
+ } else {
+ srcWdmPoint = link1.dst();
+ dstWdmPoint = srcWdmPoint;
+ }
+
+ while (true) {
+
+ if (itrLink.hasNext()) {
+ Link link2 = itrLink.next();
+ dstWdmPoint = link2.src();
+ } else {
+ break;
+ }
+
+ if (itrLink.hasNext()) {
+ Link link3 = itrLink.next();
+ if (!isOpticalLink(link3)) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ Map<ConnectPoint, ConnectPoint> pair =
+ new HashMap<ConnectPoint, ConnectPoint>();
+ pair.put(srcWdmPoint, dstWdmPoint);
+
+ connectionList.add(pair);
}
- ConnectPoint srcWdmPoint = itrSrc.next().dst();
- ConnectPoint dstWdmPoint = itrDst.next().dst();
+ for (Map<ConnectPoint, ConnectPoint> map : connectionList) {
+ for (Entry<ConnectPoint, ConnectPoint> entry : map.entrySet()) {
- OpticalConnectivityIntent opticalIntent =
- new OpticalConnectivityIntent(new IntentId(intentId++),
- srcWdmPoint,
- dstWdmPoint);
+ ConnectPoint src = entry.getKey();
+ ConnectPoint dst = entry.getValue();
- log.info(opticalIntent.toString());
- intentService.submit(opticalIntent);
+ Intent opticalIntent = new OpticalConnectivityIntent(appId,
+ srcWdmPoint,
+ dstWdmPoint);
+
+ intentService.submit(opticalIntent);
+
+ log.info(opticalIntent.toString());
+ }
+ }
+
+ }
+
+ private boolean isOpticalLink(Link link) {
+ boolean isOptical = false;
+ String t = link.annotations().value("linkType");
+ if (t.equals("WDM") || t.equals("PktOptLink")) {
+ isOptical = true;
+ }
+ return isOptical;
}
private void teardownLightpath(Intent intent) {
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/OpticalConnectivityIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/OpticalConnectivityIntent.java
index 4e4ebe5..6e595c5 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/OpticalConnectivityIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/OpticalConnectivityIntent.java
@@ -1,13 +1,14 @@
package org.onlab.onos.net.intent;
+import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.ConnectPoint;
/**
- * An optical layer Intent for a connectivity from a Transponder port to another
+ * An optical layer Intent for a connectivity from one Transponder port to another
* Transponder port. No trafficSelector as well as trafficTreament are needed.
*
*/
-public class OpticalConnectivityIntent extends AbstractIntent {
+public class OpticalConnectivityIntent extends Intent {
protected ConnectPoint src;
protected ConnectPoint dst;
@@ -18,8 +19,9 @@
* @param src The source transponder port.
* @param dst The destination transponder port.
*/
- public OpticalConnectivityIntent(IntentId id, ConnectPoint src, ConnectPoint dst) {
- super(id);
+ public OpticalConnectivityIntent(ApplicationId appId, ConnectPoint src, ConnectPoint dst) {
+ super(id(OpticalConnectivityIntent.class, src, dst),
+ appId, null);
this.src = src;
this.dst = dst;
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/OpticalPathIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/OpticalPathIntent.java
index d0d73d9..1ad828d 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/OpticalPathIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/OpticalPathIntent.java
@@ -1,8 +1,8 @@
package org.onlab.onos.net.intent;
import java.util.Collection;
-import java.util.Objects;
+import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.Path;
@@ -11,15 +11,18 @@
import com.google.common.base.MoreObjects;
-public class OpticalPathIntent extends OpticalConnectivityIntent implements InstallableIntent {
-
+public class OpticalPathIntent extends OpticalConnectivityIntent {
private final Path path;
private final TrafficSelector opticalMatch;
private final TrafficTreatment opticalAction;
- public OpticalPathIntent(IntentId id, TrafficSelector match, TrafficTreatment action,
- ConnectPoint ingressPort, ConnectPoint egressPort,
- Path path) {
+ public OpticalPathIntent(ApplicationId appId,
+ ConnectPoint src,
+ ConnectPoint dst,
+ TrafficSelector match,
+ TrafficTreatment action,
+ Path path) {
+ super(appId, src, dst);
this.opticalMatch = match;
this.opticalAction = action;
this.path = path;
@@ -44,32 +47,11 @@
}
@Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- if (!super.equals(o)) {
- return false;
- }
-
- OpticalPathIntent that = (OpticalPathIntent) o;
-
- if (!path.equals(that.path)) {
- return false;
- }
-
+ public boolean isInstallable() {
return true;
}
@Override
- public int hashCode() {
- return Objects.hash(super.hashCode(), path);
- }
-
- @Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("id", id())
@@ -81,7 +63,6 @@
.toString();
}
- @Override
public Collection<Link> requiredLinks() {
return path.links();
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java
index d888ed3..e44a01b 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java
@@ -3,7 +3,7 @@
import static org.slf4j.LoggerFactory.getLogger;
import java.util.ArrayList;
-
+import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -12,24 +12,28 @@
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.onos.CoreService;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultEdgeLink;
-
import org.onlab.onos.net.Link;
import org.onlab.onos.net.Path;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
-import org.onlab.onos.net.intent.IdGenerator;
import org.onlab.onos.net.intent.Intent;
import org.onlab.onos.net.intent.IntentCompiler;
import org.onlab.onos.net.intent.IntentExtensionService;
-import org.onlab.onos.net.intent.IntentId;
+
import org.onlab.onos.net.intent.OpticalConnectivityIntent;
import org.onlab.onos.net.intent.OpticalPathIntent;
-
import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.net.resource.LinkResourceService;
+import org.onlab.onos.net.topology.LinkWeight;
import org.onlab.onos.net.topology.PathService;
+import org.onlab.onos.net.topology.Topology;
+import org.onlab.onos.net.topology.TopologyEdge;
+
+import org.onlab.onos.net.topology.TopologyService;
import org.slf4j.Logger;
/**
@@ -49,14 +53,17 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PathService pathService;
- // protected LinkResourceService resourceService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected TopologyService topologyService;
- protected IdGenerator<IntentId> intentIdGenerator;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LinkResourceService resourceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
@Activate
public void activate() {
- IdBlockAllocator idBlockAllocator = new DummyIdBlockAllocator();
- intentIdGenerator = new IdBlockAllocatorBasedIntentIdGenerator(idBlockAllocator);
intentManager.registerCompiler(OpticalConnectivityIntent.class, this);
}
@@ -67,29 +74,29 @@
@Override
public List<Intent> compile(OpticalConnectivityIntent intent) {
- // TO DO: compute multiple paths using the K-shortest path algorithm
+ // TODO: compute multiple paths using the K-shortest path algorithm
+ List<Intent> retList = new ArrayList<>();
Path path = calculatePath(intent.getSrcConnectPoint(), intent.getDst());
- log.info("calculate the lightpath: {}.", path.toString());
+ if (path == null) {
+ return retList;
+ } else {
+ log.info("the computed lightpath is : {}.", path.toString());
+ }
List<Link> links = new ArrayList<>();
links.add(DefaultEdgeLink.createEdgeLink(intent.getSrcConnectPoint(), true));
links.addAll(path.links());
links.add(DefaultEdgeLink.createEdgeLink(intent.getDst(), false));
- // TO DO: choose a wavelength using the first-fit algorithm
TrafficSelector opticalSelector = null;
TrafficTreatment opticalTreatment = null;
- List<Intent> retList = new ArrayList<>();
- int wavelength = assignWavelength(path);
- log.info("assign the wavelength: {}.", wavelength);
-
// create a new opticalPathIntent
- Intent newIntent = new OpticalPathIntent(intentIdGenerator.getNewId(),
- opticalSelector,
- opticalTreatment,
+ Intent newIntent = new OpticalPathIntent(intent.appId(),
path.src(),
path.dst(),
+ opticalSelector,
+ opticalTreatment,
path);
retList.add(newIntent);
@@ -97,18 +104,45 @@
return retList;
}
- private Path calculatePath(ConnectPoint one, ConnectPoint two) {
- // TODO: K-shortest path computation algorithm
- Set<Path> paths = pathService.getPaths(one.deviceId(), two.deviceId());
- if (paths.isEmpty()) {
- throw new PathNotFoundException("No optical path from " + one + " to " + two);
- }
- return paths.iterator().next();
- }
+ private Path calculatePath(ConnectPoint start, ConnectPoint end) {
+ // TODO: support user policies
+ Topology topology = topologyService.currentTopology();
+ LinkWeight weight = new LinkWeight() {
+ @Override
+ public double weight(TopologyEdge edge) {
+ boolean isOptical = false;
+ String t = edge.link().annotations().value("linkType");
+ if (t.equals("WDM")) {
+ isOptical = true;
+ }
+ if (isOptical) {
+ return 1; // optical links
+ } else {
+ return 10000; // packet links
+ }
+ }
+ };
- private int assignWavelength(Path path) {
- // TODO: wavelength assignment
- return 1;
+ Set<Path> paths = topologyService.getPaths(topology,
+ start.deviceId(),
+ end.deviceId(),
+ weight);
+
+ Iterator<Path> itr = paths.iterator();
+ while (itr.hasNext()) {
+ Path path = itr.next();
+ if (path.cost() >= 10000) {
+ itr.remove();
+ }
+ }
+
+ if (paths.isEmpty()) {
+ log.info("No optical path found from " + start + " to " + end);
+ return null;
+ } else {
+ return paths.iterator().next();
+ }
+
}
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java
index 2e4f2fd..1f7ef68 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java
@@ -19,6 +19,7 @@
import org.onlab.onos.net.flow.CompletedBatchOperation;
import org.onlab.onos.net.flow.DefaultFlowRule;
import org.onlab.onos.net.flow.DefaultTrafficSelector;
+import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRuleBatchEntry;
import org.onlab.onos.net.flow.FlowRuleBatchOperation;
@@ -29,6 +30,12 @@
import org.onlab.onos.net.intent.IntentExtensionService;
import org.onlab.onos.net.intent.IntentInstaller;
import org.onlab.onos.net.intent.OpticalPathIntent;
+import org.onlab.onos.net.resource.Lambda;
+import org.onlab.onos.net.resource.LinkResourceAllocations;
+import org.onlab.onos.net.resource.LinkResourceRequest;
+import org.onlab.onos.net.resource.LinkResourceService;
+import org.onlab.onos.net.resource.ResourceRequest;
+import org.onlab.onos.net.topology.TopologyService;
import org.slf4j.Logger;
import com.google.common.collect.Lists;
@@ -41,7 +48,6 @@
@Component(immediate = true)
public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIntent> {
-
private final Logger log = getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -53,8 +59,16 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected TopologyService topologyService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LinkResourceService resourceService;
+
private ApplicationId appId;
+ final static short WAVELENGTH = 80;
+
@Activate
public void activate() {
appId = coreService.registerApplication("org.onlab.onos.net.intent");
@@ -67,42 +81,25 @@
}
@Override
- public Future<CompletedBatchOperation> install(OpticalPathIntent intent) {
- TrafficSelector.Builder builder =
- DefaultTrafficSelector.builder(intent.selector());
- Iterator<Link> links = intent.path().links().iterator();
- ConnectPoint prev = links.next().dst();
- List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
- while (links.hasNext()) {
- builder.matchInport(prev.port());
- Link link = links.next();
- TrafficTreatment treatment = builder()
- .setOutput(link.src().port()).build();
-
- FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
- builder.build(),
- treatment,
- 100, // priority is set to 100
- appId,
- 100); // ROADM may need longer cross-connect time, here it is assumed 100ms.
-
- rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
- prev = link.dst();
+ public List<FlowRuleBatchOperation> install(OpticalPathIntent intent) {
+ Lambda la = assignWavelength(intent.path().links());
+ if (la == null) {
+ return null;
}
+ // resourceService.requestResources(la);
+ // la.toInt();
+ //intent.selector().criteria();
- FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules);
- Future<CompletedBatchOperation> future = flowRuleService.applyBatch(batch);
- return future;
- }
+ //TrafficSelector.Builder builder = DefaultTrafficSelector.builder();
+ //builder.matchLambdaType(la.toInt())
+ // .matchInport(intent.getSrcConnectPoint().port());
- @Override
- public Future<CompletedBatchOperation> uninstall(OpticalPathIntent intent) {
TrafficSelector.Builder builder =
DefaultTrafficSelector.builder(intent.selector());
Iterator<Link> links = intent.path().links().iterator();
ConnectPoint prev = links.next().dst();
List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
-
+ // TODO Generate multiple batches
while (links.hasNext()) {
builder.matchInport(prev.port());
Link link = links.next();
@@ -114,15 +111,75 @@
treatment,
100,
appId,
- 100);
+ 100,
+ true);
+ rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
+ prev = link.dst();
+ }
+ return Lists.newArrayList(new FlowRuleBatchOperation(rules));
+ }
+ private Lambda assignWavelength(List<Link> links) {
+ // TODO More wavelength assignment algorithm
+ int wavenum = 0;
+ Iterator<Link> itrlink = links.iterator();
+ for (int i = 1; i <= WAVELENGTH; i++) {
+ wavenum = i;
+ boolean found = true;
+ while (itrlink.hasNext()) {
+ Link link = itrlink.next();
+ if (isWavelengthUsed(link, i)) {
+ found = false;
+ break;
+ }
+ }
+ // First-Fit wavelength assignment algorithm
+ if (found) {
+ break;
+ }
+ }
+
+ if (wavenum == 0) {
+ return null;
+ }
+
+ Lambda wave = Lambda.valueOf(wavenum);
+ return wave;
+ }
+
+ private boolean isWavelengthUsed(Link link, int i) {
+ Iterable<LinkResourceAllocations> wave = resourceService.getAllocations(link);
+ for (LinkResourceAllocations ir : wave) {
+ //if ir.resources().contains(i) {
+ //}
+ }
+ return false;
+ }
+
+ @Override
+ public List<FlowRuleBatchOperation> uninstall(OpticalPathIntent intent) {
+ TrafficSelector.Builder builder =
+ DefaultTrafficSelector.builder(intent.selector());
+ Iterator<Link> links = intent.path().links().iterator();
+ ConnectPoint prev = links.next().dst();
+ List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
+ // TODO Generate multiple batches
+ while (links.hasNext()) {
+ builder.matchInport(prev.port());
+ Link link = links.next();
+ TrafficTreatment treatment = builder()
+ .setOutput(link.src().port()).build();
+ FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
+ builder.build(),
+ treatment,
+ 100,
+ appId,
+ 100,
+ true);
rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
prev = link.dst();
}
-
- FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules);
- Future<CompletedBatchOperation> future = flowRuleService.applyBatch(batch);
- return future;
+ return Lists.newArrayList(new FlowRuleBatchOperation(rules));
}
}