Avantika-Huawei

[ONOS-4170] [ONOS-4163] PCE APP side changes : PceManager (code + UT)

Change-Id: I43db98b2fa3c5930b989d4fa3e2c00f7fa65c5ca
(cherry picked from commit dbdf7723)
......@@ -23,13 +23,24 @@ import java.util.List;
import java.util.ListIterator;
import java.util.LinkedList;
import org.onlab.packet.MplsLabel;
import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.resource.label.DefaultLabelResource;
import org.onosproject.incubator.net.resource.label.LabelResource;
import org.onosproject.incubator.net.resource.label.LabelResourceId;
import org.onosproject.incubator.net.resource.label.LabelResourceService;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
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.FlowObjectiveService;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.pce.pcestore.api.PceStore;
import org.onosproject.pce.pcestore.api.LspLocalLabelInfo;
import org.onosproject.pce.pcestore.PceccTunnelInfo;
......@@ -58,6 +69,8 @@ public final class BasicPceccHandler {
private static BasicPceccHandler crHandlerInstance = null;
private LabelResourceService labelRsrcService;
private PceStore pceStore;
private FlowObjectiveService flowObjectiveService;
private ApplicationId appId;
/**
* Initializes default values.
......@@ -83,8 +96,11 @@ public final class BasicPceccHandler {
* @param labelRsrcService label resource service
* @param pceStore pce label store
*/
public void initialize(LabelResourceService labelRsrcService, PceStore pceStore) {
public void initialize(LabelResourceService labelRsrcService, FlowObjectiveService flowObjectiveService,
ApplicationId appId, PceStore pceStore) {
this.labelRsrcService = labelRsrcService;
this.flowObjectiveService = flowObjectiveService;
this.appId = appId;
this.pceStore = pceStore;
}
......@@ -106,8 +122,8 @@ public final class BasicPceccHandler {
if ((linkList != null) && (linkList.size() > 0)) {
// Sequence through reverse order to push local labels into devices
// Generation of labels from egress to ingress
for (ListIterator iterator = linkList.listIterator(linkList.size()); iterator.hasPrevious();) {
Link link = (Link) iterator.previous();
for (ListIterator<Link> iterator = linkList.listIterator(linkList.size()); iterator.hasPrevious();) {
Link link = iterator.previous();
DeviceId dstDeviceId = link.dst().deviceId();
DeviceId srcDeviceId = link.src().deviceId();
labelRscList = labelRsrcService.applyFromDevicePool(dstDeviceId, applyNum);
......@@ -131,16 +147,14 @@ public final class BasicPceccHandler {
}
// Push into destination device
//TODO: uncomment below lines once installLocalLabelRule() method is ready
// Destination device IN port is link.dst().port()
//installLocalLabelRule(dstDeviceId, labelId, dstPort, tunnel.tunnelId(), isLastLabelToPush,
// LabelType.IN, Objective.Operation.ADD);
installLocalLabelRule(dstDeviceId, labelId, dstPort, tunnel.tunnelId(), isLastLabelToPush,
Long.valueOf(LabelType.IN_LABEL.value), Objective.Operation.ADD);
// Push into source device
//TODO: uncomment below lines once installLocalLabelRule() method is ready
// Source device OUT port will be link.dst().port(). Means its remote port used to send packet.
//installLocalLabelRule(srcDeviceId, labelId, dstPort, tunnel.tunnelId(), isLastLabelToPush,
// LabelType.OUT, Objective.Operation.ADD);
installLocalLabelRule(srcDeviceId, labelId, dstPort, tunnel.tunnelId(), isLastLabelToPush,
Long.valueOf(LabelType.OUT_LABEL.value), Objective.Operation.ADD);
// Add or update pcecc tunnel info in pce store.
updatePceccTunnelInfoInStore(srcDeviceId, dstDeviceId, labelId, dstPort,
......@@ -183,7 +197,7 @@ public final class BasicPceccHandler {
if ((lspLabelInfoList != null) && (lspLabelInfoList.size() > 0)) {
for (int i = 0; i < lspLabelInfoList.size(); ++i) {
LspLocalLabelInfo lspLocalLabelInfo =
(DefaultLspLocalLabelInfo) lspLabelInfoList.get(i);
lspLabelInfoList.get(i);
LspLocalLabelInfo.Builder lspLocalLabelInfoBuilder = null;
if (dstDeviceId.equals(lspLocalLabelInfo.deviceId())) {
lspLocalLabelInfoBuilder = DefaultLspLocalLabelInfo.builder(lspLocalLabelInfo);
......@@ -264,7 +278,7 @@ public final class BasicPceccHandler {
List<LspLocalLabelInfo> lspLocalLabelInfoList = pceccTunnelInfo.lspLocalLabelInfoList();
if ((lspLocalLabelInfoList != null) && (lspLocalLabelInfoList.size() > 0)) {
for (Iterator<LspLocalLabelInfo> iterator = lspLocalLabelInfoList.iterator(); iterator.hasNext();) {
LspLocalLabelInfo lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
LspLocalLabelInfo lspLocalLabelInfo = iterator.next();
DeviceId deviceId = lspLocalLabelInfo.deviceId();
LabelResourceId inLabelId = lspLocalLabelInfo.inLabelId();
LabelResourceId outLabelId = lspLocalLabelInfo.outLabelId();
......@@ -278,15 +292,13 @@ public final class BasicPceccHandler {
// Push into device
if ((inLabelId != null) && (inPort != null)) {
//TODO: uncomment below lines once installLocalLabelRule() method is ready
//installLocalLabelRule(deviceId, inLabelId, inPort, tunnelId, isLastLabelToPush,
// LabelType.IN, Objective.Operation.REMOVE);
installLocalLabelRule(deviceId, inLabelId, inPort, tunnel.tunnelId(), isLastLabelToPush,
Long.valueOf(LabelType.IN_LABEL.value), Objective.Operation.REMOVE);
}
if ((outLabelId != null) && (outPort != null)) {
//TODO: uncomment below lines once installLocalLabelRule() method is ready
//installLocalLabelRule(deviceId, outLabelId, outPort, tunnelId, isLastLabelToPush,
// LabelType.OUT, Objective.Operation.REMOVE);
installLocalLabelRule(deviceId, outLabelId, outPort, tunnel.tunnelId(), isLastLabelToPush,
Long.valueOf(LabelType.OUT_LABEL.value), Objective.Operation.REMOVE);
}
// List is stored from egress to ingress. So, using IN label id to release.
......@@ -315,4 +327,35 @@ public final class BasicPceccHandler {
log.error("Unable to find PCECC tunnel info in store for a tunnel {}.", tunnel.toString());
}
}
// Install a rule for pushing local labels to the device which is specific to path.
private void installLocalLabelRule(DeviceId deviceId, LabelResourceId labelId,
PortNumber portNum, TunnelId tunnelId,
Boolean isBos, Long labelType,
Objective.Operation type) {
checkNotNull(flowObjectiveService);
checkNotNull(appId);
TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
selectorBuilder.matchMplsLabel(MplsLabel.mplsLabel(labelId.id().intValue()));
selectorBuilder.matchInPort(portNum);
selectorBuilder.matchTunnelId(Long.parseLong(tunnelId.id()));
selectorBuilder.matchMplsBos(isBos);
selectorBuilder.matchMetadata(labelType);
TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
ForwardingObjective.Builder forwardingObjective = DefaultForwardingObjective.builder()
.withSelector(selectorBuilder.build())
.withTreatment(treatment)
.withFlag(ForwardingObjective.Flag.VERSATILE)
.fromApp(appId)
.makePermanent();
if (type.equals(Objective.Operation.ADD)) {
flowObjectiveService.forward(deviceId, forwardingObjective.add());
} else {
flowObjectiveService.forward(deviceId, forwardingObjective.remove());
}
}
}
......
......@@ -16,11 +16,15 @@
package org.onosproject.pce.pceservice;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.felix.scr.annotations.Activate;
......@@ -29,22 +33,53 @@ import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.util.Bandwidth;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
import org.onosproject.incubator.net.resource.label.LabelResourceId;
import org.onosproject.incubator.net.resource.label.LabelResourceService;
import org.onosproject.core.IdGenerator;
import org.onosproject.incubator.net.tunnel.DefaultTunnel;
import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
import org.onosproject.incubator.net.tunnel.LabelStack;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
import org.onosproject.incubator.net.tunnel.TunnelEvent;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelListener;
import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultAnnotations.Builder;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
import org.onosproject.pce.pceservice.constraint.CapabilityConstraint.CapabilityType;
import org.onosproject.pce.pceservice.constraint.CostConstraint;
import org.onosproject.pce.pceservice.constraint.SharedBandwidthConstraint;
import org.onosproject.net.resource.Resource;
import org.onosproject.net.resource.ResourceAllocation;
import org.onosproject.net.resource.ResourceConsumer;
import org.onosproject.net.resource.ResourceQueryService;
import org.onosproject.net.resource.ResourceService;
import org.onosproject.net.resource.Resources;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.PathService;
import org.onosproject.net.topology.TopologyEdge;
import org.onosproject.pce.pceservice.api.PceService;
import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
import org.onosproject.pce.pcestore.PcePathInfo;
import org.onosproject.pce.pcestore.PceccTunnelInfo;
import org.onosproject.pce.pcestore.api.PceStore;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.DistributedSet;
import org.onosproject.store.service.Serializer;
......@@ -53,6 +88,29 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.INIT;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.ESTABLISHED;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
import static org.onosproject.pce.pceservice.LspType.WITH_SIGNALLING;
import static org.onosproject.pce.pceservice.LspType.SR_WITHOUT_SIGNALLING;
import static org.onosproject.pce.pceservice.LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.BANDWIDTH;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LOCAL_LSP_ID;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LSP_SIG_TYPE;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PCE_INIT;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PLSP_ID;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PCC_TUNNEL_ID;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.DELEGATE;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.COST_TYPE;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
/**
* Implementation of PCE service.
......@@ -63,8 +121,17 @@ public class PceManager implements PceService {
private static final Logger log = LoggerFactory.getLogger(PceManager.class);
public static final String PCE_SERVICE_APP = "org.onosproject.pce";
private static final String LOCAL_LSP_ID_GEN_TOPIC = "pcep-local-lsp-id";
private static final int PREFIX_LENGTH = 32;
private static final String TUNNEL_CONSUMER_ID_GEN_TOPIC = "pcep-tunnel-consumer-id";
private IdGenerator tunnelConsumerIdGen;
private static final String LSRID = "lsrId";
private static final String TRUE = "true";
private static final String FALSE = "false";
private static final String END_OF_SYNC_IP_PREFIX = "0.0.0.0/32";
private IdGenerator localLspIdIdGen;
protected DistributedSet<Short> localLspIdFreeList;
......@@ -72,22 +139,45 @@ public class PceManager implements PceService {
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected TunnelService tunnelService;
protected ResourceService resourceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
protected ResourceQueryService resourceQueryService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PathService pathService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ResourceService resourceService;
protected PceStore pceStore;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected TunnelService tunnelService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PacketService packetService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LabelResourceAdminService labelRsrcAdminService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LabelResourceService labelRsrcService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowObjectiveService flowObjectiveService;
private TunnelListener listener = new InnerTunnelListener();
private BasicPceccHandler crHandler;
private PceccSrTeBeHandler srTeHandler;
private ApplicationId appId;
private final PcepPacketProcessor processor = new PcepPacketProcessor();
/**
* Creates new instance of PceManager.
*/
......@@ -97,18 +187,30 @@ public class PceManager implements PceService {
@Activate
protected void activate() {
appId = coreService.registerApplication(PCE_SERVICE_APP);
log.info("Started");
crHandler = BasicPceccHandler.getInstance();
crHandler.initialize(labelRsrcService, flowObjectiveService, appId, pceStore);
srTeHandler = PceccSrTeBeHandler.getInstance();
srTeHandler.initialize(labelRsrcAdminService, labelRsrcService, flowObjectiveService, appId, pceStore);
tunnelService.addListener(listener);
tunnelConsumerIdGen = coreService.getIdGenerator(TUNNEL_CONSUMER_ID_GEN_TOPIC);
localLspIdIdGen = coreService.getIdGenerator(LOCAL_LSP_ID_GEN_TOPIC);
localLspIdFreeList = storageService.<Short>setBuilder()
.withName("pcepLocalLspIdDeletedList")
.withSerializer(Serializer.using(KryoNamespaces.API))
.build()
.asDistributedSet();
packetService.addProcessor(processor, PacketProcessor.director(4));
log.info("Started");
}
@Deactivate
protected void deactivate() {
tunnelService.removeListener(listener);
packetService.removeProcessor(processor);
log.info("Stopped");
}
......@@ -133,13 +235,13 @@ public class PceManager implements PceService {
*/
protected Set<Path> computePath(DeviceId src, DeviceId dst, List<Constraint> constraints) {
if (pathService == null) {
return null;
return ImmutableSet.of();
}
Set<Path> paths = pathService.getPaths(src, dst, weight(constraints));
if (!paths.isEmpty()) {
return paths;
}
return null;
return ImmutableSet.of();
}
//[TODO:] handle requests in queue
......@@ -149,22 +251,264 @@ public class PceManager implements PceService {
checkNotNull(src);
checkNotNull(dst);
checkNotNull(tunnelName);
checkNotNull(constraints);
checkNotNull(lspType);
// TODO: compute and setup path.
//TODO: gets the path based on constraints and creates a tunnel in network via tunnel manager
return computePath(src, dst, constraints) != null ? true : false;
// Convert from DeviceId to TunnelEndPoint
Device srcDevice = deviceService.getDevice(src);
Device dstDevice = deviceService.getDevice(dst);
if (srcDevice == null || dstDevice == null) {
// Device is not known.
pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType));
return false;
}
// In future projections instead of annotations will be used to fetch LSR ID.
String srcLsrId = srcDevice.annotations().value(LSRID);
String dstLsrId = dstDevice.annotations().value(LSRID);
if (srcLsrId == null || dstLsrId == null) {
// LSR id is not known.
pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType));
return false;
}
TunnelEndPoint srcEndPoint = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(srcLsrId));
TunnelEndPoint dstEndPoint = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(dstLsrId));
double bwConstraintValue = 0;
CostConstraint costConstraint = null;
if (constraints != null) {
constraints.add(CapabilityConstraint.of(CapabilityType.valueOf(lspType.name())));
Iterator<Constraint> iterator = constraints.iterator();
while (iterator.hasNext()) {
Constraint constraint = iterator.next();
if (constraint instanceof BandwidthConstraint) {
bwConstraintValue = ((BandwidthConstraint) constraint).bandwidth().bps();
} else if (constraint instanceof CostConstraint) {
costConstraint = (CostConstraint) constraint;
}
}
/*
* Add cost at the end of the list of constraints. The path computation algorithm also computes cumulative
* cost. The function which checks the limiting/capability constraints also returns per link cost. This
* function can either return the result of limiting/capability constraint validation or the value of link
* cost, depending upon what is the last constraint in the loop.
*/
if (costConstraint != null) {
constraints.remove(costConstraint);
constraints.add(costConstraint);
}
} else {
constraints = new LinkedList<>();
constraints.add(CapabilityConstraint.of(CapabilityType.valueOf(lspType.name())));
}
Set<Path> computedPathSet = computePath(src, dst, constraints);
// NO-PATH
if (computedPathSet.isEmpty()) {
pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType));
return false;
}
Builder annotationBuilder = DefaultAnnotations.builder();
if (bwConstraintValue != 0) {
annotationBuilder.set(BANDWIDTH, String.valueOf(bwConstraintValue));
}
if (costConstraint != null) {
annotationBuilder.set(COST_TYPE, String.valueOf(costConstraint.type()));
}
annotationBuilder.set(LSP_SIG_TYPE, lspType.name());
annotationBuilder.set(PCE_INIT, TRUE);
annotationBuilder.set(DELEGATE, TRUE);
Path computedPath = computedPathSet.iterator().next();
LabelStack labelStack = null;
if (lspType == SR_WITHOUT_SIGNALLING) {
labelStack = srTeHandler.computeLabelStack(computedPath);
// Failed to form a label stack.
if (labelStack == null) {
pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType));
return false;
}
}
if (lspType != WITH_SIGNALLING) {
/*
* Local LSP id which is assigned by RSVP for RSVP signalled LSPs, will be assigned by
* PCE for non-RSVP signalled LSPs.
*/
annotationBuilder.set(LOCAL_LSP_ID, String.valueOf(getNextLocalLspId()));
}
// For SR-TE tunnels, call SR manager for label stack and put it inside tunnel.
Tunnel tunnel = new DefaultTunnel(null, srcEndPoint, dstEndPoint, MPLS, INIT, null, null,
TunnelName.tunnelName(tunnelName), computedPath,
labelStack, annotationBuilder.build());
// Allocate bandwidth.
TunnelConsumerId consumerId = null;
if (bwConstraintValue != 0) {
consumerId = reserveBandwidth(computedPath, bwConstraintValue, null);
if (consumerId == null) {
pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType));
return false;
}
}
TunnelId tunnelId = tunnelService.setupTunnel(appId, src, tunnel, computedPath);
if (tunnelId == null) {
pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType));
if (consumerId != null) {
resourceService.release(consumerId);
}
return false;
}
if (consumerId != null) {
// Store tunnel consumer id in LSP-Label store.
PceccTunnelInfo pceccTunnelInfo = new PceccTunnelInfo(null, consumerId);
pceStore.addTunnelInfo(tunnelId, pceccTunnelInfo);
}
return true;
}
@Override
public boolean updatePath(TunnelId tunnelId, List<Constraint> constraints) {
checkNotNull(tunnelId);
checkNotNull(constraints);
Set<Path> computedPathSet = null;
Tunnel tunnel = tunnelService.queryTunnel(tunnelId);
if (tunnel == null) {
return false;
}
if (tunnel.type() != MPLS || FALSE.equalsIgnoreCase(tunnel.annotations().value(DELEGATE))) {
// Only delegated LSPs can be updated.
return false;
}
List<Link> links = tunnel.path().links();
String lspSigType = tunnel.annotations().value(LSP_SIG_TYPE);
double bwConstraintValue = 0;
SharedBandwidthConstraint shBwConstraint = null;
BandwidthConstraint bwConstraint = null;
CostConstraint costConstraint = null;
if (constraints != null) {
// Call path computation in shared bandwidth mode.
Iterator<Constraint> iterator = constraints.iterator();
while (iterator.hasNext()) {
Constraint constraint = iterator.next();
if (constraint instanceof BandwidthConstraint) {
bwConstraint = (BandwidthConstraint) constraint;
bwConstraintValue = bwConstraint.bandwidth().bps();
} else if (constraint instanceof CostConstraint) {
costConstraint = (CostConstraint) constraint;
}
}
// Remove and keep the cost constraint at the end of the list of constraints.
if (costConstraint != null) {
constraints.remove(costConstraint);
}
// TODO: compute and update path.
Bandwidth existingBwValue = null;
String existingBwAnnotation = tunnel.annotations().value(BANDWIDTH);
if (existingBwAnnotation != null) {
existingBwValue = Bandwidth.bps(Double.parseDouble(existingBwAnnotation));
/*
* The computation is a shared bandwidth constraint based, so need to remove bandwidth constraint which
* has been utilized to create shared bandwidth constraint.
*/
if (bwConstraint != null) {
constraints.remove(bwConstraint);
}
}
if (existingBwValue != null) {
shBwConstraint = new SharedBandwidthConstraint(links, existingBwValue, bwConstraint.bandwidth());
constraints.add(shBwConstraint);
}
} else {
constraints = new LinkedList<>();
}
constraints.add(CapabilityConstraint.of(CapabilityType.valueOf(lspSigType)));
if (costConstraint != null) {
constraints.add(costConstraint);
}
computedPathSet = computePath(links.get(0).src().deviceId(), links.get(links.size() - 1).dst().deviceId(),
constraints);
// NO-PATH
if (computedPathSet.isEmpty()) {
return false;
}
Builder annotationBuilder = DefaultAnnotations.builder();
annotationBuilder.set(BANDWIDTH, String.valueOf(bwConstraintValue));
annotationBuilder.set(LSP_SIG_TYPE, lspSigType);
annotationBuilder.set(PCE_INIT, TRUE);
annotationBuilder.set(DELEGATE, TRUE);
annotationBuilder.set(PLSP_ID, tunnel.annotations().value(PLSP_ID));
annotationBuilder.set(PCC_TUNNEL_ID, tunnel.annotations().value(PCC_TUNNEL_ID));
Path computedPath = computedPathSet.iterator().next();
LabelStack labelStack = null;
TunnelConsumerId consumerId = null;
LspType lspType = LspType.valueOf(lspSigType);
long localLspId = 0;
if (lspType != WITH_SIGNALLING) {
/*
* Local LSP id which is assigned by RSVP for RSVP signalled LSPs, will be assigned by
* PCE for non-RSVP signalled LSPs.
*/
localLspId = getNextLocalLspId();
annotationBuilder.set(LOCAL_LSP_ID, String.valueOf(localLspId));
if (lspType == SR_WITHOUT_SIGNALLING) {
labelStack = srTeHandler.computeLabelStack(computedPath);
// Failed to form a label stack.
if (labelStack == null) {
return false;
}
}
}
Tunnel updatedTunnel = new DefaultTunnel(null, tunnel.src(), tunnel.dst(), MPLS, INIT, null, null,
tunnel.tunnelName(), computedPath,
labelStack, annotationBuilder.build());
// Allocate shared bandwidth.
if (bwConstraintValue != 0) {
consumerId = reserveBandwidth(computedPath, bwConstraintValue, shBwConstraint);
if (consumerId == null) {
return false;
}
}
TunnelId updatedTunnelId = tunnelService.setupTunnel(appId, links.get(0).src().deviceId(), updatedTunnel,
computedPath);
if (updatedTunnelId == null) {
if (consumerId != null) {
resourceService.release(consumerId);
}
return false;
}
if (consumerId != null) {
// Store tunnel consumer id in LSP-Label store.
PceccTunnelInfo pceccTunnelInfo = new PceccTunnelInfo(null, consumerId);
pceStore.addTunnelInfo(updatedTunnelId, pceccTunnelInfo);
}
return true;
}
......@@ -249,4 +593,281 @@ public class PceManager implements PceService {
return cost;
}
}
// Allocates the bandwidth locally for PCECC tunnels.
private TunnelConsumerId reserveBandwidth(Path computedPath, double bandwidthConstraint,
SharedBandwidthConstraint shBwConstraint) {
checkNotNull(computedPath);
checkNotNull(bandwidthConstraint);
Resource resource = null;
double bwToAllocate = 0;
TunnelConsumerId consumer = TunnelConsumerId.valueOf(tunnelConsumerIdGen.getNewId());
/**
* Shared bandwidth sub-case : Lesser bandwidth required than original -
* No reservation required.
*/
Double additionalBwValue = null;
if (shBwConstraint != null) {
additionalBwValue = ((bandwidthConstraint - shBwConstraint.sharedBwValue().bps()) <= 0) ? null
: (bandwidthConstraint - shBwConstraint.sharedBwValue().bps());
}
Optional<ResourceAllocation> resAlloc = null;
for (Link link : computedPath.links()) {
bwToAllocate = 0;
if ((shBwConstraint != null) && (shBwConstraint.links().contains(link))) {
if (additionalBwValue != null) {
bwToAllocate = bandwidthConstraint - additionalBwValue;
}
} else {
bwToAllocate = bandwidthConstraint;
}
/**
* In shared bandwidth cases, where new BW is lesser than old BW, it
* is not required to allocate anything.
*/
if (bwToAllocate != 0) {
resource = Resources.continuous(link.src().deviceId(), link.src().port(), Bandwidth.class)
.resource(bwToAllocate);
resAlloc = resourceService.allocate(consumer, resource);
// If allocation for any link fails, then release the partially allocated bandwidth.
if (!resAlloc.isPresent()) {
resourceService.release(consumer);
return null;
}
}
}
/*
* Note: Storing of tunnel consumer id is done by caller of bandwidth reservation function. So deleting tunnel
* consumer id should be done by caller of bandwidth releasing function. This will prevent ambiguities related
* to who is supposed to store/delete.
*/
return consumer;
}
/*
* Deallocates the bandwidth which is reserved locally for PCECC tunnels.
*/
private void releaseBandwidth(Tunnel tunnel) {
// Between same source and destination, search the tunnel with same symbolic path name.
Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnel.src(), tunnel.dst());
Tunnel newTunnel = null;
for (Tunnel tunnelObj : tunnelQueryResult) {
if (tunnel.tunnelName().value().equals(tunnelObj.tunnelName().value())) {
newTunnel = tunnelObj;
break;
}
}
// Even if one link is shared, the bandwidth release should happen based on shared mechanism.
boolean isLinkShared = false;
if (newTunnel != null) {
for (Link link : tunnel.path().links()) {
if (newTunnel.path().links().contains(link)) {
isLinkShared = true;
break;
}
}
}
if (isLinkShared) {
releaseSharedBandwidth(newTunnel, tunnel);
return;
}
resourceService.release(pceStore.getTunnelInfo(tunnel.tunnelId()).tunnelConsumerId());
return;
/*
* Note: Storing of tunnel consumer id is done by caller of bandwidth reservation function. So deleting tunnel
* consumer id should be done by caller of bandwidth releasing function. This will prevent ambiguities related
* to who is supposed to store/delete.
*/
}
/**
* Re-allocates the bandwidth for the tunnel for which the bandwidth was
* allocated in shared mode initially.
*/
private synchronized void releaseSharedBandwidth(Tunnel newTunnel, Tunnel oldTunnel) {
// 1. Release old tunnel's bandwidth.
resourceService.release(pceStore.getTunnelInfo(oldTunnel.tunnelId()).tunnelConsumerId());
// 2. Release new tunnel's bandwidth
ResourceConsumer consumer = pceStore.getTunnelInfo(newTunnel.tunnelId()).tunnelConsumerId();
resourceService.release(consumer);
// 3. Allocate new tunnel's complete bandwidth.
double bandwidth = Double.parseDouble(newTunnel.annotations().value(BANDWIDTH));
Resource resource;
for (Link link : newTunnel.path().links()) {
resource = Resources.continuous(link.src().deviceId(), link.src().port(), Bandwidth.class)
.resource(bandwidth);
resourceService.allocate(consumer, resource); // Reusing new tunnel's TunnelConsumerId intentionally.
}
}
// Listens on tunnel events.
private class InnerTunnelListener implements TunnelListener {
@Override
public void event(TunnelEvent event) {
// Event gets generated with old tunnel object.
Tunnel tunnel = event.subject();
if (tunnel.type() != MPLS) {
return;
}
LspType lspType = LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE));
String tunnelBandwidth = tunnel.annotations().value(BANDWIDTH);
double bwConstraintValue = 0;
if (tunnelBandwidth != null) {
bwConstraintValue = Double.parseDouble(tunnelBandwidth);
}
switch (event.type()) {
case TUNNEL_ADDED:
// Allocate bandwidth for non-initiated, delegated LSPs with non-zero bandwidth (learned LSPs).
String pceInit = tunnel.annotations().value(PCE_INIT);
if (FALSE.equalsIgnoreCase(pceInit)
&& bwConstraintValue != 0) {
reserveBandwidth(tunnel.path(), bwConstraintValue, null);
}
break;
case TUNNEL_UPDATED:
// Allocate/send labels for basic PCECC tunnels.
if ((tunnel.state() == ESTABLISHED) && (lspType == WITHOUT_SIGNALLING_AND_WITHOUT_SR)) {
crHandler.allocateLabel(tunnel);
}
if (tunnel.state() == UNSTABLE) {
/*
* During LSP DB sync if PCC doesn't report LSP which was PCE initiated, it's state is turned into
* unstable so that it can be setup again. Add into failed path store so that it can be recomputed
* and setup while global reoptimization.
*/
List<Constraint> constraints = new LinkedList<>();
String bandwidth = tunnel.annotations().value(BANDWIDTH);
if (bandwidth != null) {
constraints.add(new BandwidthConstraint(Bandwidth
.bps(Double.parseDouble(bandwidth))));
}
String costType = tunnel.annotations().value(COST_TYPE);
if (costType != null) {
CostConstraint costConstraint = new CostConstraint(CostConstraint.Type.valueOf(costType));
constraints.add(costConstraint);
}
constraints.add(CapabilityConstraint
.of(CapabilityType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE))));
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));
}
break;
case TUNNEL_REMOVED:
if (lspType != WITH_SIGNALLING) {
localLspIdFreeList.add(Short.valueOf(tunnel.annotations().value(LOCAL_LSP_ID)));
}
// If not zero bandwidth, and delegated (initiated LSPs will also be delegated).
if (bwConstraintValue != 0) {
releaseBandwidth(event.subject());
// Release basic PCECC labels.
if (lspType == WITHOUT_SIGNALLING_AND_WITHOUT_SR) {
// Delete stored tunnel consumer id from PCE store (while still retaining label list.)
PceccTunnelInfo pceccTunnelInfo = pceStore.getTunnelInfo(tunnel.tunnelId());
pceccTunnelInfo.tunnelConsumerId(null);
crHandler.releaseLabel(tunnel);
} else {
pceStore.removeTunnelInfo(tunnel.tunnelId());
}
}
break;
default:
break;
}
return;
}
}
private boolean syncLabelDb(DeviceId deviceId) {
checkNotNull(deviceId);
Map<DeviceId, LabelResourceId> globalNodeLabelMap = pceStore.getGlobalNodeLabels();
for (Entry<DeviceId, LabelResourceId> entry : globalNodeLabelMap.entrySet()) {
// Convert from DeviceId to TunnelEndPoint
Device srcDevice = deviceService.getDevice(entry.getKey());
/*
* If there is a slight difference in timing such that if device subsystem has removed the device but PCE
* store still has it, just ignore such devices.
*/
if (srcDevice == null) {
continue;
}
String srcLsrId = srcDevice.annotations().value(LSRID);
if (srcLsrId == null) {
continue;
}
srTeHandler.advertiseNodeLabelRule(deviceId,
entry.getValue(),
IpPrefix.valueOf(IpAddress.valueOf(srcLsrId), PREFIX_LENGTH),
Objective.Operation.ADD, false);
}
Map<Link, LabelResourceId> adjLabelMap = pceStore.getAdjLabels();
for (Entry<Link, LabelResourceId> entry : adjLabelMap.entrySet()) {
if (entry.getKey().src().deviceId().equals(deviceId)) {
srTeHandler.installAdjLabelRule(deviceId,
entry.getValue(),
entry.getKey().src().port(),
entry.getKey().dst().port(),
Objective.Operation.ADD);
}
}
srTeHandler.advertiseNodeLabelRule(deviceId,
LabelResourceId.labelResourceId(0),
IpPrefix.valueOf(END_OF_SYNC_IP_PREFIX),
Objective.Operation.ADD, true);
return true;
}
// Process the packet received.
private class PcepPacketProcessor implements PacketProcessor {
// Process the packet received and in our case initiates the label DB sync.
@Override
public void process(PacketContext context) {
// Stop processing if the packet has been handled, since we
// can't do any more to it.
if (context.isHandled()) {
return;
}
InboundPacket pkt = context.inPacket();
syncLabelDb(pkt.receivedFrom().deviceId());
}
}
}
\ No newline at end of file
......
......@@ -25,6 +25,11 @@ import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.TpPort;
import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.resource.label.DefaultLabelResource;
import org.onosproject.incubator.net.resource.label.LabelResource;
import org.onosproject.incubator.net.resource.label.LabelResourceId;
......@@ -36,7 +41,15 @@ import org.onosproject.net.DeviceId;
import org.onosproject.pce.pcestore.api.PceStore;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
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.FlowObjectiveService;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.Objective;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -67,7 +80,9 @@ public final class PceccSrTeBeHandler {
private static PceccSrTeBeHandler srTeHandlerInstance = null;
private LabelResourceAdminService labelRsrcAdminService;
private LabelResourceService labelRsrcService;
private FlowObjectiveService flowObjectiveService;
private PceStore pceStore;
private ApplicationId appId;
/**
* Initializes default values.
......@@ -95,10 +110,14 @@ public final class PceccSrTeBeHandler {
* @param pceStore PCE label store
*/
public void initialize(LabelResourceAdminService labelRsrcAdminService,
LabelResourceService labelRsrcService, PceStore pceStore) {
LabelResourceService labelRsrcService,
FlowObjectiveService flowObjectiveService,
ApplicationId appId, PceStore pceStore) {
this.labelRsrcAdminService = labelRsrcAdminService;
this.labelRsrcService = labelRsrcService;
this.flowObjectiveService = flowObjectiveService;
this.pceStore = pceStore;
this.appId = appId;
}
/**
......@@ -152,15 +171,15 @@ public final class PceccSrTeBeHandler {
}
pceStore.addGlobalNodeLabel(specificDeviceId, specificLabelId);
//TODO: uncomment below line once advertiseNodeLabelRule() is ready
// Push its label information into specificDeviceId
//advertiseNodeLabelRule(specificDeviceId, specificLabelId,
// IpPrefix.valueOf(IpAddress.valueOf(specificLsrId), PREFIX_LENGTH),
advertiseNodeLabelRule(specificDeviceId, specificLabelId,
IpPrefix.valueOf(IpAddress.valueOf(specificLsrId), PREFIX_LENGTH),
Objective.Operation.ADD, false);
// Configure (node-label, lsr-id) mapping of each devices in list to specific device and vice versa.
for (Map.Entry element:deviceIdLsrIdMap.entrySet()) {
DeviceId otherDevId = (DeviceId) element.getKey();
String otherLsrId = (String) element.getValue();
for (Map.Entry<DeviceId, String> element:deviceIdLsrIdMap.entrySet()) {
DeviceId otherDevId = element.getKey();
String otherLsrId = element.getValue();
if (otherLsrId == null) {
log.error("The lsr-id of device id {} is null.", otherDevId.toString());
releaseNodeLabel(specificDeviceId, specificLsrId, deviceIdLsrIdMap);
......@@ -176,12 +195,11 @@ public final class PceccSrTeBeHandler {
}
// Push to device
// TODO: uncomment below line once advertiseNodeLabelRule() is ready
// Push label information of specificDeviceId to otherDevId in list and vice versa.
//advertiseNodeLabelRule(otherDevId, specificLabelId, IpPrefix.valueOf(IpAddress.valueOf(specificLsrId),
// PREFIX_LENGTH), Objective.Operation.ADD);
//advertiseNodeLabelRule(specificDeviceId, otherLabelId, IpPrefix.valueOf(IpAddress.valueOf(otherLsrId),
// PREFIX_LENGTH), Objective.Operation.ADD);
advertiseNodeLabelRule(otherDevId, specificLabelId, IpPrefix.valueOf(IpAddress.valueOf(specificLsrId),
PREFIX_LENGTH), Objective.Operation.ADD, false);
advertiseNodeLabelRule(specificDeviceId, otherLabelId, IpPrefix.valueOf(IpAddress.valueOf(otherLsrId),
PREFIX_LENGTH), Objective.Operation.ADD, false);
}
return true;
......@@ -214,15 +232,14 @@ public final class PceccSrTeBeHandler {
}
// Go through all devices in the map and remove label entry
for (Map.Entry element:deviceIdLsrIdMap.entrySet()) {
DeviceId otherDevId = (DeviceId) element.getKey();
for (Map.Entry<DeviceId, String> element:deviceIdLsrIdMap.entrySet()) {
DeviceId otherDevId = element.getKey();
// Remove this specific device label information from all other nodes except
// this specific node where connection already lost.
if (!specificDeviceId.equals(otherDevId)) {
//TODO: uncomment below lines once advertiseNodeLabelRule() is ready
//advertiseNodeLabelRule(otherDevId, labelId, IpPrefix.valueOf(IpAddress.valueOf(specificLsrId),
// PREFIX_LENGTH), Objective.Operation.REMOVE);
advertiseNodeLabelRule(otherDevId, labelId, IpPrefix.valueOf(IpAddress.valueOf(specificLsrId),
PREFIX_LENGTH), Objective.Operation.REMOVE, false);
}
}
......@@ -278,8 +295,7 @@ public final class PceccSrTeBeHandler {
link.toString());
// Push adjacency label to device
//TODO: uncomment below line once installAdjLabelRule() method is ready
//installAdjLabelRule(srcDeviceId, labelId, link.src().port(), link.dst().port(), Objective.Operation.ADD);
installAdjLabelRule(srcDeviceId, labelId, link.src().port(), link.dst().port(), Objective.Operation.ADD);
// Save in store
pceStore.addAdjLabel(link, labelId);
......@@ -309,8 +325,7 @@ public final class PceccSrTeBeHandler {
DeviceId srcDeviceId = link.src().deviceId();
// Release adjacency label from device
//TODO: uncomment below line once installAdjLabelRule() method is ready
//installAdjLabelRule(srcDeviceId, labelId, link.src().port(), link.dst().port(), Objective.Operation.REMOVE);
installAdjLabelRule(srcDeviceId, labelId, link.src().port(), link.dst().port(), Objective.Operation.REMOVE);
// Release link label from label manager
Multimap<DeviceId, LabelResource> release = ArrayListMultimap.create();
......@@ -350,7 +365,7 @@ public final class PceccSrTeBeHandler {
LabelResourceId adjLabelId = null;
DeviceId deviceId = null;
for (Iterator<Link> iterator = linkList.iterator(); iterator.hasNext();) {
link = (Link) iterator.next();
link = iterator.next();
// Add source device label now
deviceId = link.src().deviceId();
nodeLabelId = pceStore.getGlobalNodeLabel(deviceId);
......@@ -386,4 +401,109 @@ public final class PceccSrTeBeHandler {
}
return new DefaultLabelStack(labelStack);
}
/**
* Install a rule for pushing unique global labels to the device.
* @param deviceId device to which flow should be pushed
* @param labelId label for the device
* @param type type of operation
*/
private void installNodeLabelRule(DeviceId deviceId, LabelResourceId labelId, Objective.Operation type) {
checkNotNull(flowObjectiveService);
checkNotNull(appId);
TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
selectorBuilder.matchMplsLabel(MplsLabel.mplsLabel(labelId.id().intValue()));
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.build();
ForwardingObjective.Builder forwardingObjective = DefaultForwardingObjective.builder()
.withSelector(selectorBuilder.build())
.withTreatment(treatment)
.withFlag(ForwardingObjective.Flag.VERSATILE)
.fromApp(appId)
.makePermanent();
if (type.equals(Objective.Operation.ADD)) {
flowObjectiveService.forward(deviceId, forwardingObjective.add());
} else {
flowObjectiveService.forward(deviceId, forwardingObjective.remove());
}
}
/**
* Install a rule for pushing node labels to the device of other nodes.
* @param deviceId device to which flow should be pushed
* @param labelId label for the device
* @param ipPrefix device for which label is pushed
* @param type type of operation
* @param bBos is this the end of sync push
*/
public void advertiseNodeLabelRule(DeviceId deviceId, LabelResourceId labelId,
IpPrefix ipPrefix, Objective.Operation type, boolean bBos) {
checkNotNull(flowObjectiveService);
checkNotNull(appId);
TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
selectorBuilder.matchMplsLabel(MplsLabel.mplsLabel(labelId.id().intValue()));
selectorBuilder.matchIPSrc(ipPrefix);
if (bBos) {
selectorBuilder.matchMplsBos(bBos);
}
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.build();
ForwardingObjective.Builder forwardingObjective = DefaultForwardingObjective.builder()
.withSelector(selectorBuilder.build())
.withTreatment(treatment)
.withFlag(ForwardingObjective.Flag.VERSATILE)
.fromApp(appId)
.makePermanent();
if (type.equals(Objective.Operation.ADD)) {
flowObjectiveService.forward(deviceId, forwardingObjective.add());
} else {
flowObjectiveService.forward(deviceId, forwardingObjective.remove());
}
}
/**
* Install a rule for pushing Adjacency labels to the device.
* @param deviceId device to which flow should be pushed
* @param labelId label for the adjacency
* @param srcPortNum local port of the adjacency
* @param dstPortNum remote port of the adjacency
* @param type type of operation
*/
public void installAdjLabelRule(DeviceId deviceId, LabelResourceId labelId,
PortNumber srcPortNum, PortNumber dstPortNum,
Objective.Operation type) {
checkNotNull(flowObjectiveService);
checkNotNull(appId);
TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
selectorBuilder.matchMplsLabel(MplsLabel.mplsLabel(labelId.id().intValue()));
selectorBuilder.matchTcpSrc(TpPort.tpPort((int) srcPortNum.toLong()));
selectorBuilder.matchTcpDst(TpPort.tpPort((int) dstPortNum.toLong()));
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.build();
ForwardingObjective.Builder forwardingObjective = DefaultForwardingObjective.builder()
.withSelector(selectorBuilder.build())
.withTreatment(treatment)
.withFlag(ForwardingObjective.Flag.VERSATILE)
.fromApp(appId)
.makePermanent();
if (type.equals(Objective.Operation.ADD)) {
flowObjectiveService.forward(deviceId, forwardingObjective.add());
} else {
flowObjectiveService.forward(deviceId, forwardingObjective.remove());
}
}
}
......
/*
* 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;
/**
* Collection of keys for annotation for PCEP tunnels.
*/
public final class PcepAnnotationKeys {
/**
* Prohibits instantiation.
*/
private PcepAnnotationKeys() {
}
/**
* Annotation key for bandwidth.
* The value for this key is interpreted as Mbps.
*/
public static final String BANDWIDTH = "bandwidth";
/**
* Annotation key for the LSP signaling type.
*/
public static final String LSP_SIG_TYPE = "lspSigType";
/**
* Annotation key for the PCC tunnel id.
*/
public static final String PCC_TUNNEL_ID = "PccTunnelId";
/**
* Annotation key for the LSP id assigned per tunnel per session.
*/
public static final String PLSP_ID = "PLspId";
/**
* Annotation key for the LSP id assigned per tunnel.
*/
public static final String LOCAL_LSP_ID = "localLspId";
/**
* Annotation key for the identification of initiated LSP.
*/
public static final String PCE_INIT = "pceInit";
/**
* Annotation key for the cost type.
*/
public static final String COST_TYPE = "costType";
/**
* Annotation key for the Delegation.
* Whether LSPs are delegated or not.
*/
public static final String DELEGATE = "delegate";
}
......@@ -15,6 +15,7 @@
*/
package org.onosproject.pce.pceservice;
import org.onlab.util.Identifier;
import org.onosproject.net.resource.ResourceConsumer;
import com.google.common.annotations.Beta;
......@@ -25,9 +26,7 @@ import org.onosproject.net.resource.ResourceConsumerId;
* resource allocations.
*/
@Beta
public final class TunnelConsumerId implements ResourceConsumer {
private final long value;
public final class TunnelConsumerId extends Identifier<Long> implements ResourceConsumer {
/**
* Creates a tunnel resource consumer identifier from the specified long value.
......@@ -43,7 +42,7 @@ public final class TunnelConsumerId implements ResourceConsumer {
* Initializes object for serializer.
*/
public TunnelConsumerId() {
this.value = 0;
super(0L);
}
/**
......@@ -54,43 +53,25 @@ public final class TunnelConsumerId implements ResourceConsumer {
* resource consumer id
*/
public TunnelConsumerId(long value) {
this.value = value;
super(value);
}
/**
* Returns the tunnel resource consumer id value in long format.
* Returns the backing identifier value.
*
* @return value the tunnel resource consumer id's long value
* @return value backing identifier value
*/
public long value() {
return value;
}
@Override
public int hashCode() {
return Long.hashCode(value);
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof TunnelConsumerId)) {
return false;
}
TunnelConsumerId that = (TunnelConsumerId) obj;
return this.value == that.value;
return identifier;
}
@Override
public String toString() {
return "0x" + Long.toHexString(value);
return "0x" + Long.toHexString(identifier);
}
@Override
public ResourceConsumerId consumerId() {
// TODO
return null;
return ResourceConsumerId.of(this);
}
}
......
/*
* Copyright 2016 Open Networking Laboratory
* 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.
......
......@@ -31,6 +31,8 @@ import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.DefaultGroupId;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
......@@ -45,11 +47,11 @@ import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.Path;
import org.onosproject.pce.pcestore.api.LspLocalLabelInfo;
import org.onosproject.pce.pcestore.api.PceStore;
import org.onosproject.pce.pcestore.PceccTunnelInfo;
import org.onosproject.pce.pcestore.DefaultLspLocalLabelInfo;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pce.util.LabelResourceAdapter;
import org.onosproject.pce.util.PceStoreAdapter;
......@@ -67,6 +69,9 @@ public class BasicPceccHandlerTest {
private BasicPceccHandler pceccHandler;
protected LabelResourceService labelRsrcService;
protected PceStore pceStore;
private FlowObjectiveService flowObjectiveService;
private CoreService coreService;
private ApplicationId appId;
private TunnelEndPoint src = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(23423));
private TunnelEndPoint dst = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(32421));
private DefaultGroupId groupId = new DefaultGroupId(92034);
......@@ -92,7 +97,10 @@ public class BasicPceccHandlerTest {
pceccHandler = BasicPceccHandler.getInstance();
labelRsrcService = new LabelResourceAdapter();
pceStore = new PceStoreAdapter();
pceccHandler.initialize(labelRsrcService, pceStore);
flowObjectiveService = new PceManagerTest.MockFlowObjService();
coreService = new PceManagerTest.MockCoreService();
appId = coreService.registerApplication("org.onosproject.pce");
pceccHandler.initialize(labelRsrcService, flowObjectiveService, appId, pceStore);
// Cretae tunnel test
// Link
......@@ -190,7 +198,7 @@ public class BasicPceccHandlerTest {
iterator = lspLocalLabelInfoList.iterator();
// Retrieve values and check device5
lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
lspLocalLabelInfo = iterator.next();
deviceId = lspLocalLabelInfo.deviceId();
inLabelId = lspLocalLabelInfo.inLabelId();
outLabelId = lspLocalLabelInfo.outLabelId();
......@@ -205,7 +213,7 @@ public class BasicPceccHandlerTest {
// Next element check
// Retrieve values and check device4
lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
lspLocalLabelInfo = iterator.next();
deviceId = lspLocalLabelInfo.deviceId();
inLabelId = lspLocalLabelInfo.inLabelId();
outLabelId = lspLocalLabelInfo.outLabelId();
......@@ -220,7 +228,7 @@ public class BasicPceccHandlerTest {
// Next element check
// Retrieve values and check device3
lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
lspLocalLabelInfo = iterator.next();
deviceId = lspLocalLabelInfo.deviceId();
inLabelId = lspLocalLabelInfo.inLabelId();
outLabelId = lspLocalLabelInfo.outLabelId();
......@@ -235,7 +243,7 @@ public class BasicPceccHandlerTest {
// Next element check
// Retrieve values and check device2
lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
lspLocalLabelInfo = iterator.next();
deviceId = lspLocalLabelInfo.deviceId();
inLabelId = lspLocalLabelInfo.inLabelId();
outLabelId = lspLocalLabelInfo.outLabelId();
......@@ -250,7 +258,7 @@ public class BasicPceccHandlerTest {
// Next element check
// Retrieve values and check device1
lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
lspLocalLabelInfo = iterator.next();
deviceId = lspLocalLabelInfo.deviceId();
inLabelId = lspLocalLabelInfo.inLabelId();
outLabelId = lspLocalLabelInfo.outLabelId();
......
......@@ -96,20 +96,20 @@ public class PathComputationTest {
private final MockDeviceService deviceService = new MockDeviceService();
private PceManager pceManager = new PceManager();
public static ProviderId providerId = new ProviderId("pce", "foo");
private static final String DEVICE1 = "D001";
private static final String DEVICE2 = "D002";
private static final String DEVICE3 = "D003";
private static final String DEVICE4 = "D004";
private static final String DEVICE5 = "D005";
public static final String DEVICE1 = "D001";
public static final String DEVICE2 = "D002";
public static final String DEVICE3 = "D003";
public static final String DEVICE4 = "D004";
public static final String DEVICE5 = "D005";
public static final String PCEPDEVICE1 = "PD001";
public static final String PCEPDEVICE2 = "PD002";
public static final String PCEPDEVICE3 = "PD003";
public static final String PCEPDEVICE4 = "PD004";
private static final TopologyVertex D1 = new DefaultTopologyVertex(DeviceId.deviceId("D001"));
private static final TopologyVertex D2 = new DefaultTopologyVertex(DeviceId.deviceId("D002"));
private static final TopologyVertex D3 = new DefaultTopologyVertex(DeviceId.deviceId("D003"));
private static final TopologyVertex D4 = new DefaultTopologyVertex(DeviceId.deviceId("D004"));
private static final TopologyVertex D5 = new DefaultTopologyVertex(DeviceId.deviceId("D005"));
public static final TopologyVertex D1 = new DefaultTopologyVertex(DeviceId.deviceId("D001"));
public static final TopologyVertex D2 = new DefaultTopologyVertex(DeviceId.deviceId("D002"));
public static final TopologyVertex D3 = new DefaultTopologyVertex(DeviceId.deviceId("D003"));
public static final TopologyVertex D4 = new DefaultTopologyVertex(DeviceId.deviceId("D004"));
public static final TopologyVertex D5 = new DefaultTopologyVertex(DeviceId.deviceId("D005"));
private static final String ANNOTATION_COST = "cost";
private static final String ANNOTATION_TE_COST = "teCost";
private static final String UNKNOWN = "unknown";
......@@ -130,7 +130,7 @@ public class PathComputationTest {
*
* @return graph path search algorithm
*/
private AbstractGraphPathSearch<TopologyVertex, TopologyEdge> graphSearch() {
public static AbstractGraphPathSearch<TopologyVertex, TopologyEdge> graphSearch() {
return new DijkstraGraphSearch<>();
}
......@@ -143,7 +143,7 @@ public class PathComputationTest {
* @param port2 destination port
* @return link
*/
private Link addLink(String device, long port, String device2, long port2, boolean setCost, int value) {
public static Link addLink(String device, long port, String device2, long port2, boolean setCost, int value) {
ConnectPoint src = new ConnectPoint(DeviceId.deviceId(device), PortNumber.portNumber(port));
ConnectPoint dst = new ConnectPoint(DeviceId.deviceId(device2), PortNumber.portNumber(port2));
Link curLink;
......@@ -256,19 +256,37 @@ public class PathComputationTest {
}
}
private Path networkPath(org.onlab.graph.Path<TopologyVertex, TopologyEdge> path) {
/**
* Returns the path in Path object format.
*/
public static Path networkPath(org.onlab.graph.Path<TopologyVertex, TopologyEdge> path) {
List<Link> links = path.edges().stream().map(TopologyEdge::link).collect(Collectors.toList());
return new DefaultPath(CORE_PROVIDER_ID, links, path.cost());
}
/**
* Test Resource service for path computation.
* Tests Resource service for path computation.
*/
private class MockPathResourceService extends ResourceServiceAdapter {
public class MockPathResourceService extends ResourceServiceAdapter {
private final Map<Resource, ResourceConsumer> assignment = new HashMap<>();
private Map<ResourceId, List<ResourceAllocation>> resourcesAllocations = new HashMap<>();
@Override
public Optional<ResourceAllocation> allocate(ResourceConsumer consumer, Resource resources) {
List<ResourceAllocation> allocations = allocate(consumer, ImmutableList.of(resources));
if (allocations.isEmpty()) {
return Optional.empty();
}
assert allocations.size() == 1;
ResourceAllocation allocation = allocations.get(0);
assert allocation.resource().equals(resources);
// cast is ensured by the assertions above
return Optional.of(allocation);
}
@Override
public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<Resource> resources) {
for (Resource resource: resources) {
if (resource instanceof ContinuousResource) {
......
package org.onosproject.pce.pceservice;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
import static org.onosproject.net.Link.State.ACTIVE;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.COST;
import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.TE_COST;
import static org.onosproject.net.resource.Resources.continuous;
import static org.onosproject.pce.pceservice.LspType.SR_WITHOUT_SIGNALLING;
import static org.onosproject.pce.pceservice.LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
import static org.onosproject.pce.pceservice.LspType.WITH_SIGNALLING;
import static org.onosproject.pce.pceservice.PathComputationTest.D1;
import static org.onosproject.pce.pceservice.PathComputationTest.D2;
import static org.onosproject.pce.pceservice.PathComputationTest.D3;
import static org.onosproject.pce.pceservice.PathComputationTest.D4;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LOCAL_LSP_ID;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PLSP_ID;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.ESTABLISHED;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.graph.GraphPathSearch;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.util.Bandwidth;
import org.onosproject.common.DefaultTopologyGraph;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.core.IdGenerator;
import org.onosproject.incubator.net.resource.label.LabelResourceId;
import org.onosproject.incubator.net.resource.label.LabelResourceService;
import org.onosproject.incubator.net.tunnel.DefaultTunnel;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.Tunnel.State;
import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
import org.onosproject.incubator.net.tunnel.TunnelEvent;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelListener;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.Device;
import org.onosproject.net.DefaultAnnotations.Builder;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.IntentId;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.onosproject.net.packet.DefaultInboundPacket;
import org.onosproject.net.packet.DefaultPacketContext;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.packet.PacketServiceAdapter;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.resource.Resource;
import org.onosproject.net.topology.DefaultTopologyEdge;
import org.onosproject.net.topology.DefaultTopologyVertex;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.PathServiceAdapter;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyEdge;
import org.onosproject.net.topology.TopologyGraph;
import org.onosproject.net.topology.TopologyServiceAdapter;
import org.onosproject.net.topology.TopologyVertex;
import org.onosproject.pce.pceservice.PathComputationTest.MockPathResourceService;
import org.onosproject.pce.pceservice.constraint.CostConstraint;
import org.onosproject.pce.pcestore.api.PceStore;
import org.onosproject.pce.util.LabelResourceAdapter;
import org.onosproject.pce.util.PceStoreAdapter;
import org.onosproject.pce.util.TunnelServiceAdapter;
import org.onosproject.pce.util.FlowObjServiceAdapter;
import org.onosproject.store.service.TestStorageService;
import com.google.common.collect.ImmutableSet;
/**
* Tests the functions of PceManager.
*/
public class PceManagerTest {
private PathComputationTest pathCompTest = new PathComputationTest();
private MockPathResourceService resourceService = pathCompTest.new MockPathResourceService();
private MockTopologyService topologyService = new MockTopologyService();
private MockPathService pathService = new MockPathService();
private PceManager pceManager = new PceManager();
private MockCoreService coreService = new MockCoreService();
private MockTunnelServiceAdapter tunnelService = new MockTunnelServiceAdapter();
private TestStorageService storageService = new TestStorageService();
private PacketService packetService = new MockPacketService();
private MockDeviceService deviceService = new MockDeviceService();
private MockFlowObjService flowObjectiveService = new MockFlowObjService();
private PceStore pceStore = new PceStoreAdapter();
private LabelResourceService labelResourceService = new LabelResourceAdapter();
public static ProviderId providerId = new ProviderId("pce", "foo");
private static final String L3 = "L3";
private static final String LSRID = "lsrId";
private static final String PCECC_CAPABILITY = "pceccCapability";
private static final String SR_CAPABILITY = "srCapability";
private static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
private TopologyGraph graph = null;
private Device deviceD1, deviceD2, deviceD3, deviceD4;
private Device pcepDeviceD1, pcepDeviceD2, pcepDeviceD3, pcepDeviceD4;
private Link link1, link2, link3, link4;
private static int flowsDownloaded;
private TunnelListener tunnelListener;
@Before
public void startUp() {
pceManager.pathService = pathService;
pceManager.resourceService = resourceService;
pceManager.tunnelService = tunnelService;
pceManager.coreService = coreService;
pceManager.storageService = storageService;
pceManager.packetService = packetService;
pceManager.deviceService = deviceService;
pceManager.labelRsrcService = labelResourceService;
pceManager.flowObjectiveService = flowObjectiveService;
pceManager.pceStore = pceStore;
pceManager.activate();
}
private void build4RouterTopo(boolean setCost, boolean setPceccCap, boolean setSrCap,
boolean setLabelStackCap, int bandwidth) {
Set<TopologyVertex> vertexes = new HashSet<TopologyVertex>();
vertexes.add(D1);
vertexes.add(D2);
vertexes.add(D3);
vertexes.add(D4);
Set<TopologyEdge> edges = new HashSet<TopologyEdge>();
link1 = PathComputationTest.addLink(D1.deviceId().toString(), 10, D2.deviceId().toString(), 20, setCost, 50);
TopologyEdge edge1 = new DefaultTopologyEdge(D1, D2, link1);
edges.add(edge1);
link2 = PathComputationTest.addLink(D2.deviceId().toString(), 30, D4.deviceId().toString(), 40, setCost, 20);
TopologyEdge edge2 = new DefaultTopologyEdge(D2, D4, link2);
edges.add(edge2);
link3 = PathComputationTest.addLink(D1.deviceId().toString(), 80, D3.deviceId().toString(), 70, setCost, 100);
TopologyEdge edge3 = new DefaultTopologyEdge(D1, D3, link3);
edges.add(edge3);
link4 = PathComputationTest.addLink(D3.deviceId().toString(), 60, D4.deviceId().toString(), 50, setCost, 80);
TopologyEdge edge4 = new DefaultTopologyEdge(D3, D4, link4);
edges.add(edge4);
graph = new DefaultTopologyGraph(vertexes, edges);
DefaultAnnotations.Builder builderDev1 = DefaultAnnotations.builder();
DefaultAnnotations.Builder builderDev2 = DefaultAnnotations.builder();
DefaultAnnotations.Builder builderDev3 = DefaultAnnotations.builder();
DefaultAnnotations.Builder builderDev4 = DefaultAnnotations.builder();
builderDev1.set(AnnotationKeys.TYPE, L3);
builderDev1.set(LSRID, "1.1.1.1");
builderDev2.set(AnnotationKeys.TYPE, L3);
builderDev2.set(LSRID, "2.2.2.2");
builderDev3.set(AnnotationKeys.TYPE, L3);
builderDev3.set(LSRID, "3.3.3.3");
builderDev4.set(AnnotationKeys.TYPE, L3);
builderDev4.set(LSRID, "4.4.4.4");
if (setSrCap) {
builderDev1.set(SR_CAPABILITY, "true");
builderDev2.set(SR_CAPABILITY, "true");
builderDev3.set(SR_CAPABILITY, "true");
builderDev4.set(SR_CAPABILITY, "true");
}
if (setPceccCap) {
builderDev1.set(PCECC_CAPABILITY, "true");
builderDev2.set(PCECC_CAPABILITY, "true");
builderDev3.set(PCECC_CAPABILITY, "true");
builderDev4.set(PCECC_CAPABILITY, "true");
}
if (setLabelStackCap) {
builderDev1.set(LABEL_STACK_CAPABILITY, "true");
builderDev2.set(LABEL_STACK_CAPABILITY, "true");
builderDev3.set(LABEL_STACK_CAPABILITY, "true");
builderDev4.set(LABEL_STACK_CAPABILITY, "true");
}
deviceD1 = new MockDevice(D1.deviceId(), builderDev1.build());
deviceD2 = new MockDevice(D2.deviceId(), builderDev2.build());
deviceD3 = new MockDevice(D3.deviceId(), builderDev3.build());
deviceD4 = new MockDevice(D4.deviceId(), builderDev4.build());
deviceService.addDevice(deviceD1);
deviceService.addDevice(deviceD2);
deviceService.addDevice(deviceD3);
deviceService.addDevice(deviceD4);
pcepDeviceD1 = new MockDevice(DeviceId.deviceId(PathComputationTest.PCEPDEVICE1), builderDev1.build());
deviceService.addDevice(pcepDeviceD1);
pcepDeviceD2 = new MockDevice(DeviceId.deviceId(PathComputationTest.PCEPDEVICE2), builderDev1.build());
deviceService.addDevice(pcepDeviceD2);
pcepDeviceD3 = new MockDevice(DeviceId.deviceId(PathComputationTest.PCEPDEVICE3), builderDev1.build());
deviceService.addDevice(pcepDeviceD3);
pcepDeviceD4 = new MockDevice(DeviceId.deviceId(PathComputationTest.PCEPDEVICE4), builderDev1.build());
deviceService.addDevice(pcepDeviceD4);
if (bandwidth != 0) {
List<Resource> resources = new LinkedList<>();
resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(bandwidth));
resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(bandwidth));
resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(bandwidth));
resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(bandwidth));
resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(bandwidth));
resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(bandwidth));
resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(bandwidth));
resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(bandwidth));
resourceService.allocate(IntentId.valueOf(bandwidth), resources);
}
}
/**
* Tests path success with (IGP) cost constraint for signalled LSP.
*/
@Test
public void setupPathTest1() {
build4RouterTopo(true, false, false, false, 0); // IGP cost is set here.
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(COST);
constraints.add(costConstraint);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(true));
}
/**
* Tests path failure with (IGP) cost constraint for signalled LSP.
*/
@Test
public void setupPathTest2() {
build4RouterTopo(false, false, false, false, 0); // TE cost is set here, not IGP.
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(COST);
constraints.add(costConstraint);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(false));
}
/**
* Tests path success with TE-cost constraint for signalled LSP.
*/
@Test
public void setupPathTest3() {
build4RouterTopo(false, false, false, false, 0); // TE cost is set here.
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(true));
}
/**
* Tests path failure with TE-cost constraint for signalled LSP.
*/
@Test
public void setupPathTest4() {
build4RouterTopo(true, false, false, false, 0); // IGP cost is set here, not TE.
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(false));
}
/**
* Tests path success with (IGP) cost constraint for non-SR non-signalled LSP.
*/
@Test
public void setupPathTest5() {
build4RouterTopo(true, true, false, false, 0);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(COST);
constraints.add(costConstraint);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints,
WITHOUT_SIGNALLING_AND_WITHOUT_SR);
assertThat(result, is(true));
}
/**
* Tests path success with TE-cost constraint for non-SR non-sgnalled LSP.
*/
@Test
public void setupPathTest6() {
build4RouterTopo(false, true, false, false, 0);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints,
WITHOUT_SIGNALLING_AND_WITHOUT_SR);
assertThat(result, is(true));
}
/**
* Tests path failure with TE-cost constraint for non-SR non-signalled LSP(CR). Label capability not registered.
*/
@Test
public void setupPathTest7() {
build4RouterTopo(true, false, false, false, 0);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints,
WITHOUT_SIGNALLING_AND_WITHOUT_SR);
assertThat(result, is(false));
}
/**
* Tests path failure as bandwidth is requested but is not registered.
*/
@Test
public void setupPathTest8() {
build4RouterTopo(true, false, false, false, 0);
List<Constraint> constraints = new LinkedList<Constraint>();
BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
constraints.add(bwConstraint);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(false));
}
/**
* Tests path failure as bandwidth requested is more than registered.
*/
@Test
public void setupPathTest9() {
build4RouterTopo(false, false, false, false, 5);
List<Constraint> constraints = new LinkedList<Constraint>();
BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
constraints.add(bwConstraint);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(false));
}
/**
* Tests path setup failure(without signalling). Label capability is not present.
*/
@Test
public void setupPathTest10() {
build4RouterTopo(false, false, false, false, 0);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, SR_WITHOUT_SIGNALLING);
assertThat(result, is(false));
}
/**
* Tests path setup without failure for LSP with signalling and with bandwidth reservation.
*/
@Test
public void setupPathTest11() {
build4RouterTopo(false, true, true, true, 15);
List<Constraint> constraints = new LinkedList<Constraint>();
BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
constraints.add(bwConstraint);
LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, SR_WITHOUT_SIGNALLING);
assertThat(result, is(false));
}
/**
* Tests path setup without signalling and with bandwidth reservation.
*/
@Test
public void setupPathTest12() {
build4RouterTopo(false, true, true, true, 15);
List<Constraint> constraints = new LinkedList<Constraint>();
BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
constraints.add(bwConstraint);
LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
LabelResourceId link1Label = LabelResourceId.labelResourceId(5202);
pceManager.pceStore.addAdjLabel(link1, link1Label);
LabelResourceId link2Label = LabelResourceId.labelResourceId(5203);
pceManager.pceStore.addAdjLabel(link2, link2Label);
LabelResourceId link3Label = LabelResourceId.labelResourceId(5204);
pceManager.pceStore.addAdjLabel(link3, link3Label);
LabelResourceId link4Label = LabelResourceId.labelResourceId(5205);
pceManager.pceStore.addAdjLabel(link4, link4Label);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, SR_WITHOUT_SIGNALLING);
assertThat(result, is(true));
}
/**
* Tests path setup without cost/bandwidth constraints.
*/
@Test
public void setupPathTest13() {
build4RouterTopo(false, false, false, false, 0);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", null, WITH_SIGNALLING);
assertThat(result, is(true));
}
/**
* Tests path update with increase in bandwidth.
*/
@Test
public void updatePathTest1() {
build4RouterTopo(false, true, true, true, 100);
// Setup tunnel.
List<Constraint> constraints = new LinkedList<>();
BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(60.0));
constraints.add(bwConstraint);
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
assertThat(result, is(true));
// Change constraint and update it.
constraints = new LinkedList<>();
bwConstraint = new BandwidthConstraint(Bandwidth.bps(50.0));
constraints.add(bwConstraint);
constraints.add(costConstraint);
Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
assertThat(tunnels.size(), is(1));
Tunnel tunnel = tunnels.iterator().next();
// Stimulate the effect of LSP ids from protocol msg.
tunnelService.updateTunnelWithLspIds(tunnel, "123", "1", State.ACTIVE);
result = pceManager.updatePath(tunnel.tunnelId(), constraints);
assertThat(result, is(true));
tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
assertThat(tunnels.size(), is(2));
}
/**
* Tests path update with decrease in bandwidth.
*/
@Test
public void updatePathTest2() {
build4RouterTopo(false, true, true, true, 100);
// Setup tunnel.
List<Constraint> constraints = new LinkedList<Constraint>();
BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(60.0));
constraints.add(bwConstraint);
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
LabelResourceId link1Label = LabelResourceId.labelResourceId(5202);
pceManager.pceStore.addAdjLabel(link1, link1Label);
LabelResourceId link2Label = LabelResourceId.labelResourceId(5203);
pceManager.pceStore.addAdjLabel(link2, link2Label);
LabelResourceId link3Label = LabelResourceId.labelResourceId(5204);
pceManager.pceStore.addAdjLabel(link3, link3Label);
LabelResourceId link4Label = LabelResourceId.labelResourceId(5205);
pceManager.pceStore.addAdjLabel(link4, link4Label);
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, SR_WITHOUT_SIGNALLING);
assertThat(result, is(true));
// Change constraint and update it.
constraints.remove(bwConstraint);
bwConstraint = new BandwidthConstraint(Bandwidth.bps(70.0));
constraints.add(bwConstraint);
Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
assertThat(tunnels.size(), is(1));
for (Tunnel tunnel : tunnels) {
result = pceManager.updatePath(tunnel.tunnelId(), constraints);
assertThat(result, is(true));
}
tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
assertThat(tunnels.size(), is(2));
}
/**
* Tests path update without cost/bandwidth constraints.
*/
@Test
public void updatePathTest3() {
build4RouterTopo(false, true, true, true, 100);
// Setup tunnel.
boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", null, WITH_SIGNALLING);
assertThat(result, is(true));
Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
assertThat(tunnels.size(), is(1));
for (Tunnel tunnel : tunnels) {
result = pceManager.updatePath(tunnel.tunnelId(), null);
assertThat(result, is(true));
}
Iterable<Tunnel> queryTunnelResult = pceManager.queryAllPath();
assertThat((int) queryTunnelResult.spliterator().getExactSizeIfKnown(), is(2));
}
/**
* Tests path release.
*/
@Test
public void releasePathTest1() {
build4RouterTopo(false, false, false, false, 5);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
assertThat(tunnels.size(), is(1));
boolean result;
for (Tunnel tunnel : tunnels) {
result = pceManager.releasePath(tunnel.tunnelId());
assertThat(result, is(true));
}
tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
assertThat(tunnels.size(), is(0));
}
/**
* Tests path release failure.
*/
@Test
public void releasePathTest2() {
build4RouterTopo(false, false, false, false, 5);
List<Constraint> constraints = new LinkedList<Constraint>();
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
assertThat(tunnels.size(), is(1));
// Random tunnel id.
boolean result = pceManager.releasePath(TunnelId.valueOf("111"));
assertThat(result, is(false));
tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
assertThat(tunnels.size(), is(1));
}
/**
* Tests packet in to trigger label DB sync.
*/
@Test
public void packetProcessingTest() throws URISyntaxException {
build4RouterTopo(false, true, true, true, 0); // This also initializes devices etc.
final int srcHost = 2;
final int dstHost = 5;
LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
ConnectPoint src = new ConnectPoint(D1.deviceId(), PortNumber.portNumber(srcHost));
ConnectPoint dst = new ConnectPoint(D2.deviceId(), PortNumber.portNumber(dstHost));
Link link1 = DefaultLink.builder().src(src).dst(dst).state(ACTIVE).type(DIRECT)
.providerId(new ProviderId("eth", "1")).build();
LabelResourceId link1Label = LabelResourceId.labelResourceId(5204);
pceManager.pceStore.addAdjLabel(link1, link1Label);
Ethernet eth;
IPv4 ipv4;
ipv4 = new IPv4();
eth = new Ethernet();
eth.setEtherType(Ethernet.TYPE_IPV4);
eth.setPayload(ipv4);
eth.setSourceMACAddress("00:00:00:10:00:0" + srcHost).setDestinationMACAddress("00:00:00:10:00:0" + dstHost);
InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(D1.deviceId(), PortNumber.portNumber(srcHost)),
eth, ByteBuffer.wrap(eth.serialize()));
pktProcessor.process(new MockPcepPacketContext(inPkt, null));
assertThat(flowsDownloaded, is(4));
}
/**
* Tests tunnel events added and removed.
*/
@Test
public void tunnelEventTest1() {
build4RouterTopo(false, true, true, true, 15);
List<Constraint> constraints = new LinkedList<Constraint>();
BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
constraints.add(bwConstraint);
LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
LabelResourceId link1Label = LabelResourceId.labelResourceId(5202);
pceManager.pceStore.addAdjLabel(link1, link1Label);
LabelResourceId link2Label = LabelResourceId.labelResourceId(5203);
pceManager.pceStore.addAdjLabel(link2, link2Label);
LabelResourceId link3Label = LabelResourceId.labelResourceId(5204);
pceManager.pceStore.addAdjLabel(link3, link3Label);
LabelResourceId link4Label = LabelResourceId.labelResourceId(5205);
pceManager.pceStore.addAdjLabel(link4, link4Label);
pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T1", constraints, SR_WITHOUT_SIGNALLING);
assertThat(pceStore.getTunnelInfoCount(), is(1));
Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
for (Tunnel tunnel : tunnels) {
TunnelEvent event = new TunnelEvent(TunnelEvent.Type.TUNNEL_ADDED, tunnel);
tunnelListener.event(event);
pceManager.releasePath(tunnel.tunnelId());
event = new TunnelEvent(TunnelEvent.Type.TUNNEL_REMOVED, tunnel);
tunnelListener.event(event);
}
assertThat(pceStore.getTunnelInfoCount(), is(0));
}
/**
* Tests label allocation/removal in CR case based on tunnel event.
*/
@Test
public void tunnelEventTest2() {
build4RouterTopo(false, true, true, true, 15);
List<Constraint> constraints = new LinkedList<Constraint>();
BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
constraints.add(bwConstraint);
pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T2", constraints, WITHOUT_SIGNALLING_AND_WITHOUT_SR);
assertThat(pceStore.getTunnelInfoCount(), is(1));
TunnelEvent event;
Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
for (Tunnel tunnel : tunnels) {
event = new TunnelEvent(TunnelEvent.Type.TUNNEL_ADDED, tunnel);
tunnelListener.event(event);
// Stimulate the effect of LSP ids from protocol msg.
tunnelService.updateTunnelWithLspIds(tunnel, "123", "1", ESTABLISHED);
}
tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
for (Tunnel tunnel : tunnels) {
event = new TunnelEvent(TunnelEvent.Type.TUNNEL_UPDATED, tunnel);
tunnelListener.event(event);
pceManager.releasePath(tunnel.tunnelId());
event = new TunnelEvent(TunnelEvent.Type.TUNNEL_REMOVED, tunnel);
tunnelListener.event(event);
}
assertThat(pceStore.getTunnelInfoCount(), is(0));
}
/**
* Tests handling UNSTABLE state based on tunnel event.
*/
@Test
public void tunnelEventTest3() {
build4RouterTopo(false, true, true, true, 15);
List<Constraint> constraints = new LinkedList<Constraint>();
BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
CostConstraint costConstraint = new CostConstraint(TE_COST);
constraints.add(costConstraint);
constraints.add(bwConstraint);
pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T2", constraints, WITHOUT_SIGNALLING_AND_WITHOUT_SR);
assertThat(pceStore.getTunnelInfoCount(), is(1));
assertThat(pceStore.getFailedPathInfoCount(), is(0));
TunnelEvent event;
Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
for (Tunnel tunnel : tunnels) {
event = new TunnelEvent(TunnelEvent.Type.TUNNEL_ADDED, tunnel);
tunnelListener.event(event);
// Stimulate the effect of LSP ids from protocol msg.
tunnelService.updateTunnelWithLspIds(tunnel, "123", "1", UNSTABLE);
}
tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
for (Tunnel tunnel : tunnels) {
event = new TunnelEvent(TunnelEvent.Type.TUNNEL_UPDATED, tunnel);
tunnelListener.event(event);
}
assertThat(pceStore.getTunnelInfoCount(), is(1));
assertThat(pceStore.getFailedPathInfoCount(), is(1));
}
@After
public void tearDown() {
pceManager.deactivate();
pceManager.pathService = null;
pceManager.resourceService = null;
pceManager.tunnelService = null;
pceManager.coreService = null;
pceManager.storageService = null;
pceManager.packetService = null;
pceManager.deviceService = null;
pceManager.labelRsrcService = null;
pceManager.flowObjectiveService = null;
pceManager.pceStore = null;
flowsDownloaded = 0;
}
private class MockTopologyService extends TopologyServiceAdapter {
@Override
public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst);
Set<TopologyVertex> vertices = graph.getVertexes();
if (!vertices.contains(srcV) || !vertices.contains(dstV)) {
// src or dst not part of the current graph
return ImmutableSet.of();
}
GraphPathSearch.Result<TopologyVertex, TopologyEdge> result = PathComputationTest.graphSearch()
.search(graph, srcV, dstV, weight, ALL_PATHS);
ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) {
builder.add(PathComputationTest.networkPath(path));
}
return builder.build();
}
}
private class MockPathService extends PathServiceAdapter {
@Override
public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
// If either edge is null, bail with no paths.
if (src == null || dst == null) {
return ImmutableSet.of();
}
// Otherwise get all paths between the source and destination edge
// devices.
return topologyService.getPaths(null, (DeviceId) src, (DeviceId) dst, weight);
}
}
private class MockTunnelServiceAdapter extends TunnelServiceAdapter {
private HashMap<TunnelId, Tunnel> tunnelIdAsKeyStore = new HashMap<TunnelId, Tunnel>();
private int tunnelIdCounter = 0;
@Override
public TunnelId setupTunnel(ApplicationId producerId, ElementId srcElementId, Tunnel tunnel, Path path) {
TunnelId tunnelId = TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
Tunnel tunnelToInsert = new DefaultTunnel(tunnel.providerId(), tunnel.src(), tunnel.dst(), tunnel.type(),
tunnel.state(), tunnel.groupId(), tunnelId, tunnel.tunnelName(),
path, tunnel.annotations());
tunnelIdAsKeyStore.put(tunnelId, tunnelToInsert);
return tunnelId;
}
@Override
public void addListener(TunnelListener listener) {
tunnelListener = listener;
}
/**
* Stimulates the effect of receiving PLSP id and LSP id from protocol PCRpt msg.
*/
public TunnelId updateTunnelWithLspIds(Tunnel tunnel, String pLspId, String localLspId, State state) {
TunnelId tunnelId = tunnel.tunnelId();
Builder annotationBuilder = DefaultAnnotations.builder();
annotationBuilder.putAll(tunnel.annotations());
// PCRpt in response to PCInitate msg will carry PLSP id allocated by PCC.
if (tunnel.annotations().value(PLSP_ID) == null) {
annotationBuilder.set(PLSP_ID, pLspId);
}
// Signalled LSPs will carry local LSP id allocated by signalling protocol(PCC).
if (tunnel.annotations().value(LOCAL_LSP_ID) == null) {
annotationBuilder.set(LOCAL_LSP_ID, localLspId);
}
SparseAnnotations annotations = annotationBuilder.build();
tunnelIdAsKeyStore.remove(tunnelId, tunnel);
Tunnel tunnelToInsert = new DefaultTunnel(tunnel.providerId(), tunnel.src(), tunnel.dst(), tunnel.type(),
state, tunnel.groupId(), tunnelId, tunnel.tunnelName(),
tunnel.path(), annotations);
tunnelIdAsKeyStore.put(tunnelId, tunnelToInsert);
return tunnelId;
}
@Override
public boolean downTunnel(ApplicationId producerId, TunnelId tunnelId) {
for (TunnelId tunnelIdKey : tunnelIdAsKeyStore.keySet()) {
if (tunnelIdKey.equals(tunnelId)) {
tunnelIdAsKeyStore.remove(tunnelId);
return true;
}
}
return false;
}
@Override
public Tunnel queryTunnel(TunnelId tunnelId) {
for (TunnelId tunnelIdKey : tunnelIdAsKeyStore.keySet()) {
if (tunnelIdKey.equals(tunnelId)) {
return tunnelIdAsKeyStore.get(tunnelId);
}
}
return null;
}
@Override
public Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst) {
Collection<Tunnel> result = new HashSet<Tunnel>();
Tunnel tunnel = null;
for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
tunnel = tunnelIdAsKeyStore.get(tunnelId);
if ((null != tunnel) && (src.equals(tunnel.src())) && (dst.equals(tunnel.dst()))) {
result.add(tunnel);
}
}
return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
}
@Override
public Collection<Tunnel> queryTunnel(Tunnel.Type type) {
Collection<Tunnel> result = new HashSet<Tunnel>();
for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
result.add(tunnelIdAsKeyStore.get(tunnelId));
}
return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
}
}
public static class MockCoreService extends CoreServiceAdapter {
@Override
public ApplicationId registerApplication(String name) {
return new DefaultApplicationId(1, name);
}
@Override
public IdGenerator getIdGenerator(String topic) {
return new IdGenerator() {
private AtomicLong counter = new AtomicLong(0);
@Override
public long getNewId() {
return counter.getAndIncrement();
}
};
}
}
private class MockDevice extends DefaultDevice {
MockDevice(DeviceId id, Annotations annotations) {
super(null, id, null, null, null, null, null, null, annotations);
}
}
private class MockDeviceService extends DeviceServiceAdapter {
List<Device> devices = new LinkedList<>();
private void addDevice(Device dev) {
devices.add(dev);
}
@Override
public Device getDevice(DeviceId deviceId) {
for (Device dev : devices) {
if (dev.id().equals(deviceId)) {
return dev;
}
}
return null;
}
@Override
public Iterable<Device> getAvailableDevices() {
return devices;
}
}
private PacketProcessor pktProcessor = null;
private class MockPacketService extends PacketServiceAdapter {
@Override
public void addProcessor(PacketProcessor processor, int priority) {
pktProcessor = processor;
}
}
// Minimal PacketContext to make core and applications happy.
final class MockPcepPacketContext extends DefaultPacketContext {
private MockPcepPacketContext(InboundPacket inPkt, OutboundPacket outPkt) {
super(System.currentTimeMillis(), inPkt, outPkt, false);
}
@Override
public void send() {
}
}
public static class MockFlowObjService extends FlowObjServiceAdapter {
@Override
public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
++flowsDownloaded;
}
}
}
......@@ -33,6 +33,8 @@ import org.junit.Before;
import org.junit.Test;
import org.onosproject.incubator.net.resource.label.LabelResourceId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
import org.onosproject.incubator.net.resource.label.LabelResourceService;
import org.onosproject.incubator.net.tunnel.LabelStack;
......@@ -41,6 +43,7 @@ import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.Path;
import org.onosproject.pce.pcestore.api.PceStore;
import org.onosproject.net.provider.ProviderId;
......@@ -61,6 +64,9 @@ public class PceccSrTeBeHandlerTest {
protected LabelResourceAdminService labelRsrcAdminService;
protected LabelResourceService labelRsrcService;
protected PceStore pceStore;
private FlowObjectiveService flowObjectiveService;
private CoreService coreService;
private ApplicationId appId;
private ProviderId providerId;
private DeviceId deviceId1;
private DeviceId deviceId2;
......@@ -88,8 +94,11 @@ public class PceccSrTeBeHandlerTest {
srTeHandler = PceccSrTeBeHandler.getInstance();
labelRsrcService = new LabelResourceAdapter();
labelRsrcAdminService = new LabelResourceAdapter();
flowObjectiveService = new PceManagerTest.MockFlowObjService();
coreService = new PceManagerTest.MockCoreService();
appId = coreService.registerApplication("org.onosproject.pce");
pceStore = new PceStoreAdapter();
srTeHandler.initialize(labelRsrcAdminService, labelRsrcService, pceStore);
srTeHandler.initialize(labelRsrcAdminService, labelRsrcService, flowObjectiveService, appId, pceStore);
// Creates path
// Creates list of links
......@@ -446,39 +455,39 @@ public class PceccSrTeBeHandlerTest {
// check node-label of deviceId1
List<LabelResourceId> labelList = labelStack.labelResources();
Iterator<LabelResourceId> iterator = labelList.iterator();
labelId = (LabelResourceId) iterator.next();
labelId = iterator.next();
assertThat(labelId, is(LabelResourceId.labelResourceId(4097)));
// check adjacency label of deviceId1
labelId = (LabelResourceId) iterator.next();
labelId = iterator.next();
assertThat(labelId, is(LabelResourceId.labelResourceId(5122)));
// check node-label of deviceId2
labelId = (LabelResourceId) iterator.next();
labelId = iterator.next();
assertThat(labelId, is(LabelResourceId.labelResourceId(4098)));
// check adjacency label of deviceId2
labelId = (LabelResourceId) iterator.next();
labelId = iterator.next();
assertThat(labelId, is(LabelResourceId.labelResourceId(5123)));
// check node-label of deviceId3
labelId = (LabelResourceId) iterator.next();
labelId = iterator.next();
assertThat(labelId, is(LabelResourceId.labelResourceId(4099)));
// check adjacency label of deviceId3
labelId = (LabelResourceId) iterator.next();
labelId = iterator.next();
assertThat(labelId, is(LabelResourceId.labelResourceId(5124)));
// check node-label of deviceId4
labelId = (LabelResourceId) iterator.next();
labelId = iterator.next();
assertThat(labelId, is(LabelResourceId.labelResourceId(4100)));
// check adjacency label of deviceId4
labelId = (LabelResourceId) iterator.next();
labelId = iterator.next();
assertThat(labelId, is(LabelResourceId.labelResourceId(5125)));
// check node-label of deviceId5
labelId = (LabelResourceId) iterator.next();
labelId = iterator.next();
assertThat(labelId, is(LabelResourceId.labelResourceId(4101)));
}
}
......
/*
* 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.util;
import java.util.List;
import org.onosproject.net.DeviceId;
import org.onosproject.net.flowobjective.FilteringObjective;
import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.NextObjective;
/**
* Test implementation of FlowObjectiveService.
*/
public class FlowObjServiceAdapter implements FlowObjectiveService {
private ForwardingObjective forwardingObjective;
@Override
public void filter(DeviceId deviceId, FilteringObjective filteringObjective) {
}
@Override
public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
this.forwardingObjective = forwardingObjective;
}
@Override
public void next(DeviceId deviceId, NextObjective nextObjective) {
}
@Override
public int allocateNextId() {
return 0;
}
@Override
public void initPolicy(String policy) {
}
public ForwardingObjective forwardingObjective() {
return forwardingObjective;
}
@Override
public List<String> getNextMappings() {
return null;
}
}
/*
* 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.util;
import java.util.Collection;
import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.Tunnel.Type;
import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelListener;
import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.incubator.net.tunnel.TunnelSubscription;
import org.onosproject.net.Annotations;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.Path;
/**
* Provides test implementation of class TunnelService.
*/
public class TunnelServiceAdapter implements TunnelService {
@Override
public void addListener(TunnelListener listener) {
// TODO Auto-generated method stub
}
@Override
public void removeListener(TunnelListener listener) {
// TODO Auto-generated method stub
}
@Override
public Tunnel borrowTunnel(ApplicationId consumerId, TunnelId tunnelId, Annotations... annotations) {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelName tunnelName,
Annotations... annotations) {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src, TunnelEndPoint dst,
Annotations... annotations) {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src, TunnelEndPoint dst, Type type,
Annotations... annotations) {
// TODO Auto-generated method stub
return null;
}
@Override
public TunnelId setupTunnel(ApplicationId producerId, ElementId srcElementId, Tunnel tunnel, Path path) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean downTunnel(ApplicationId producerId, TunnelId tunnelId) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean returnTunnel(ApplicationId consumerId, TunnelId tunnelId, Annotations... annotations) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean returnTunnel(ApplicationId consumerId, TunnelName tunnelName, Annotations... annotations) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src, TunnelEndPoint dst, Type type,
Annotations... annotations) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src, TunnelEndPoint dst,
Annotations... annotations) {
// TODO Auto-generated method stub
return false;
}
@Override
public Tunnel queryTunnel(TunnelId tunnelId) {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<TunnelSubscription> queryTunnelSubscription(ApplicationId consumerId) {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<Tunnel> queryTunnel(Type type) {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst) {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<Tunnel> queryAllTunnels() {
// TODO Auto-generated method stub
return null;
}
@Override
public int tunnelCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public Iterable<Tunnel> getTunnels(DeviceId deviceId) {
// TODO Auto-generated method stub
return null;
}
}
......@@ -56,4 +56,15 @@ public final class PcepAnnotationKeys {
* Annotation key for the identification of initiated LSP.
*/
public static final String PCE_INIT = "pceInit";
/**
* Annotation key for the cost type.
*/
public static final String COST_TYPE = "costType";
/**
* Annotation key for the Delegation.
* Whether LSPs are delegated or not
*/
public static final String DELEGATE = "delegate";
}
......