Allow static lambda and port mappings (ONOS-2067).
Fix bug in device resource store.
Change-Id: I219a4de9ec803b3d142a6b957868f64dc599fa24
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java
index fc62b25..557288c 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java
@@ -23,8 +23,8 @@
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
+import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
import org.onosproject.net.OchPort;
import org.onosproject.net.OduCltPort;
import org.onosproject.net.OduSignalType;
@@ -138,7 +138,7 @@
.signalType(OduSignalType.ODU4)
.bidirectional(intent.isBidirectional())
.build();
- intents.add(connIntent);
+ intentService.submit(connIntent);
}
// Create optical circuit intent
@@ -155,7 +155,7 @@
circuitIntent = new FlowRuleIntent(appId, rules, intent.resources());
// Save circuit to connectivity intent mapping
- deviceResourceService.requestMapping(connIntent.id(), circuitIntent.id());
+ deviceResourceService.requestMapping(connIntent.id(), intent.id());
intents.add(circuitIntent);
return intents;
@@ -163,16 +163,43 @@
/**
* Checks if current allocations on given resource can satisfy request.
+ * If the resource is null, return true.
*
* @param request
* @param resource
* @return
*/
private boolean isAvailable(Intent request, IntentId resource) {
+ if (resource == null) {
+ return true;
+ }
+
Set<IntentId> mapping = deviceResourceService.getMapping(resource);
- // TODO: hardcoded 10 x 10G
- return mapping.size() < 10;
+ if (mapping == null) {
+ return true;
+ }
+
+ // TODO: hardcoded 80% utilization
+ return mapping.size() < 8;
+ }
+
+ private boolean isAllowed(OpticalCircuitIntent circuitIntent, OpticalConnectivityIntent connIntent) {
+ ConnectPoint srcStaticPort = staticPort(circuitIntent.getSrc());
+ if (srcStaticPort != null) {
+ if (!srcStaticPort.equals(connIntent.getSrc())) {
+ return false;
+ }
+ }
+
+ ConnectPoint dstStaticPort = staticPort(circuitIntent.getDst());
+ if (dstStaticPort != null) {
+ if (!dstStaticPort.equals(connIntent.getDst())) {
+ return false;
+ }
+ }
+
+ return true;
}
/**
@@ -191,7 +218,13 @@
ConnectPoint src = circuitIntent.getSrc();
ConnectPoint dst = circuitIntent.getDst();
- if (!src.equals(connIntent.getSrc()) && !dst.equals(connIntent.getDst())) {
+ // Ignore if the intents don't have identical src and dst devices
+ if (!src.deviceId().equals(connIntent.getSrc().deviceId()) &&
+ !dst.deviceId().equals(connIntent.getDst().deviceId())) {
+ continue;
+ }
+
+ if (!isAllowed(circuitIntent, connIntent)) {
continue;
}
@@ -203,21 +236,44 @@
return null;
}
- private OchPort findAvailableOchPort(DeviceId deviceId, OpticalCircuitIntent circuitIntent) {
- List<Port> ports = deviceService.getPorts(deviceId);
+ private ConnectPoint staticPort(ConnectPoint connectPoint) {
+ Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port());
+
+ String staticPort = port.annotations().value(AnnotationKeys.STATIC_PORT);
+
+ // FIXME: need a better way to match the port
+ if (staticPort != null) {
+ for (Port p : deviceService.getPorts(connectPoint.deviceId())) {
+ if (staticPort.equals(p.number().name())) {
+ return new ConnectPoint(p.element().id(), p.number());
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private OchPort findAvailableOchPort(ConnectPoint oduPort, OpticalCircuitIntent circuitIntent) {
+ // First see if the port mappings are constrained
+ ConnectPoint ochCP = staticPort(oduPort);
+
+ if (ochCP != null) {
+ OchPort ochPort = (OchPort) deviceService.getPort(ochCP.deviceId(), ochCP.port());
+ IntentId intentId = deviceResourceService.getAllocations(ochPort);
+ if (isAvailable(circuitIntent, intentId)) {
+ return ochPort;
+ }
+ }
+
+ // No port constraints, so find any port that works
+ List<Port> ports = deviceService.getPorts(oduPort.deviceId());
for (Port port : ports) {
if (!(port instanceof OchPort)) {
continue;
}
- // Port is not used
IntentId intentId = deviceResourceService.getAllocations(port);
- if (intentId == null) {
- return (OchPort) port;
- }
-
- // Port is used but has free resources
if (isAvailable(circuitIntent, intentId)) {
return (OchPort) port;
}
@@ -226,16 +282,14 @@
return null;
}
- // TODO: Add constraints for OduClt to OCh port mappings
- // E.g., ports need to belong to same line card.
private Pair<OchPort, OchPort> findPorts(OpticalCircuitIntent intent) {
- OchPort srcPort = findAvailableOchPort(intent.getSrc().deviceId(), intent);
+ OchPort srcPort = findAvailableOchPort(intent.getSrc(), intent);
if (srcPort == null) {
return null;
}
- OchPort dstPort = findAvailableOchPort(intent.getDst().deviceId(), intent);
+ OchPort dstPort = findAvailableOchPort(intent.getDst(), intent);
if (dstPort == null) {
return null;
}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
index 13a2b6b..e5a8e3b 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
@@ -26,8 +26,10 @@
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.util.Frequency;
+import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.GridType;
import org.onosproject.net.Link;
import org.onosproject.net.OchPort;
@@ -123,17 +125,26 @@
// Use first path that can be successfully reserved
for (Path path : paths) {
- // Request and reserve lambda on path
- LinkResourceAllocations linkAllocs = assignWavelength(intent, path);
- if (linkAllocs == null) {
- continue;
+
+ // Static or dynamic lambda allocation
+ LambdaResourceAllocation lambdaAlloc;
+ String staticLambda = srcPort.annotations().value(AnnotationKeys.STATIC_LAMBDA);
+ if (staticLambda != null) {
+ // FIXME: need to actually reserve the lambda
+ lambdaAlloc = new LambdaResourceAllocation(LambdaResource.valueOf(Integer.parseInt(staticLambda)));
+ } else {
+ // Request and reserve lambda on path
+ LinkResourceAllocations linkAllocs = assignWavelength(intent, path);
+ if (linkAllocs == null) {
+ continue;
+ }
+ lambdaAlloc = getWavelength(path, linkAllocs);
}
OmsPort omsPort = (OmsPort) deviceService.getPort(path.src().deviceId(), path.src().port());
// Create installable optical path intent
- LambdaResourceAllocation lambdaAlloc = getWavelength(path, linkAllocs);
- OchSignal ochSignal = getOchSignal(lambdaAlloc, omsPort.minFrequency(), omsPort.grid());
+ OchSignal ochSignal = getOchSignal(lambdaAlloc, omsPort.maxFrequency(), omsPort.grid());
// Only support fixed grid for now
OchSignalType signalType = OchSignalType.FIXED_GRID;
@@ -188,7 +199,10 @@
LinkResourceAllocations allocations = linkResourceService.requestResources(request.build());
- checkWavelengthContinuity(allocations, path);
+ if (!checkWavelengthContinuity(allocations, path)) {
+ linkResourceService.releaseResources(allocations);
+ return null;
+ }
return allocations;
}
@@ -229,15 +243,15 @@
* Convert lambda resource allocation in OCh signal.
*
* @param alloc lambda resource allocation
- * @param minFrequency minimum frequency
+ * @param maxFrequency maximum frequency
* @param grid grid spacing frequency
* @return OCh signal
*/
- private OchSignal getOchSignal(LambdaResourceAllocation alloc, Frequency minFrequency, Frequency grid) {
+ private OchSignal getOchSignal(LambdaResourceAllocation alloc, Frequency maxFrequency, Frequency grid) {
int channel = alloc.lambda().toInt();
// Calculate center frequency
- Frequency centerFrequency = minFrequency.add(grid.multiply(channel)).add(grid.floorDivision(2));
+ Frequency centerFrequency = maxFrequency.subtract(grid.multiply(channel - 1));
// Build OCh signal object
int spacingMultiplier = (int) (centerFrequency.subtract(OchSignal.CENTER_FREQUENCY).asHz() / grid.asHz());
@@ -248,6 +262,23 @@
return ochSignal;
}
+ private ConnectPoint staticPort(ConnectPoint connectPoint) {
+ Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port());
+
+ String staticPort = port.annotations().value(AnnotationKeys.STATIC_PORT);
+
+ // FIXME: need a better way to match the port
+ if (staticPort != null) {
+ for (Port p : deviceService.getPorts(connectPoint.deviceId())) {
+ if (staticPort.equals(p.number().name())) {
+ return new ConnectPoint(p.element().id(), p.number());
+ }
+ }
+ }
+
+ return null;
+ }
+
/**
* Calculates optical paths in WDM topology.
*
@@ -260,13 +291,29 @@
LinkWeight weight = new LinkWeight() {
@Override
public double weight(TopologyEdge edge) {
+ // Disregard inactive or non-optical links
if (edge.link().state() == Link.State.INACTIVE) {
return -1;
}
if (edge.link().type() != Link.Type.OPTICAL) {
return -1;
}
- //return edge.link().annotations().value("optical.type").equals("WDM") ? +1 : -1;
+ // Adhere to static port mappings
+ DeviceId srcDeviceId = edge.link().src().deviceId();
+ if (srcDeviceId.equals(intent.getSrc().deviceId())) {
+ ConnectPoint srcStaticPort = staticPort(intent.getSrc());
+ if (srcStaticPort != null) {
+ return srcStaticPort.equals(edge.link().src()) ? 1 : -1;
+ }
+ }
+ DeviceId dstDeviceId = edge.link().dst().deviceId();
+ if (dstDeviceId.equals(intent.getDst().deviceId())) {
+ ConnectPoint dstStaticPort = staticPort(intent.getDst());
+ if (dstStaticPort != null) {
+ return dstStaticPort.equals(edge.link().dst()) ? 1 : -1;
+ }
+ }
+
return 1;
}
};