[ONOS-4743] - DB sync is suspended if PCEP session is formed before BGP devices are learnt
Change-Id: I543201c54883e06182c1c83c4c64dd16a18e096c
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 a28a26e..76f6e3f 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
@@ -1058,6 +1058,18 @@
// Node-label allocation is being done during Label DB Sync.
// So, when device is detected, no need to do node-label
// allocation.
+ String lsrId = specificDevice.annotations().value(LSRID);
+ if (lsrId != null) {
+ pceStore.addLsrIdDevice(lsrId, specificDevice.id());
+
+ // Search in failed DB sync store. If found, trigger label DB sync.
+ DeviceId pccDeviceId = DeviceId.deviceId(lsrId);
+ if (pceStore.hasPccLsr(pccDeviceId)) {
+ log.debug("Continue to perform label DB sync for device {}.", pccDeviceId.toString());
+ syncLabelDb(pccDeviceId);
+ pceStore.removePccLsr(pccDeviceId);
+ }
+ }
break;
case DEVICE_REMOVED:
@@ -1065,6 +1077,11 @@
if (mastershipService.getLocalRole(specificDevice.id()) == MastershipRole.MASTER) {
releaseNodeLabel(specificDevice);
}
+
+ if (specificDevice.annotations().value(LSRID) != null) {
+ pceStore.removeLsrIdDevice(specificDevice.annotations().value(LSRID));
+ }
+
break;
default:
@@ -1252,13 +1269,20 @@
private boolean syncLabelDb(DeviceId deviceId) {
checkNotNull(deviceId);
- Device specificDevice = deviceService.getDevice(deviceId);
- if (specificDevice == null) {
- log.error("Unable to find device for specific device id {}.", deviceId.toString());
+ DeviceId actualDevcieId = pceStore.getLsrIdDevice(deviceId.toString());
+ if (actualDevcieId == null) {
+ log.error("Device not available {}.", deviceId.toString());
+ pceStore.addPccLsr(deviceId);
return false;
}
- if (pceStore.getGlobalNodeLabel(deviceId) != null) {
+ Device specificDevice = deviceService.getDevice(actualDevcieId);
+ if (specificDevice == null) {
+ log.error("Unable to find device for specific device id {}.", actualDevcieId.toString());
+ return false;
+ }
+
+ if (pceStore.getGlobalNodeLabel(actualDevcieId) != null) {
Map<DeviceId, LabelResourceId> globalNodeLabelMap = pceStore.getGlobalNodeLabels();
for (Entry<DeviceId, LabelResourceId> entry : globalNodeLabelMap.entrySet()) {
@@ -1279,7 +1303,7 @@
continue;
}
- srTeHandler.advertiseNodeLabelRule(deviceId,
+ srTeHandler.advertiseNodeLabelRule(actualDevcieId,
entry.getValue(),
IpPrefix.valueOf(IpAddress.valueOf(srcLsrId), PREFIX_LENGTH),
Objective.Operation.ADD, false);
@@ -1287,8 +1311,8 @@
Map<Link, LabelResourceId> adjLabelMap = pceStore.getAdjLabels();
for (Entry<Link, LabelResourceId> entry : adjLabelMap.entrySet()) {
- if (entry.getKey().src().deviceId().equals(deviceId)) {
- srTeHandler.installAdjLabelRule(deviceId,
+ if (entry.getKey().src().deviceId().equals(actualDevcieId)) {
+ srTeHandler.installAdjLabelRule(actualDevcieId,
entry.getValue(),
entry.getKey().src().port(),
entry.getKey().dst().port(),
@@ -1297,12 +1321,12 @@
}
}
- srTeHandler.advertiseNodeLabelRule(deviceId,
+ srTeHandler.advertiseNodeLabelRule(actualDevcieId,
LabelResourceId.labelResourceId(0),
IpPrefix.valueOf(END_OF_SYNC_IP_PREFIX),
Objective.Operation.ADD, true);
- log.debug("End of label DB sync for device {}", deviceId);
+ log.debug("End of label DB sync for device {}", actualDevcieId);
if (mastershipService.getLocalRole(specificDevice.id()) == MastershipRole.MASTER) {
// Allocate node-label to this specific device.
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/DistributedPceStore.java b/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/DistributedPceStore.java
index 6afdb30..0cda281 100644
--- a/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/DistributedPceStore.java
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/DistributedPceStore.java
@@ -19,6 +19,8 @@
import com.google.common.collect.ImmutableSet;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -89,6 +91,13 @@
// List of Failed path info
private DistributedSet<PcePathInfo> failedPathSet;
+ // Locally maintain LSRID to device id mapping for better performance.
+ private Map<String, DeviceId> lsrIdDeviceIdMap = new HashMap<>();
+
+ // List of PCC LSR ids whose BGP device information was not available to perform
+ // label db sync.
+ private HashSet<DeviceId> pendinglabelDbSyncPccMap = new HashSet();
+
@Activate
protected void activate() {
globalNodeLabelMap = storageService.<DeviceId, LabelResourceId>consistentMapBuilder()
@@ -341,4 +350,50 @@
}
return true;
}
+
+ @Override
+ public boolean addLsrIdDevice(String lsrId, DeviceId deviceId) {
+ checkNotNull(lsrId);
+ checkNotNull(deviceId);
+
+ lsrIdDeviceIdMap.put(lsrId, deviceId);
+ return true;
+ }
+
+ @Override
+ public boolean removeLsrIdDevice(String lsrId) {
+ checkNotNull(lsrId);
+
+ lsrIdDeviceIdMap.remove(lsrId);
+ return true;
+ }
+
+ @Override
+ public DeviceId getLsrIdDevice(String lsrId) {
+ checkNotNull(lsrId);
+
+ return lsrIdDeviceIdMap.get(lsrId);
+
+ }
+
+ @Override
+ public boolean addPccLsr(DeviceId lsrId) {
+ checkNotNull(lsrId);
+ pendinglabelDbSyncPccMap.add(lsrId);
+ return true;
+ }
+
+ @Override
+ public boolean removePccLsr(DeviceId lsrId) {
+ checkNotNull(lsrId);
+ pendinglabelDbSyncPccMap.remove(lsrId);
+ return true;
+ }
+
+ @Override
+ public boolean hasPccLsr(DeviceId lsrId) {
+ checkNotNull(lsrId);
+ return pendinglabelDbSyncPccMap.contains(lsrId);
+
+ }
}
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/api/PceStore.java b/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/api/PceStore.java
index 02ffcf6..3c9ceb7 100644
--- a/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/api/PceStore.java
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pcestore/api/PceStore.java
@@ -224,4 +224,54 @@
* @return success or failure
*/
boolean removeFailedPathInfo(PcePathInfo failedPathInfo);
+
+ /**
+ * Adds lsrid to device id mapping.
+ *
+ * @param lsrId lsrId of the device
+ * @param deviceId device id
+ * @return success or failure
+ */
+ boolean addLsrIdDevice(String lsrId, DeviceId deviceId);
+
+ /**
+ * Removes lsrid to device id mapping.
+ *
+ * @param lsrId lsrId of the device
+ * @return success or failure
+ */
+ boolean removeLsrIdDevice(String lsrId);
+
+ /**
+ * Gets lsrid to device id mapping.
+ *
+ * @param lsrId lsrId of the device
+ * @return device id of the lsrId
+ */
+ DeviceId getLsrIdDevice(String lsrId);
+
+ /**
+ * Adds lsrId of the PCC in form of device id for the PCC for which sync is pending due to non-availability of BGP.
+ * device.
+ *
+ * @param lsrId LSR id of the PCC in form of device id
+ * @return success or failure
+ */
+ public boolean addPccLsr(DeviceId lsrId);
+
+ /**
+ * Removes lsrId of the PCC in form of device id for the PCC for which pending sync is done.
+ *
+ * @param lsrId LSR id of the PCC in form of device id
+ * @return success or failure
+ */
+ public boolean removePccLsr(DeviceId lsrId);
+
+ /**
+ * Gets lsrId of the PCC in form of device id.
+ *
+ * @param lsrId LSR id of the PCC in form of device id
+ * @return success or failure
+ */
+ public boolean hasPccLsr(DeviceId lsrId);
}
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceManagerTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceManagerTest.java
index 602c328..852a7c1 100644
--- a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceManagerTest.java
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceManagerTest.java
@@ -690,6 +690,7 @@
LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
+ pceManager.pceStore.addLsrIdDevice(deviceD1.annotations().value(LSRID), deviceD1.id());
pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
@@ -713,7 +714,7 @@
eth.setEtherType(Ethernet.TYPE_IPV4);
eth.setPayload(ipv4);
- InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(D1.deviceId(),
+ InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(DeviceId.deviceId("1.1.1.1"),
PortNumber.portNumber(PCEP_PORT)),
eth, null);
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/util/PceStoreAdapter.java b/apps/pce/app/src/test/java/org/onosproject/pce/util/PceStoreAdapter.java
index beaf8ae..48120ad 100644
--- a/apps/pce/app/src/test/java/org/onosproject/pce/util/PceStoreAdapter.java
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/util/PceStoreAdapter.java
@@ -19,6 +19,8 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -52,6 +54,9 @@
// Set of Path info
private Set<PcePathInfo> failedPathInfoSet = new HashSet<>();
+ // Locally maintain LSRID to device id mapping for better performance.
+ private Map<String, DeviceId> lsrIdDeviceIdMap = new HashMap<>();
+
@Override
public boolean existsGlobalNodeLabel(DeviceId id) {
return globalNodeLabelMap.containsKey(id);
@@ -208,4 +213,39 @@
}
return true;
}
+
+ @Override
+ public boolean addLsrIdDevice(String lsrId, DeviceId deviceId) {
+ lsrIdDeviceIdMap.put(lsrId, deviceId);
+ return true;
+ }
+
+ @Override
+ public boolean removeLsrIdDevice(String lsrId) {
+ lsrIdDeviceIdMap.remove(lsrId);
+ return true;
+ }
+
+ @Override
+ public DeviceId getLsrIdDevice(String lsrId) {
+ return lsrIdDeviceIdMap.get(lsrId);
+ }
+
+ @Override
+ public boolean addPccLsr(DeviceId lsrId) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean removePccLsr(DeviceId lsrId) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean hasPccLsr(DeviceId lsrId) {
+ // TODO Auto-generated method stub
+ return false;
+ }
}
diff --git a/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/PcepPacketProvider.java b/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/PcepPacketProvider.java
index 41cf375..5d4a042 100644
--- a/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/PcepPacketProvider.java
+++ b/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/PcepPacketProvider.java
@@ -12,9 +12,7 @@
import org.onlab.packet.IPv4;
import org.onlab.packet.MacAddress;
import org.onlab.packet.TCP;
-import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
@@ -96,22 +94,7 @@
// Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
String lsrId = String.valueOf(pccId.ipAddress());
- DeviceId pccDeviceId = null;
-
- // Find PCC deviceID from lsrId stored as annotations
- Iterable<Device> devices = deviceService.getAvailableDevices();
- for (Device dev : devices) {
- if ("L3".equals(dev.annotations().value(AnnotationKeys.TYPE))
- && lsrId.equals(dev.annotations().value(LSRID))) {
- pccDeviceId = dev.id();
- break;
- }
- }
-
- if (pccDeviceId == null) {
- log.error("Device not found to perform label DB sync.");
- return;
- }
+ DeviceId pccDeviceId = DeviceId.deviceId(lsrId);
InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(pccDeviceId,
PortNumber.portNumber(PCEP_PORT)),