[ONOS-5187] Compute path with Explicit path objects
Change-Id: Id34dbef9bd6cfa9971d0d10adf4bbc141f03a913
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/DefaultPcePath.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/DefaultPcePath.java
index f0472aa..4e7247a 100644
--- a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/DefaultPcePath.java
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/DefaultPcePath.java
@@ -18,14 +18,18 @@
import static com.google.common.base.MoreObjects.toStringHelper;
+import java.util.Collection;
+import java.util.List;
import java.util.Objects;
+import org.onlab.rest.BaseResource;
import org.onlab.util.DataRateUnit;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.onosproject.net.intent.Constraint;
import org.onosproject.pce.pceservice.constraint.CostConstraint;
+import org.onosproject.pce.pcestore.api.PceStore;
/**
* Implementation of an entity which provides functionalities of pce path.
@@ -39,6 +43,7 @@
private String name; // symbolic-path-name
private Constraint costConstraint; // cost constraint
private Constraint bandwidthConstraint; // bandwidth constraint
+ private Collection<ExplicitPathInfo> explicitPathInfo; //list of explicit path info
/**
* Initializes PCE path attributes.
@@ -50,10 +55,11 @@
* @param name symbolic-path-name
* @param costConstrnt cost constraint
* @param bandwidthConstrnt bandwidth constraint
+ * @param explicitPathInfo list of explicit path info
*/
private DefaultPcePath(TunnelId id, String src, String dst, LspType lspType,
- String name, Constraint costConstrnt, Constraint bandwidthConstrnt) {
-
+ String name, Constraint costConstrnt, Constraint bandwidthConstrnt,
+ Collection<ExplicitPathInfo> explicitPathInfo) {
this.id = id;
this.source = src;
this.destination = dst;
@@ -61,6 +67,7 @@
this.name = name;
this.costConstraint = costConstrnt;
this.bandwidthConstraint = bandwidthConstrnt;
+ this.explicitPathInfo = explicitPathInfo;
}
@Override
@@ -114,6 +121,11 @@
}
@Override
+ public Collection<ExplicitPathInfo> explicitPathInfo() {
+ return explicitPathInfo;
+ }
+
+ @Override
public PcePath copy(PcePath path) {
if (null != path.source()) {
this.source = path.source();
@@ -138,7 +150,8 @@
@Override
public int hashCode() {
- return Objects.hash(id, source, destination, lspType, name, costConstraint, bandwidthConstraint);
+ return Objects.hash(id, source, destination, lspType, name, costConstraint, bandwidthConstraint,
+ explicitPathInfo);
}
@Override
@@ -154,7 +167,8 @@
&& Objects.equals(lspType, that.lspType)
&& Objects.equals(name, that.name)
&& Objects.equals(costConstraint, that.costConstraint)
- && Objects.equals(bandwidthConstraint, that.bandwidthConstraint);
+ && Objects.equals(bandwidthConstraint, that.bandwidthConstraint)
+ && Objects.equals(explicitPathInfo, that.explicitPathInfo);
}
return false;
}
@@ -170,6 +184,7 @@
.add("name", name)
.add("costConstraint", costConstraint)
.add("bandwidthConstraint", bandwidthConstraint)
+ .add("explicitPathInfo", explicitPathInfo)
.toString();
}
@@ -185,7 +200,7 @@
/**
* Builder class for pce path.
*/
- public static final class Builder implements PcePath.Builder {
+ public static final class Builder extends BaseResource implements PcePath.Builder {
private TunnelId id;
private String source;
private String destination;
@@ -193,6 +208,7 @@
private String name;
private Constraint costConstraint;
private Constraint bandwidthConstraint;
+ private Collection<ExplicitPathInfo> explicitPathInfo;
@Override
public Builder id(String id) {
@@ -240,6 +256,12 @@
}
@Override
+ public Builder explicitPathInfo(Collection<ExplicitPathInfo> explicitPathInfo) {
+ this.explicitPathInfo = explicitPathInfo;
+ return this;
+ }
+
+ @Override
public Builder of(Tunnel tunnel) {
this.id = TunnelId.valueOf(tunnel.tunnelId().id());
this.source = tunnel.path().src().deviceId().toString();
@@ -264,13 +286,20 @@
DataRateUnit.valueOf("BPS"));
}
+ PceStore pceStore = get(PceStore.class);
+ List<ExplicitPathInfo> explicitPathInfoList = pceStore
+ .getTunnelNameExplicitPathInfoMap(tunnel.tunnelName().value());
+ if (explicitPathInfoList != null) {
+ this.explicitPathInfo = explicitPathInfoList;
+ }
+
return this;
}
@Override
public PcePath build() {
return new DefaultPcePath(id, source, destination, lspType, name,
- costConstraint, bandwidthConstraint);
+ costConstraint, bandwidthConstraint, explicitPathInfo);
}
}
}
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/ExplicitPathInfo.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/ExplicitPathInfo.java
new file mode 100644
index 0000000..52ef270
--- /dev/null
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/ExplicitPathInfo.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2016-present 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.pce.pceservice;
+
+import org.onosproject.net.NetworkResource;
+
+import com.google.common.annotations.Beta;
+
+import java.util.Objects;
+
+/**
+ * Representation of explicit path info consists of contraints (strict / loose) to compute path.
+ */
+@Beta
+public final class ExplicitPathInfo {
+
+ private final Type type;
+
+ //Can be Link or DeviceId
+ private final NetworkResource value;
+
+ public enum Type {
+ /**
+ * Signifies that path includes strict node or link.
+ */
+ STRICT(0),
+
+ /**
+ * Signifies that path includes loose node or link.
+ */
+ LOOSE(1);
+
+ int value;
+
+ /**
+ * Assign val with the value as the type.
+ *
+ * @param val type
+ */
+ Type(int val) {
+ value = val;
+ }
+
+ /**
+ * Returns value of type.
+ *
+ * @return type
+ */
+ public byte type() {
+ return (byte) value;
+ }
+ }
+
+ /**
+ * Creates instance of explicit path object.
+ *
+ * @param type specifies whether strict or loose node/link
+ * @param value specifies deviceId or link
+ */
+ public ExplicitPathInfo(Type type, NetworkResource value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ /**
+ * Returns explicit path type.
+ *
+ * @return explicit path type as strict/loose
+ */
+ public Type type() {
+ return type;
+ }
+
+ /**
+ * Returns deviceId or link.
+ *
+ * @return deviceId or link
+ */
+ public NetworkResource value() {
+ return value;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, value);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ExplicitPathInfo) {
+ final ExplicitPathInfo other = (ExplicitPathInfo) obj;
+ return Objects.equals(this.type, other.type)
+ && Objects.equals(this.value, other.value);
+ }
+ return false;
+ }
+}
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java
index a4c2aa6..9267dc2 100644
--- a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java
@@ -24,6 +24,7 @@
import java.util.List;
import java.util.Optional;
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;
@@ -48,9 +49,11 @@
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultAnnotations.Builder;
+import org.onosproject.net.DefaultPath;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
+import org.onosproject.net.NetworkResource;
import org.onosproject.net.Path;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.intent.Constraint;
@@ -86,6 +89,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.INIT;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
@@ -230,10 +234,177 @@
return ImmutableSet.of();
}
- //[TODO:] handle requests in queue
+ //Computes the partial path from partial computed path to specified dst.
+ private List<Path> computePartialPath(List<Path> computedPath, DeviceId src, DeviceId dst,
+ List<Constraint> constraints) {
+ int size = computedPath.size();
+ Path path = null;
+ DeviceId deviceId = size == 0 ? src :
+ computedPath.get(size - 1).dst().deviceId();
+
+ Set<Path> tempComputePath = computePath(deviceId, dst, constraints);
+ if (tempComputePath.isEmpty()) {
+ return null;
+ }
+
+ //if path validation fails return null
+ //Validate computed path to avoid loop in the path
+ for (Path p : tempComputePath) {
+ if (pathValidation(computedPath, p)) {
+ path = p;
+ break;
+ }
+ }
+ if (path == null) {
+ return null;
+ }
+
+ //Store the partial path result in a list
+ computedPath.add(path);
+ return computedPath;
+ }
+
+ private List<DeviceId> createListOfDeviceIds(List<? extends NetworkResource> list) {
+ List<Link> links = new LinkedList<>();
+ if (!list.isEmpty() && list.iterator().next() instanceof Path) {
+ for (Path path : (List<Path>) list) {
+ links.addAll(path.links());
+ }
+ } else if (!list.isEmpty() && list.iterator().next() instanceof Link) {
+ links.addAll((List<Link>) list);
+ }
+
+ //List of devices for new path computed
+ DeviceId source = null;
+ DeviceId destination = null;
+ List<DeviceId> devList = new LinkedList<>();
+
+ for (Link l : links) {
+ if (!devList.contains(l.src().deviceId())) {
+ devList.add(l.src().deviceId());
+ }
+ if (!devList.contains(l.dst().deviceId())) {
+ devList.add(l.dst().deviceId());
+ }
+ }
+
+ return devList;
+ }
+
+ //To dectect loops in the path i.e if the partial paths has intersection node avoid it.
+ private boolean pathValidation(List<Path> partialPath, Path path) {
+
+ //List of devices in new path computed
+ List<DeviceId> newPartialPathDevList;
+ newPartialPathDevList = createListOfDeviceIds(path.links());
+
+ //List of devices in partial computed path
+ List<DeviceId> partialComputedPathDevList;
+ partialComputedPathDevList = createListOfDeviceIds(partialPath);
+
+ for (DeviceId deviceId : newPartialPathDevList) {
+ for (DeviceId devId : partialComputedPathDevList) {
+ if (!newPartialPathDevList.get(0).equals(deviceId) &&
+ !partialComputedPathDevList.get(partialComputedPathDevList.size() - 1).equals(devId)
+ && deviceId.equals(devId)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ //Returns final computed explicit path (list of partial computed paths).
+ private List<Path> computeExplicitPath(List<ExplicitPathInfo> explicitPathInfo, DeviceId src, DeviceId dst,
+ List<Constraint> constraints) {
+ List<Path> finalComputedPath = new LinkedList<>();
+ for (ExplicitPathInfo info : explicitPathInfo) {
+ /*
+ * If explicit path object is LOOSE,
+ * 1) If specified as DeviceId (node) :
+ * If it is source , compute from source to destination (partial computation not required),
+ * otherwise compute from specified source to specified device
+ * 2) If specified as Link :
+ * Compute partial path from source to link's source , if path exists compute from link's source to dst
+ */
+ if (info.type().equals(ExplicitPathInfo.Type.LOOSE)) {
+ if (info.value() instanceof DeviceId) {
+ // If deviceId is source no need to compute
+ if (!(info.value()).equals(src)) {
+ finalComputedPath = computePartialPath(finalComputedPath, src, (DeviceId) info.value(),
+ constraints);
+ }
+
+ } else if (info.value() instanceof Link) {
+ if ((((Link) info.value()).src().deviceId().equals(src))
+ || (!finalComputedPath.isEmpty()
+ && finalComputedPath.get(finalComputedPath.size() - 1).dst().equals(
+ ((Link) info.value()).src().deviceId()))) {
+
+ finalComputedPath = computePartialPath(finalComputedPath, src, ((Link) info.value()).dst()
+ .deviceId(), constraints);
+ } else {
+
+ finalComputedPath = computePartialPath(finalComputedPath, src, ((Link) info.value()).src()
+ .deviceId(), constraints) != null ? computePartialPath(finalComputedPath, src,
+ ((Link) info.value()).dst().deviceId(), constraints) : null;
+ }
+ }
+ /*
+ * If explicit path object is STRICT,
+ * 1) If specified as DeviceId (node) :
+ * Check whether partial computed path has reachable to strict specified node or
+ * strict node is the source, if no set path as null else do nothing
+ * 2) If specified as Link :
+ * Check whether partial computed path has reachable to strict link's src, if yes compute
+ * path from strict link's src to link's dst (to include specified link)
+ */
+ } else if (info.type().equals(ExplicitPathInfo.Type.STRICT)) {
+ if (info.value() instanceof DeviceId) {
+ if (!(!finalComputedPath.isEmpty() && finalComputedPath.get(finalComputedPath.size() - 1).dst()
+ .deviceId().equals(info.value()))
+ && !info.value().equals(src)) {
+ finalComputedPath = null;
+ }
+
+ } else if (info.value() instanceof Link) {
+
+ finalComputedPath = ((Link) info.value()).src().deviceId().equals(src)
+ || !finalComputedPath.isEmpty()
+ && finalComputedPath.get(finalComputedPath.size() - 1).dst().deviceId()
+ .equals(((Link) info.value()).src().deviceId()) ? computePartialPath(
+ finalComputedPath, src, ((Link) info.value()).dst().deviceId(), constraints) : null;
+
+ }
+ }
+ if (finalComputedPath == null) {
+ return null;
+ }
+ }
+ // Destination is not reached in Partial computed path then compute till destination
+ if (finalComputedPath.isEmpty() || !finalComputedPath.isEmpty()
+ && !finalComputedPath.get(finalComputedPath.size() - 1).dst().deviceId().equals(dst)) {
+
+ finalComputedPath = computePartialPath(finalComputedPath, src, dst, constraints);
+ if (finalComputedPath == null) {
+ return null;
+ }
+ }
+
+ return finalComputedPath;
+ }
+
@Override
public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
LspType lspType) {
+ return setupPath(src, dst, tunnelName, constraints, lspType, null);
+ }
+
+ //[TODO:] handle requests in queue
+ @Override
+ public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
+ LspType lspType, List<ExplicitPathInfo> explicitPathInfo) {
checkNotNull(src);
checkNotNull(dst);
checkNotNull(tunnelName);
@@ -245,7 +416,7 @@
if (srcDevice == null || dstDevice == null) {
// Device is not known.
- pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType));
+ pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo));
return false;
}
@@ -255,7 +426,7 @@
if (srcLsrId == null || dstLsrId == null) {
// LSR id is not known.
- pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType));
+ pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo));
return false;
}
@@ -263,7 +434,7 @@
DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(srcLsrId), DeviceCapability.class);
if (cfg == null) {
log.debug("No session to ingress.");
- pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType));
+ pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo));
return false;
}
@@ -299,12 +470,30 @@
constraints = new LinkedList<>();
constraints.add(CapabilityConstraint.of(CapabilityType.valueOf(lspType.name())));
}
+ Set<Path> computedPathSet = Sets.newLinkedHashSet();
- Set<Path> computedPathSet = computePath(src, dst, constraints);
+ if (explicitPathInfo != null && !explicitPathInfo.isEmpty()) {
+ List<Path> finalComputedPath = computeExplicitPath(explicitPathInfo, src, dst, constraints);
+ if (finalComputedPath == null) {
+ return false;
+ }
+
+ pceStore.tunnelNameExplicitPathInfoMap(tunnelName, explicitPathInfo);
+ List<Link> links = new LinkedList<>();
+ double totalCost = 0;
+ // Add all partial computed paths
+ for (Path path : finalComputedPath) {
+ links.addAll(path.links());
+ totalCost = totalCost + path.cost();
+ }
+ computedPathSet.add(new DefaultPath(finalComputedPath.iterator().next().providerId(), links, totalCost));
+ } else {
+ computedPathSet = computePath(src, dst, constraints);
+ }
// NO-PATH
if (computedPathSet.isEmpty()) {
- pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType));
+ pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo));
return false;
}
@@ -339,14 +528,15 @@
if (bwConstraintValue != 0) {
consumerId = reserveBandwidth(computedPath, bwConstraintValue, null);
if (consumerId == null) {
- pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType));
+ pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints,
+ lspType, explicitPathInfo));
return false;
}
}
TunnelId tunnelId = tunnelService.setupTunnel(appId, src, tunnel, computedPath);
if (tunnelId == null) {
- pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType));
+ pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo));
if (consumerId != null) {
resourceService.release(consumerId);
}
@@ -363,7 +553,7 @@
@Override
public boolean updatePath(TunnelId tunnelId, List<Constraint> constraints) {
checkNotNull(tunnelId);
- Set<Path> computedPathSet = null;
+ Set<Path> computedPathSet = Sets.newLinkedHashSet();
Tunnel tunnel = tunnelService.queryTunnel(tunnelId);
if (tunnel == null) {
@@ -441,8 +631,30 @@
constraints.add(costConstraint);
}
- computedPathSet = computePath(links.get(0).src().deviceId(), links.get(links.size() - 1).dst().deviceId(),
- constraints);
+ List<ExplicitPathInfo> explicitPathInfo = pceStore
+ .getTunnelNameExplicitPathInfoMap(tunnel.tunnelName().value());
+ if (explicitPathInfo != null) {
+ List<Path> finalComputedPath = computeExplicitPath(explicitPathInfo,
+ tunnel.path().src().deviceId(), tunnel.path().dst().deviceId(),
+ constraints);
+
+ if (finalComputedPath == null) {
+ return false;
+ }
+
+ List<Link> totalLinks = new LinkedList<>();
+ double totalCost = 0;
+ //Add all partial computed paths
+ for (Path path : finalComputedPath) {
+ totalLinks.addAll(path.links());
+ totalCost = totalCost + path.cost();
+ }
+ computedPathSet.add(new DefaultPath(finalComputedPath.iterator().next().providerId(),
+ totalLinks, totalCost));
+ } else {
+ computedPathSet = computePath(tunnel.path().src().deviceId(), tunnel.path().dst().deviceId(),
+ constraints);
+ }
// NO-PATH
if (computedPathSet.isEmpty()) {
@@ -636,7 +848,8 @@
// then PCInitiate (Remove)
pceStore.addFailedPathInfo(new PcePathInfo(tunnel.path().src().deviceId(), tunnel
.path().dst().deviceId(), tunnel.tunnelName().value(), constraintList,
- LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE))));
+ LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)),
+ pceStore.getTunnelNameExplicitPathInfoMap(tunnel.tunnelName().value())));
//Release that tunnel calling PCInitiate
releasePath(tunnel.tunnelId());
}
@@ -832,7 +1045,9 @@
List<Link> links = tunnel.path().links();
pceStore.addFailedPathInfo(new PcePathInfo(links.get(0).src().deviceId(),
links.get(links.size() - 1).dst().deviceId(),
- tunnel.tunnelName().value(), constraints, lspType));
+ tunnel.tunnelName().value(), constraints, lspType,
+ pceStore.getTunnelNameExplicitPathInfoMap(tunnel
+ .tunnelName().value())));
}
break;
@@ -861,6 +1076,11 @@
}
}
+ @Override
+ public List<ExplicitPathInfo> explicitPathInfoList(String tunnelName) {
+ return pceStore.getTunnelNameExplicitPathInfoMap(tunnelName);
+ }
+
//Computes path from tunnel store and also path failed to setup.
private void callForOptimization() {
//Recompute the LSPs which it was delegated [LSPs stored in PCE store (failed paths)]
@@ -880,7 +1100,7 @@
*/
if (mastershipService.isLocalMaster(failedPathInfo.src())) {
if (setupPath(failedPathInfo.src(), failedPathInfo.dst(), failedPathInfo.name(),
- failedPathInfo.constraints(), failedPathInfo.lspType())) {
+ failedPathInfo.constraints(), failedPathInfo.lspType(), failedPathInfo.explicitPathInfo())) {
// If computation is success remove that path
pceStore.removeFailedPathInfo(failedPathInfo);
return true;
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PcePath.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PcePath.java
index ec4e257..038ac5b 100644
--- a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PcePath.java
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PcePath.java
@@ -19,7 +19,8 @@
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.net.intent.Constraint;
-import org.onosproject.pce.pceservice.DefaultPcePath.Builder;
+
+import java.util.Collection;
/**
* Abstraction of an entity which provides functionalities of pce path.
@@ -97,6 +98,13 @@
Constraint bandwidthConstraint();
/**
+ * Returns the list of explicit path objects.
+ *
+ * @return list of explicit path objects
+ */
+ Collection<ExplicitPathInfo> explicitPathInfo();
+
+ /**
* Copies only non-null or non-zero member variables.
*
* @param id path-id
@@ -174,6 +182,14 @@
Builder of(Tunnel tunnel);
/**
+ * Returns the builder object of ExplicitPathInfo.
+ *
+ * @param explicitPathInfo list of explicit path obj
+ * @return builder object of ExplicitPathInfo
+ */
+ Builder explicitPathInfo(Collection<ExplicitPathInfo> explicitPathInfo);
+
+ /**
* Builds object of pce path.
*
* @return object of pce path.
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/api/PceService.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/api/PceService.java
index f2d3622..fdfdb73 100644
--- a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/api/PceService.java
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/api/PceService.java
@@ -19,6 +19,7 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.intent.Constraint;
+import org.onosproject.pce.pceservice.ExplicitPathInfo;
import org.onosproject.pce.pceservice.LspType;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelId;
@@ -42,6 +43,20 @@
boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints, LspType lspType);
/**
+ * Creates new path based on constraints and LSP type.
+ *
+ * @param src source device
+ * @param dst destination device
+ * @param tunnelName name of the tunnel
+ * @param constraints list of constraints to be applied on path
+ * @param lspType type of path to be setup
+ * @param explicitPathInfo list of explicit path info
+ * @return false on failure and true on successful path creation
+ */
+ boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints, LspType lspType,
+ List<ExplicitPathInfo> explicitPathInfo);
+
+ /**
* Updates an existing path.
*
* @param tunnelId tunnel identifier
@@ -72,4 +87,12 @@
* @return tunnel if path exists, otherwise null
*/
Tunnel queryPath(TunnelId tunnelId);
+
+ /**
+ * Returns list of explicit path info.
+ *
+ * @param tunnelName tunnel name
+ * @return list of explicit path info
+ */
+ List<ExplicitPathInfo> explicitPathInfoList(String tunnelName);
}
\ No newline at end of file