[ONOS-6241] (vNet) Can't find a virtual device Id
fix for ONOS-6241.
If there are two virtual devices with same deviceId on
the different tenant, our virtual network service failed
to return deviceId.
Change-Id: I7d2000a085406af9b003e52367d6de0f9990d6f0
diff --git a/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/DistributedVirtualNetworkStore.java b/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/DistributedVirtualNetworkStore.java
index 529a0cd..6447916 100644
--- a/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/DistributedVirtualNetworkStore.java
+++ b/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/DistributedVirtualNetworkStore.java
@@ -73,6 +73,7 @@
import java.util.HashSet;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -125,7 +126,7 @@
});
// Listener for virtual device events
- private final MapEventListener<DeviceId, VirtualDevice> virtualDeviceMapListener =
+ private final MapEventListener<VirtualDeviceId, VirtualDevice> virtualDeviceMapListener =
new InternalMapListener<>((mapEventType, virtualDevice) -> {
VirtualNetworkEvent.Type eventType =
mapEventType.equals(MapEvent.Type.INSERT)
@@ -143,8 +144,8 @@
private Map<TenantId, Set<NetworkId>> tenantIdNetworkIdSetMap;
// Track virtual devices by device Id
- private ConsistentMap<DeviceId, VirtualDevice> deviceIdVirtualDeviceConsistentMap;
- private Map<DeviceId, VirtualDevice> deviceIdVirtualDeviceMap;
+ private ConsistentMap<VirtualDeviceId, VirtualDevice> deviceIdVirtualDeviceConsistentMap;
+ private Map<VirtualDeviceId, VirtualDevice> deviceIdVirtualDeviceMap;
// Track device IDs by network Id
private ConsistentMap<NetworkId, Set<DeviceId>> networkIdDeviceIdSetConsistentMap;
@@ -181,6 +182,7 @@
.register(VirtualNetwork.class)
.register(DefaultVirtualNetwork.class)
.register(VirtualDevice.class)
+ .register(VirtualDeviceId.class)
.register(DefaultVirtualDevice.class)
.register(VirtualHost.class)
.register(DefaultVirtualHost.class)
@@ -226,7 +228,7 @@
.build();
tenantIdNetworkIdSetMap = tenantIdNetworkIdSetConsistentMap.asJavaMap();
- deviceIdVirtualDeviceConsistentMap = storageService.<DeviceId, VirtualDevice>consistentMapBuilder()
+ deviceIdVirtualDeviceConsistentMap = storageService.<VirtualDeviceId, VirtualDevice>consistentMapBuilder()
.withSerializer(SERIALIZER)
.withName("onos-deviceId-virtualdevice")
.withRelaxedReadConsistency()
@@ -395,17 +397,20 @@
return (networkIdVirtualNetworkMap.containsKey(networkId));
}
-
@Override
public VirtualDevice addDevice(NetworkId networkId, DeviceId deviceId) {
checkState(networkExists(networkId), "The network has not been added.");
+
Set<DeviceId> deviceIdSet = networkIdDeviceIdSetMap.get(networkId);
if (deviceIdSet == null) {
deviceIdSet = new HashSet<>();
}
+
+ checkState(!deviceIdSet.contains(deviceId), "The device already exists.");
+
VirtualDevice virtualDevice = new DefaultVirtualDevice(networkId, deviceId);
//TODO update both maps in one transaction.
- deviceIdVirtualDeviceMap.put(deviceId, virtualDevice);
+ deviceIdVirtualDeviceMap.put(new VirtualDeviceId(networkId, deviceId), virtualDevice);
deviceIdSet.add(deviceId);
networkIdDeviceIdSetMap.put(networkId, deviceIdSet);
return virtualDevice;
@@ -428,7 +433,7 @@
}
});
- if (deviceIdSet != null) {
+ if (!deviceIdSet.isEmpty()) {
networkIdDeviceIdSetMap.compute(networkId, (id, existingDeviceIds) -> {
if (existingDeviceIds == null || existingDeviceIds.isEmpty()) {
return new HashSet<>();
@@ -437,7 +442,7 @@
}
});
- deviceIdVirtualDeviceMap.remove(deviceId);
+ deviceIdVirtualDeviceMap.remove(new VirtualDeviceId(networkId, deviceId));
}
}
@@ -598,7 +603,7 @@
virtualPortSet = new HashSet<>();
}
- VirtualDevice device = deviceIdVirtualDeviceMap.get(deviceId);
+ VirtualDevice device = deviceIdVirtualDeviceMap.get(new VirtualDeviceId(networkId, deviceId));
checkNotNull(device, "The device has not been created for deviceId: " + deviceId);
checkState(!virtualPortExists(networkId, deviceId, portNumber),
@@ -625,7 +630,7 @@
p.number().equals(portNumber)).findFirst();
checkState(virtualPortOptional.isPresent(), "The virtual port has not been added.");
- VirtualDevice device = deviceIdVirtualDeviceMap.get(deviceId);
+ VirtualDevice device = deviceIdVirtualDeviceMap.get(new VirtualDeviceId(networkId, deviceId));
checkNotNull(device, "The device has not been created for deviceId: "
+ deviceId);
@@ -641,7 +646,7 @@
@Override
public void removePort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
checkState(networkExists(networkId), "The network has not been added.");
- VirtualDevice device = deviceIdVirtualDeviceMap.get(deviceId);
+ VirtualDevice device = deviceIdVirtualDeviceMap.get(new VirtualDeviceId(networkId, deviceId));
checkNotNull(device, "The device has not been created for deviceId: "
+ deviceId);
@@ -721,7 +726,8 @@
Set<DeviceId> deviceIdSet = networkIdDeviceIdSetMap.get(networkId);
Set<VirtualDevice> virtualDeviceSet = new HashSet<>();
if (deviceIdSet != null) {
- deviceIdSet.forEach(deviceId -> virtualDeviceSet.add(deviceIdVirtualDeviceMap.get(deviceId)));
+ deviceIdSet.forEach(deviceId -> virtualDeviceSet.add(
+ deviceIdVirtualDeviceMap.get(new VirtualDeviceId(networkId, deviceId))));
}
return ImmutableSet.copyOf(virtualDeviceSet);
}
@@ -930,4 +936,46 @@
}
}
}
+
+ /**
+ * A wrapper class to isolate device id from other virtual networks.
+ */
+
+ private static class VirtualDeviceId {
+
+ NetworkId networkId;
+ DeviceId deviceId;
+
+ public VirtualDeviceId(NetworkId networkId, DeviceId deviceId) {
+ this.networkId = networkId;
+ this.deviceId = deviceId;
+ }
+
+ public NetworkId getNetworkId() {
+ return networkId;
+ }
+
+ public DeviceId getDeviceId() {
+ return deviceId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(networkId, deviceId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof VirtualDeviceId) {
+ VirtualDeviceId that = (VirtualDeviceId) obj;
+ return this.deviceId.equals(that.deviceId) &&
+ this.networkId.equals(that.networkId);
+ }
+ return false;
+ }
+ }
}