PCE Changes to handle bandwidth changes from network
Change-Id: Ib4961ac4ea8ed803fb035ab93725ae6f0968a5c0
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java
index ecc1d72..bc80a7f 100644
--- a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java
@@ -17,11 +17,14 @@
import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.apache.felix.scr.annotations.Activate;
@@ -45,6 +48,9 @@
import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.LinkKey;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultAnnotations.Builder;
@@ -54,21 +60,19 @@
import org.onosproject.net.Link;
import org.onosproject.net.NetworkResource;
import org.onosproject.net.Path;
+import org.onosproject.net.config.basics.SubjectFactories;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.intent.Constraint;
-import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.MastershipRole;
+import org.onosproject.bandwidthmgr.api.BandwidthMgmtService;
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.PceBandwidthConstraint;
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;
@@ -79,6 +83,7 @@
import org.onosproject.pce.pcestore.PcePathInfo;
import org.onosproject.pce.pcestore.api.PceStore;
import org.onosproject.pcep.api.DeviceCapability;
+import org.onosproject.pcep.api.TeLinkConfig;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.DistributedSet;
import org.onosproject.store.service.Serializer;
@@ -118,9 +123,6 @@
public static final String DEVICE_TYPE = "type";
public static final String L3_DEVICE = "L3";
- 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";
@@ -133,12 +135,6 @@
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected ResourceService resourceService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected ResourceQueryService resourceQueryService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PathService pathService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -162,13 +158,27 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected TopologyService topologyService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected BandwidthMgmtService bandwidthMgmtService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigRegistry netConfigRegistry;
+
private TunnelListener listener = new InnerTunnelListener();
private ApplicationId appId;
private final TopologyListener topologyListener = new InternalTopologyListener();
- public static final int INITIAL_DELAY = 30;
- public static final int PERIODIC_DELAY = 30;
+ private List<TunnelId> rsvpTunnelsWithLocalBw = new ArrayList<>();
+
+ private final ConfigFactory<LinkKey, TeLinkConfig> configFactory =
+ new ConfigFactory<LinkKey, TeLinkConfig>(SubjectFactories.LINK_SUBJECT_FACTORY,
+ TeLinkConfig.class, "teLinkConfig") {
+ @Override
+ public TeLinkConfig createConfig() {
+ return new TeLinkConfig();
+ }
+ };
/**
* Creates new instance of PceManager.
@@ -182,7 +192,6 @@
tunnelService.addListener(listener);
- tunnelConsumerIdGen = coreService.getIdGenerator(TUNNEL_CONSUMER_ID_GEN_TOPIC);
localLspIdIdGen = coreService.getIdGenerator(LOCAL_LSP_ID_GEN_TOPIC);
localLspIdIdGen.getNewId(); // To prevent 0, the 1st value generated from being used in protocol.
localLspIdFreeList = storageService.<Short>setBuilder()
@@ -192,6 +201,7 @@
.asDistributedSet();
topologyService.addListener(topologyListener);
+ netConfigRegistry.registerConfigFactory(configFactory);
log.info("Started");
}
@@ -200,6 +210,8 @@
protected void deactivate() {
tunnelService.removeListener(listener);
topologyService.removeListener(topologyListener);
+ netConfigRegistry.unregisterConfigFactory(configFactory);
+
log.info("Stopped");
}
@@ -460,8 +472,8 @@
while (iterator.hasNext()) {
Constraint constraint = iterator.next();
- if (constraint instanceof BandwidthConstraint) {
- bwConstraintValue = ((BandwidthConstraint) constraint).bandwidth().bps();
+ if (constraint instanceof PceBandwidthConstraint) {
+ bwConstraintValue = ((PceBandwidthConstraint) constraint).bandwidth().bps();
} else if (constraint instanceof CostConstraint) {
costConstraint = (CostConstraint) constraint;
}
@@ -534,11 +546,9 @@
TunnelName.tunnelName(tunnelName), computedPath,
annotationBuilder.build());
- // Allocate bandwidth.
- TunnelConsumerId consumerId = null;
+ // Allocate bandwidth for all tunnels.
if (bwConstraintValue != 0) {
- consumerId = reserveBandwidth(computedPath, bwConstraintValue, null);
- if (consumerId == null) {
+ if (!reserveBandwidth(computedPath, bwConstraintValue, null)) {
pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints,
lspType, explicitPathInfo));
return false;
@@ -548,16 +558,19 @@
TunnelId tunnelId = tunnelService.setupTunnel(appId, src, tunnel, computedPath);
if (tunnelId == null) {
pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo));
- if (consumerId != null) {
- resourceService.release(consumerId);
+
+ if (bwConstraintValue != 0) {
+ computedPath.links().forEach(ln -> bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(ln),
+ Double.parseDouble(tunnel.annotations().value(BANDWIDTH))));
}
+
return false;
}
- if (consumerId != null) {
- // Store tunnel consumer id in LSP store.
- pceStore.addTunnelInfo(tunnelId, consumerId);
+ if (bwConstraintValue != 0 && lspType == WITH_SIGNALLING) {
+ rsvpTunnelsWithLocalBw.add(tunnelId);
}
+
return true;
}
@@ -581,7 +594,7 @@
double bwConstraintValue = 0;
String costType = null;
SharedBandwidthConstraint shBwConstraint = null;
- BandwidthConstraint bwConstraint = null;
+ PceBandwidthConstraint bwConstraint = null;
CostConstraint costConstraint = null;
if (constraints != null) {
@@ -589,8 +602,8 @@
Iterator<Constraint> iterator = constraints.iterator();
while (iterator.hasNext()) {
Constraint constraint = iterator.next();
- if (constraint instanceof BandwidthConstraint) {
- bwConstraint = (BandwidthConstraint) constraint;
+ if (constraint instanceof PceBandwidthConstraint) {
+ bwConstraint = (PceBandwidthConstraint) constraint;
bwConstraintValue = bwConstraint.bandwidth().bps();
} else if (constraint instanceof CostConstraint) {
costConstraint = (CostConstraint) constraint;
@@ -684,7 +697,6 @@
annotationBuilder.set(PCC_TUNNEL_ID, tunnel.annotations().value(PCC_TUNNEL_ID));
Path computedPath = computedPathSet.iterator().next();
- TunnelConsumerId consumerId = null;
LspType lspType = LspType.valueOf(lspSigType);
long localLspId = 0;
if (lspType != WITH_SIGNALLING) {
@@ -700,10 +712,9 @@
tunnel.tunnelName(), computedPath,
annotationBuilder.build());
- // Allocate shared bandwidth.
+ // Allocate shared bandwidth for all tunnels.
if (bwConstraintValue != 0) {
- consumerId = reserveBandwidth(computedPath, bwConstraintValue, shBwConstraint);
- if (consumerId == null) {
+ if (!reserveBandwidth(computedPath, bwConstraintValue, shBwConstraint)) {
return false;
}
}
@@ -712,15 +723,14 @@
computedPath);
if (updatedTunnelId == null) {
- if (consumerId != null) {
- resourceService.release(consumerId);
+ if (bwConstraintValue != 0) {
+ releaseSharedBwForNewTunnel(computedPath, bwConstraintValue, shBwConstraint);
}
return false;
}
- if (consumerId != null) {
- // Store tunnel consumer id in LSP store.
- pceStore.addTunnelInfo(updatedTunnelId, consumerId);
+ if (bwConstraintValue != 0 && lspType == WITH_SIGNALLING) {
+ rsvpTunnelsWithLocalBw.add(updatedTunnelId);
}
return true;
@@ -750,6 +760,35 @@
return tunnelService.queryTunnel(tunnelId);
}
+ private boolean releaseSharedBwForNewTunnel(Path computedPath, double bandwidthConstraint,
+ SharedBandwidthConstraint shBwConstraint) {
+ checkNotNull(computedPath);
+ checkNotNull(bandwidthConstraint);
+ double bwToAllocate;
+
+ Double additionalBwValue = null;
+ if (shBwConstraint != null) {
+ additionalBwValue = ((bandwidthConstraint - shBwConstraint.sharedBwValue().bps()) <= 0) ? null
+ : (bandwidthConstraint - shBwConstraint.sharedBwValue().bps());
+ }
+
+ for (Link link : computedPath.links()) {
+ bwToAllocate = 0;
+ if ((shBwConstraint != null) && (shBwConstraint.links().contains(link))) {
+ if (additionalBwValue != null) {
+ bwToAllocate = additionalBwValue;
+ }
+ } else {
+ bwToAllocate = bandwidthConstraint;
+ }
+
+ if (bwToAllocate != 0) {
+ bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(link), bwToAllocate);
+ }
+ }
+ return true;
+ }
+
/**
* Returns the next local LSP identifier to be used either by getting from
* freed list if available otherwise generating a new one.
@@ -801,8 +840,16 @@
if (constraint instanceof CapabilityConstraint) {
cost = ((CapabilityConstraint) constraint).isValidLink(edge.link(), deviceService,
netCfgService) ? 1 : -1;
+ } else if (constraint instanceof PceBandwidthConstraint) {
+ cost = ((PceBandwidthConstraint) constraint).isValidLink(edge.link(),
+ bandwidthMgmtService) ? 1 : -1;
+ } else if (constraint instanceof SharedBandwidthConstraint) {
+ cost = ((SharedBandwidthConstraint) constraint).isValidLink(edge.link(),
+ bandwidthMgmtService) ? 1 : -1;
+ } else if (constraint instanceof CostConstraint) {
+ cost = ((CostConstraint) constraint).isValidLink(edge.link(), netCfgService);
} else {
- cost = constraint.cost(edge.link(), resourceService::isAvailable);
+ cost = constraint.cost(edge.link(), null);
}
}
return cost;
@@ -841,7 +888,7 @@
if (tunnel.annotations().value(BANDWIDTH) != null) {
//Requested bandwidth will be same as previous allocated bandwidth for the tunnel
- BandwidthConstraint localConst = new BandwidthConstraint(Bandwidth.bps(Double.parseDouble(tunnel
+ PceBandwidthConstraint localConst = new PceBandwidthConstraint(Bandwidth.bps(Double.parseDouble(tunnel
.annotations().value(BANDWIDTH))));
constraintList.add(localConst);
}
@@ -870,14 +917,13 @@
}
// Allocates the bandwidth locally for PCECC tunnels.
- private TunnelConsumerId reserveBandwidth(Path computedPath, double bandwidthConstraint,
+ private boolean reserveBandwidth(Path computedPath, double bandwidthConstraint,
SharedBandwidthConstraint shBwConstraint) {
checkNotNull(computedPath);
checkNotNull(bandwidthConstraint);
Resource resource = null;
double bwToAllocate = 0;
-
- TunnelConsumerId consumer = TunnelConsumerId.valueOf(tunnelConsumerIdGen.getNewId());
+ Map<Link, Double> linkMap = new HashMap<>();
/**
* Shared bandwidth sub-case : Lesser bandwidth required than original -
@@ -905,24 +951,20 @@
* 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;
+ if (!bandwidthMgmtService.allocLocalReservedBw(LinkKey.linkKey(link.src(), link.dst()),
+ bwToAllocate)) {
+ // If allocation for any link fails, then release the partially allocated bandwidth
+ // for all links allocated
+ linkMap.forEach((ln, aDouble) -> bandwidthMgmtService
+ .releaseLocalReservedBw(LinkKey.linkKey(ln), aDouble));
+ return false;
}
+
+ linkMap.put(link, bwToAllocate);
}
}
- /*
- * 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;
+ return true;
}
/*
@@ -950,24 +992,13 @@
}
}
- ResourceConsumer tunnelConsumerId = pceStore.getTunnelInfo(tunnel.tunnelId());
- if (tunnelConsumerId == null) {
- //If bandwidth for old tunnel is not allocated i,e 0 then no need to release
- log.debug("Bandwidth not allocated (0 bandwidth) for old LSP.");
- return;
- }
-
if (isLinkShared) {
releaseSharedBandwidth(newTunnel, tunnel);
return;
}
- resourceService.release(tunnelConsumerId);
- /*
- * 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.
- */
+ tunnel.path().links().forEach(tn -> bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(tn),
+ Double.parseDouble(tunnel.annotations().value(BANDWIDTH))));
}
/**
@@ -975,27 +1006,24 @@
* 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()));
- // 2. Release new tunnel's bandwidth, if new tunnel bandwidth is allocated
- ResourceConsumer consumer = pceStore.getTunnelInfo(newTunnel.tunnelId());
- if (consumer == null) {
- //If bandwidth for new tunnel is not allocated i,e 0 then no need to allocate
- return;
+ boolean isAllocate = false;
+ Double oldTunnelBw = Double.parseDouble(oldTunnel.annotations().value(BANDWIDTH));
+ Double newTunnelBw = Double.parseDouble(newTunnel.annotations().value(BANDWIDTH));
+
+ if (newTunnelBw > oldTunnelBw) {
+ isAllocate = true;
}
- 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.
-
+ if (oldTunnel.path().links().contains(link)) {
+ if (!isAllocate) {
+ bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(link),
+ oldTunnelBw - newTunnelBw);
+ }
+ } else {
+ bandwidthMgmtService.releaseLocalReservedBw(LinkKey.linkKey(link), oldTunnelBw);
+ }
}
}
@@ -1017,19 +1045,12 @@
}
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) {
- TunnelConsumerId consumerId = reserveBandwidth(tunnel.path(), bwConstraintValue, null);
- if (consumerId != null) {
- // Store tunnel consumer id in LSP store.
- pceStore.addTunnelInfo(tunnel.tunnelId(), consumerId);
- }
- }
- break;
-
case TUNNEL_UPDATED:
+ if (rsvpTunnelsWithLocalBw.contains(tunnel.tunnelId())) {
+ releaseBandwidth(event.subject());
+ rsvpTunnelsWithLocalBw.remove(tunnel.tunnelId());
+ }
+
if (tunnel.state() == UNSTABLE) {
/*
* During LSP DB sync if PCC doesn't report LSP which was PCE initiated, it's state is turned into
@@ -1040,7 +1061,7 @@
List<Constraint> constraints = new LinkedList<>();
String bandwidth = tunnel.annotations().value(BANDWIDTH);
if (bandwidth != null) {
- constraints.add(new BandwidthConstraint(Bandwidth
+ constraints.add(new PceBandwidthConstraint(Bandwidth
.bps(Double.parseDouble(bandwidth))));
}
@@ -1068,14 +1089,16 @@
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
- && mastershipService.getLocalRole(tunnel.path().src().deviceId()) == MastershipRole.MASTER) {
- releaseBandwidth(tunnel);
+ if (bwConstraintValue != 0 && mastershipService.getLocalRole(tunnel.path().src()
+ .deviceId()) == MastershipRole.MASTER) {
+ if (lspType != WITH_SIGNALLING) {
+ releaseBandwidth(tunnel);
+ }
}
- if (pceStore.getTunnelInfo(tunnel.tunnelId()) != null) {
+ /*if (pceStore.getTunnelInfo(tunnel.tunnelId()) != null) {
pceStore.removeTunnelInfo(tunnel.tunnelId());
- }
+ }*/
break;