[ONOS-7839] suggestedPath for optical connectivity intent with optical-rest support
Change-Id: I2b5093ac26149e450a14467c71656447233b5ce2
diff --git a/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalConnectivityIntentCompiler.java b/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
index 5a76aef..1355337 100644
--- a/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
+++ b/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
@@ -60,13 +60,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -139,8 +139,15 @@
resources.add(srcPortResource);
resources.add(dstPortResource);
+ // If there is a suggestedPath, use this path without further checking, otherwise trigger path computation
+ Stream<Path> paths;
+ if (intent.suggestedPath().isPresent()) {
+ paths = Stream.of(intent.suggestedPath().get());
+ } else {
+ paths = getOpticalPaths(intent);
+ }
+
// Find first path that has the required resources
- Stream<Path> paths = getOpticalPaths(intent);
Optional<Map.Entry<Path, List<OchSignal>>> found = paths
.map(path -> Maps.immutableEntry(path, findFirstAvailableLambda(intent, path)))
.filter(entry -> !entry.getValue().isEmpty())
@@ -350,8 +357,16 @@
return ScalarWeight.NON_VIABLE_WEIGHT;
}
+ /**
+ *
+ * @param edge edge to be weighed
+ * @return the metric retrieved from the annotations otherwise 1
+ */
@Override
public Weight weight(TopologyEdge edge) {
+
+ log.debug("Link {} metric {}", edge.link(), edge.link().annotations().value("metric"));
+
// Disregard inactive or non-optical links
if (edge.link().state() == Link.State.INACTIVE) {
return ScalarWeight.toWeight(-1);
@@ -375,7 +390,13 @@
}
}
- return ScalarWeight.toWeight(1);
+ String metricString = edge.link().annotations().value("metric");
+ if (!metricString.isEmpty()) {
+ double metric = Double.parseDouble(metricString);
+ return ScalarWeight.toWeight(metric);
+ } else {
+ return ScalarWeight.toWeight(1);
+ }
}
};
@@ -418,6 +439,7 @@
return path;
});
}
+
return paths;
}
}
diff --git a/apps/optical-model/src/main/java/org/onosproject/net/optical/util/OpticalIntentUtility.java b/apps/optical-model/src/main/java/org/onosproject/net/optical/util/OpticalIntentUtility.java
index 8deb5ba..004c302 100644
--- a/apps/optical-model/src/main/java/org/onosproject/net/optical/util/OpticalIntentUtility.java
+++ b/apps/optical-model/src/main/java/org/onosproject/net/optical/util/OpticalIntentUtility.java
@@ -25,6 +25,7 @@
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.Port;
+import org.onosproject.net.Path;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.Key;
@@ -84,7 +85,7 @@
// continue only if both OduClt port's Devices are of the same type
if (!(srcDevice.type().equals(dstDevice.type()))) {
- log.debug("Devices without same deviceType: SRC=%s and DST=%s", srcDevice.type(), dstDevice.type());
+ log.debug("Devices without same deviceType: SRC {} and DST={}", srcDevice.type(), dstDevice.type());
return intent;
}
@@ -109,7 +110,7 @@
.bidirectional(bidirectional)
.build();
} else {
- log.debug("Wrong Device Type for connect points %s and %s", ingress, egress);
+ log.debug("Wrong Device Type for connect points {} and {}", ingress, egress);
}
} else if (srcPort instanceof OchPort && dstPort instanceof OchPort) {
OduSignalType signalType = ((OchPort) srcPort).signalType();
@@ -123,7 +124,92 @@
.ochSignal(signal)
.build();
} else {
- log.debug("Unable to create optical intent between connect points %s and %s", ingress, egress);
+ log.debug("Unable to create optical intent between connect points {} and {}", ingress, egress);
+ }
+
+ return intent;
+ }
+
+ /**
+ * Returns a new optical intent created from the method parameters, strict suggestedPath is specified.
+ *
+ * @param ingress ingress description (device/port)
+ * @param egress egress description (device/port)
+ * @param deviceService device service
+ * @param key intent key
+ * @param appId application id
+ * @param bidirectional if this argument is true, the optical link created
+ * will be bidirectional, otherwise the link will be unidirectional.
+ * @param signal optical signal
+ * @param path suggested path for the intent
+ *
+ * @return created intent
+ */
+ public static Intent createExplicitOpticalIntent(ConnectPoint ingress, ConnectPoint
+ egress, DeviceService deviceService, Key key, ApplicationId appId, boolean
+ bidirectional, OchSignal signal, Path path) {
+
+ Intent intent = null;
+
+ if (ingress == null || egress == null) {
+ log.error("Invalid endpoint(s); could not create optical intent");
+ return intent;
+ }
+
+ DeviceService ds = opticalView(deviceService);
+
+ Port srcPort = ds.getPort(ingress.deviceId(), ingress.port());
+ Port dstPort = ds.getPort(egress.deviceId(), egress.port());
+
+ if (srcPort instanceof OduCltPort && dstPort instanceof OduCltPort) {
+ Device srcDevice = ds.getDevice(ingress.deviceId());
+ Device dstDevice = ds.getDevice(egress.deviceId());
+
+ // continue only if both OduClt port's Devices are of the same type
+ if (!(srcDevice.type().equals(dstDevice.type()))) {
+ log.debug("Devices without same deviceType: SRC={} and DST={}", srcDevice.type(), dstDevice.type());
+ return intent;
+ }
+
+ CltSignalType signalType = ((OduCltPort) srcPort).signalType();
+ if (Device.Type.ROADM.equals(srcDevice.type()) ||
+ Device.Type.ROADM_OTN.equals(srcDevice.type())) {
+ intent = OpticalCircuitIntent.builder()
+ .appId(appId)
+ .key(key)
+ .src(ingress)
+ .dst(egress)
+ .signalType(signalType)
+ .bidirectional(bidirectional)
+ .build();
+ } else if (Device.Type.OTN.equals(srcDevice.type())) {
+ intent = OpticalOduIntent.builder()
+ .appId(appId)
+ .key(key)
+ .src(ingress)
+ .dst(egress)
+ .signalType(signalType)
+ .bidirectional(bidirectional)
+ .build();
+ } else {
+ log.error("Wrong Device Type for connect points: " +
+ "ingress {} of type {}; egress {} of type {}",
+ ingress, srcDevice.type(), egress, dstDevice.type());
+ }
+ } else if (srcPort instanceof OchPort && dstPort instanceof OchPort) {
+ OduSignalType signalType = ((OchPort) srcPort).signalType();
+ intent = OpticalConnectivityIntent.builder()
+ .appId(appId)
+ .key(key)
+ .src(ingress)
+ .dst(egress)
+ .signalType(signalType)
+ .bidirectional(bidirectional)
+ .ochSignal(signal)
+ .suggestedPath(path)
+ .build();
+ } else {
+ log.error("Unable to create explicit optical intent between connect points {} and {}", ingress, egress);
}
return intent;
diff --git a/apps/optical-rest/src/main/java/org/onosproject/net/optical/rest/OpticalIntentsWebResource.java b/apps/optical-rest/src/main/java/org/onosproject/net/optical/rest/OpticalIntentsWebResource.java
index 2d16e02..2cb1143 100644
--- a/apps/optical-rest/src/main/java/org/onosproject/net/optical/rest/OpticalIntentsWebResource.java
+++ b/apps/optical-rest/src/main/java/org/onosproject/net/optical/rest/OpticalIntentsWebResource.java
@@ -20,23 +20,40 @@
import static org.onlab.util.Tools.nullIsNotFound;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.graph.ScalarWeight;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
-import org.onosproject.net.OchSignal;
+import org.onosproject.net.Device;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Link;
+import org.onosproject.net.DefaultPath;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.OchSignalCriterion;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.FlowRuleIntent;
+import org.onosproject.net.intent.IntentState;
import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.OpticalConnectivityIntent;
+import org.onosproject.net.link.LinkService;
import org.onosproject.net.optical.json.OchSignalCodec;
+import org.onosproject.net.provider.ProviderId;
import org.onosproject.rest.AbstractWebResource;
import org.slf4j.Logger;
-import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
+import javax.ws.rs.GET;
+import javax.ws.rs.DELETE;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Consumes;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@@ -44,11 +61,15 @@
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Collectors;
+import static org.onosproject.net.optical.util.OpticalIntentUtility.createExplicitOpticalIntent;
import static org.slf4j.LoggerFactory.getLogger;
import static org.onlab.util.Tools.readTreeFromStream;
-import static org.onosproject.net.optical.util.OpticalIntentUtility.createOpticalIntent;
/**
@@ -60,20 +81,15 @@
private static final Logger log = getLogger(OpticalIntentsWebResource.class);
private static final String JSON_INVALID = "Invalid json input";
-
private static final String APP_ID = "appId";
-
private static final String INGRESS_POINT = "ingressPoint";
private static final String EGRESS_POINT = "egressPoint";
-
private static final String BIDIRECTIONAL = "bidirectional";
-
private static final String SIGNAL = "signal";
-
- protected static final String MISSING_MEMBER_MESSAGE =
- " member is required";
- private static final String E_APP_ID_NOT_FOUND =
- "Application ID is not found";
+ private static final String SUGGESTEDPATH = "suggestedPath";
+ private static final String MISSING_MEMBER_MESSAGE = " member is required";
+ private static final String E_APP_ID_NOT_FOUND = "Application ID is not found";
+ private static final ProviderId PROVIDER_ID = new ProviderId("netconf", "optical-rest");
@Context
private UriInfo uriInfo;
@@ -108,6 +124,130 @@
}
}
+ /**
+ * Get the optical intents on the network.
+ *
+ * @return 200 OK
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getIntents() {
+
+ DeviceService deviceService = get(DeviceService.class);
+
+ IntentService intentService = get(IntentService.class);
+ Iterator intentItr = intentService.getIntents().iterator();
+
+ ArrayNode arrayFlows = mapper().createArrayNode();
+
+ while (intentItr.hasNext()) {
+
+ Intent intent = (Intent) intentItr.next();
+ if (intent instanceof OpticalConnectivityIntent) {
+
+ OpticalConnectivityIntent opticalConnectivityIntent = (OpticalConnectivityIntent) intent;
+
+ Device srcDevice = deviceService.getDevice(opticalConnectivityIntent.getSrc().deviceId());
+ Device dstDevice = deviceService.getDevice(opticalConnectivityIntent.getDst().deviceId());
+
+ String srcDeviceName = srcDevice.annotations().value(AnnotationKeys.NAME);
+ String dstDeviceName = dstDevice.annotations().value(AnnotationKeys.NAME);
+
+ ObjectNode objectNode = mapper().createObjectNode();
+
+ objectNode.put("intent id", opticalConnectivityIntent.id().toString());
+ objectNode.put("app id", opticalConnectivityIntent.appId().name());
+ objectNode.put("state", intentService.getIntentState(opticalConnectivityIntent.key()).toString());
+ objectNode.put("src", opticalConnectivityIntent.getSrc().toString());
+ objectNode.put("dst", opticalConnectivityIntent.getDst().toString());
+ objectNode.put("srcName", srcDeviceName);
+ objectNode.put("dstName", dstDeviceName);
+
+ //Only for INSTALLED intents
+ if (intentService.getIntentState(intent.key()) == IntentState.INSTALLED) {
+
+ //Retrieve associated FlowRuleIntent
+ FlowRuleIntent installableIntent =
+ (FlowRuleIntent) intentService.getInstallableIntents(opticalConnectivityIntent.key())
+ .stream()
+ .filter(FlowRuleIntent.class::isInstance)
+ .findFirst()
+ .orElse(null);
+
+ //Retrieve used ochSignal from the Selector of one of the installed FlowRule
+ //TODO store utilized ochSignal in the intent resources
+ if (installableIntent != null) {
+ OchSignal signal = installableIntent.flowRules().stream()
+ .map(r -> ((OchSignalCriterion)
+ r.selector().getCriterion(Criterion.Type.OCH_SIGID)).lambda())
+ .findFirst()
+ .orElse(null);
+
+ objectNode.put("ochSignal", signal.toString());
+ objectNode.put("centralFreq", signal.centralFrequency().asTHz() + " THz");
+ }
+
+ //Retrieve path and print it to REST
+ if (installableIntent != null) {
+ String path = installableIntent.resources().stream()
+ .filter(Link.class::isInstance)
+ .map(Link.class::cast)
+ .map(r -> deviceService.getDevice(r.src().deviceId()))
+ .map(r -> r.annotations().value(AnnotationKeys.NAME))
+ .collect(Collectors.joining(" -> "));
+
+ List<Link> pathLinks = installableIntent.resources().stream()
+ .filter(Link.class::isInstance)
+ .map(Link.class::cast)
+ .collect(Collectors.toList());
+
+ DefaultPath defaultPath = new DefaultPath(PROVIDER_ID, pathLinks, new ScalarWeight(1));
+
+ objectNode.put("path", defaultPath.toString());
+ objectNode.put("pathName", path + " -> " + dstDeviceName);
+ }
+ }
+
+ arrayFlows.add(objectNode);
+ }
+ }
+
+ ObjectNode root = this.mapper().createObjectNode().putPOJO("Intents", arrayFlows);
+ return ok(root).build();
+ }
+
+ /**
+ * Delete the specified optical intent.
+ *
+ * @param appId application identifier
+ * @param keyString intent key
+ * @return 204 NO CONTENT
+ */
+ @DELETE
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Path("{appId}/{key}")
+ public Response deleteIntent(@PathParam("appId") String appId,
+ @PathParam("key") String keyString) {
+
+ final ApplicationId app = get(CoreService.class).getAppId(appId);
+ nullIsNotFound(app, "Application Id not found");
+
+ IntentService intentService = get(IntentService.class);
+ Intent intent = intentService.getIntent(Key.of(keyString, app));
+ if (intent == null) {
+ intent = intentService.getIntent(Key.of(Long.decode(keyString), app));
+ }
+ nullIsNotFound(intent, "Intent Id is not found");
+
+ if (intent instanceof OpticalConnectivityIntent) {
+ intentService.withdraw(intent);
+ } else {
+ throw new IllegalArgumentException("Specified intent is not of type OpticalConnectivityIntent");
+ }
+
+ return Response.noContent().build();
+ }
+
private Intent decode(ObjectNode json) {
JsonNode ingressJson = json.get(INGRESS_POINT);
if (!ingressJson.isObject()) {
@@ -139,9 +279,75 @@
String appIdString = nullIsIllegal(json.get(APP_ID), APP_ID + MISSING_MEMBER_MESSAGE).asText();
CoreService service = getService(CoreService.class);
ApplicationId appId = nullIsNotFound(service.getAppId(appIdString), E_APP_ID_NOT_FOUND);
+
Key key = null;
DeviceService deviceService = get(DeviceService.class);
- return createOpticalIntent(ingress, egress, deviceService, key, appId, bidirectional, signal);
+ JsonNode suggestedPathJson = json.get(SUGGESTEDPATH);
+ DefaultPath suggestedPath = null;
+ LinkService linkService = get(LinkService.class);
+
+ if (suggestedPathJson != null) {
+ if (!suggestedPathJson.isObject()) {
+ throw new IllegalArgumentException(JSON_INVALID);
+ } else {
+ ArrayNode linksJson = nullIsIllegal((ArrayNode) suggestedPathJson.get("links"),
+ "Suggested path specified without links");
+
+ List<Link> listLinks = new ArrayList<>();
+
+ for (JsonNode node : linksJson) {
+
+ String srcString = node.get("src").asText();
+ String dstString = node.get("dst").asText();
+
+ ConnectPoint srcConnectPoint = ConnectPoint.fromString(srcString);
+ ConnectPoint dstConnectPoint = ConnectPoint.fromString(dstString);
+
+ Link link = linkService.getLink(srcConnectPoint, dstConnectPoint);
+ if (link == null) {
+ throw new IllegalArgumentException("Not existing link in the suggested path");
+ }
+
+ listLinks.add(link);
+ }
+
+ if ((!listLinks.get(0).src().deviceId().equals(ingress.deviceId())) ||
+ (!listLinks.get(0).src().port().equals(ingress.port())) ||
+ (!listLinks.get(listLinks.size() - 1).dst().deviceId().equals(egress.deviceId())) ||
+ (!listLinks.get(listLinks.size() - 1).dst().port().equals(egress.port()))) {
+ throw new IllegalArgumentException(
+ "Suggested path not compatible with ingress or egress connect points");
+ }
+
+ if (!isPathContiguous(listLinks)) {
+ throw new IllegalArgumentException(
+ "Links specified in the suggested path are not contiguous");
+ }
+
+ suggestedPath = new DefaultPath(PROVIDER_ID, listLinks, new ScalarWeight(1));
+
+ log.debug("OpticalIntent along suggestedPath {}", suggestedPath);
+ }
+ }
+
+ return createExplicitOpticalIntent(
+ ingress, egress, deviceService, key, appId, bidirectional, signal, suggestedPath);
+ }
+
+ private boolean isPathContiguous(List<Link> path) {
+ DeviceId previousDst;
+ DeviceId currentSrc;
+
+ for (int i = 1; i < path.size(); i++) {
+ previousDst = path.get(i - 1).dst().deviceId();
+ currentSrc = path.get(i).src().deviceId();
+
+ if (!previousDst.equals(currentSrc)) {
+ log.debug("OpticalIntent links are not contiguous previous {} current {}", previousDst, currentSrc);
+ return false;
+ }
+ }
+ return true;
}
}
diff --git a/apps/optical-rest/src/main/resources/definitions/CreateIntent.json b/apps/optical-rest/src/main/resources/definitions/CreateIntent.json
index 5565a24..da4f215 100644
--- a/apps/optical-rest/src/main/resources/definitions/CreateIntent.json
+++ b/apps/optical-rest/src/main/resources/definitions/CreateIntent.json
@@ -8,7 +8,7 @@
"properties": {
"appId": {
"type": "string",
- "example": "org.onosproject.ovsdb"
+ "example": "org.onosproject.optical-rest"
},
"ingressPoint": {
"type": "object",
@@ -20,11 +20,11 @@
"properties": {
"device": {
"type": "string",
- "example": "of:0000000000000001"
+ "example": "netconf:10.255.255.14:2022"
},
"port": {
"type": "string",
- "example": "1"
+ "example": "101"
}
}
},
@@ -38,17 +38,17 @@
"properties": {
"device": {
"type": "string",
- "example": "of:0000000000000002"
+ "example": "netconf:10.255.255.17:2022"
},
"port": {
"type": "string",
- "example": "200"
+ "example": "201"
}
}
},
"bidirection": {
"type": "boolean",
- "example": true
+ "example": false
},
"signal": {
"type": "object",
@@ -62,12 +62,22 @@
"properties": {
"channelSpacing": {
"type": "string",
- "enum": ["CHL_100GHZ", "CHL_50GHZ", "CHL_25GHZ", "CHL_12P5GHZ", "CHL_6P25GHZ"],
+ "enum": [
+ "CHL_100GHZ",
+ "CHL_50GHZ",
+ "CHL_25GHZ",
+ "CHL_12P5GHZ",
+ "CHL_6P25GHZ"
+ ],
"example": "CHL_50GHZ"
},
"gridType": {
"type": "string",
- "enum": ["DWDM", "CWDM", "FLEX"],
+ "enum": [
+ "DWDM",
+ "CWDM",
+ "FLEX"
+ ],
"example": "DWDM"
},
"spacingMultiplier": {
@@ -81,6 +91,40 @@
"example": 4
}
}
+ },
+ "suggestedPath": {
+ "type": "object",
+ "title": "suggestedPath",
+ "required": [
+ "links"
+ ],
+ "properties": {
+ "links": {
+ "type": "array",
+ "title": "suggestedPath",
+ "required": [
+ "link"
+ ],
+ "items": {
+ "type": "object",
+ "title": "link",
+ "required": [
+ "src",
+ "dst"
+ ],
+ "properties" : {
+ "src": {
+ "type": "string",
+ "example": "netconf:10.255.255.14:2022/101"
+ },
+ "dst": {
+ "type": "string",
+ "example": "netconf:10.255.255.9:2022/201"
+ }
+ }
+ }
+ }
+ }
}
}
}
diff --git a/core/api/src/main/java/org/onosproject/net/intent/OpticalConnectivityIntent.java b/core/api/src/main/java/org/onosproject/net/intent/OpticalConnectivityIntent.java
index 7cf4411..59247e1 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/OpticalConnectivityIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/OpticalConnectivityIntent.java
@@ -22,6 +22,7 @@
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.ResourceGroup;
+import org.onosproject.net.Path;
import java.util.Collections;
import java.util.Optional;
@@ -31,6 +32,7 @@
/**
* An optical layer intent for connectivity between two OCh ports.
* No traffic selector or traffic treatment are needed.
+ * OchSignal and suggestedPath are optional.
*/
@Beta
public final class OpticalConnectivityIntent extends Intent {
@@ -38,7 +40,9 @@
private final ConnectPoint dst;
private final OduSignalType signalType;
private final boolean isBidirectional;
+
private final Optional<OchSignal> ochSignal;
+ private final Optional<Path> suggestedPath;
/**
* Creates an optical connectivity intent between the specified
@@ -51,6 +55,7 @@
* @param signalType signal type
* @param isBidirectional indicates if intent is unidirectional
* @param ochSignal optional OCh signal
+ * @param suggestedPath optional suggested path
* @param priority priority to use for flows from this intent
* @param resourceGroup resource group of this intent
*/
@@ -61,6 +66,7 @@
OduSignalType signalType,
boolean isBidirectional,
Optional<OchSignal> ochSignal,
+ Optional<Path> suggestedPath,
int priority,
ResourceGroup resourceGroup) {
super(appId, key, Collections.emptyList(), priority, resourceGroup);
@@ -69,6 +75,7 @@
this.signalType = checkNotNull(signalType);
this.isBidirectional = isBidirectional;
this.ochSignal = ochSignal;
+ this.suggestedPath = suggestedPath;
}
/**
@@ -90,6 +97,7 @@
private OduSignalType signalType;
private boolean isBidirectional;
private Optional<OchSignal> ochSignal = Optional.empty();
+ private Optional<Path> suggestedPath = Optional.empty();
@Override
public Builder appId(ApplicationId appId) {
@@ -167,6 +175,17 @@
}
/**
+ * Sets the suggestedPath of the intent.
+ *
+ * @param suggestedPath the path
+ * @return this builder
+ */
+ public Builder suggestedPath(Path suggestedPath) {
+ this.suggestedPath = Optional.ofNullable(suggestedPath);
+ return this;
+ }
+
+ /**
* Builds an optical connectivity intent from the accumulated parameters.
*
* @return point to point intent
@@ -181,6 +200,7 @@
signalType,
isBidirectional,
ochSignal,
+ suggestedPath,
priority,
resourceGroup
);
@@ -197,6 +217,7 @@
this.signalType = null;
this.isBidirectional = false;
this.ochSignal = null;
+ this.suggestedPath = null;
}
/**
@@ -240,10 +261,20 @@
*
* @return the lambda
*/
+
public Optional<OchSignal> ochSignal() {
return ochSignal;
}
+ /**
+ * Returns the suggestedPath of the intent.
+ *
+ * @return the suggestedPath
+ */
+ public Optional<Path> suggestedPath() {
+ return suggestedPath;
+ }
+
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
@@ -257,6 +288,7 @@
.add("signalType", signalType)
.add("isBidirectional", isBidirectional)
.add("ochSignal", ochSignal)
+ .add("suggestedPath", suggestedPath)
.add("resourceGroup", resourceGroup())
.toString();
}