ONOS-4075 - Distributed virtual network store implementation,
and virtual network manager Junit tests.
Change-Id: Ic1f82822c894e3c394aa95df1e76ae59fe218120
diff --git a/core/api/src/test/java/org/onosproject/store/service/DistributedSetTest.java b/core/api/src/test/java/org/onosproject/store/service/DistributedSetTest.java
index 633786d..e8dbeb6 100644
--- a/core/api/src/test/java/org/onosproject/store/service/DistributedSetTest.java
+++ b/core/api/src/test/java/org/onosproject/store/service/DistributedSetTest.java
@@ -64,7 +64,7 @@
public void basicTests() {
set1.add("item1");
assertEquals("The set name should match.", SETNAME, set1.name());
- assertEquals("The set name should match.", DistributedPrimitive.Type.SET, set1.primitiveType());
+ assertEquals("The set primitive type should match.", DistributedPrimitive.Type.SET, set1.primitiveType());
set1.add("item2");
set1.add("item3");
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualDevice.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualDevice.java
index e3339a9..06225ff 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualDevice.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualDevice.java
@@ -27,7 +27,7 @@
/**
* Default representation of a virtual device.
*/
-public class DefaultVirtualDevice extends DefaultDevice implements VirtualDevice {
+public final class DefaultVirtualDevice extends DefaultDevice implements VirtualDevice {
private static final String VIRTUAL = "virtual";
private static final ProviderId PID = new ProviderId(VIRTUAL, VIRTUAL);
@@ -53,7 +53,7 @@
@Override
public int hashCode() {
- return 31 * super.hashCode() + networkId.hashCode();
+ return Objects.hash(networkId);
}
@Override
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualLink.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualLink.java
new file mode 100644
index 0000000..89374d4
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualLink.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2016 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.incubator.net.virtual;
+
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default representation of a virtual link.
+ */
+public final class DefaultVirtualLink extends DefaultLink implements VirtualLink {
+
+ private static final String VIRTUAL = "virtual";
+ private static final ProviderId PID = new ProviderId(VIRTUAL, VIRTUAL);
+
+ private final NetworkId networkId;
+ private final TunnelId tunnelId;
+
+ /**
+ * Constructor for a default virtual link.
+ *
+ * @param networkId network identifier
+ * @param src source connection point
+ * @param dst destination connection point
+ * @param tunnelId tunnel identifier
+ */
+ public DefaultVirtualLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) {
+ super(PID, src, dst, Type.VIRTUAL, DefaultAnnotations.builder().build());
+ this.networkId = networkId;
+ this.tunnelId = tunnelId;
+ }
+
+ @Override
+ public NetworkId networkId() {
+ return networkId;
+ }
+
+ /**
+ * Returns the tunnel identifier.
+ *
+ * @return tunnel identifier.
+ */
+ public TunnelId tunnelId() {
+ return tunnelId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(networkId, tunnelId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultVirtualLink) {
+ DefaultVirtualLink that = (DefaultVirtualLink) obj;
+ return super.equals(that) &&
+ Objects.equals(this.networkId, that.networkId) &&
+ Objects.equals(this.tunnelId, that.tunnelId);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("networkId", networkId).add("tunnelId", tunnelId).toString();
+ }
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetwork.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetwork.java
index c114191..360d385 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetwork.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetwork.java
@@ -22,7 +22,7 @@
/**
* Default implementation of the virtual network descriptor.
*/
-public class DefaultVirtualNetwork implements VirtualNetwork {
+public final class DefaultVirtualNetwork implements VirtualNetwork {
private final NetworkId id;
private final TenantId tenantId;
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualPort.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualPort.java
new file mode 100644
index 0000000..ad56efb
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/DefaultVirtualPort.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2016 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.incubator.net.virtual;
+
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.Element;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default representation of a virtual port.
+ */
+public final class DefaultVirtualPort extends DefaultPort implements VirtualPort {
+
+
+ private final NetworkId networkId;
+ private final Port realizedBy;
+
+ public DefaultVirtualPort(NetworkId networkId, Device device, PortNumber portNumber, Port realizedBy) {
+ super((Element) device, portNumber, false, DefaultAnnotations.builder().build());
+ this.networkId = networkId;
+ this.realizedBy = realizedBy;
+ }
+
+ public NetworkId networkId() {
+ return networkId;
+ }
+
+ @Override
+ public Port realizedBy() {
+ return realizedBy;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(networkId, realizedBy);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultVirtualPort) {
+ DefaultVirtualPort that = (DefaultVirtualPort) obj;
+ return super.equals(that) &&
+ Objects.equals(this.networkId, that.networkId) &&
+ Objects.equals(this.realizedBy, that.realizedBy);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this).add("networkId", networkId).add("realizedBy", realizedBy).toString();
+ }
+
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java
index 01681ef..c83b2c5 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java
@@ -27,6 +27,11 @@
public interface VirtualNetworkService {
/**
+ * The topic used for obtaining globally unique ids.
+ */
+ String VIRTUAL_NETWORK_TOPIC = "virtual-network-ids";
+
+ /**
* Returns a collection of all virtual networks created on behalf of the
* specified tenant.
*
diff --git a/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualDeviceTest.java b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualDeviceTest.java
new file mode 100644
index 0000000..b99e7e6
--- /dev/null
+++ b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualDeviceTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2016 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.incubator.net.virtual;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onosproject.net.DeviceId;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Test of the default virtual device model entity.
+ */
+public class DefaultVirtualDeviceTest {
+ final String deviceIdValue1 = "DEVICE_ID1";
+ final String deviceIdValue2 = "DEVICE_ID2";
+
+ /**
+ * Checks that the DefaultVirtualDevice class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(DefaultVirtualDevice.class);
+ }
+
+ @Test
+ public void testEquality() {
+ DefaultVirtualDevice device1 =
+ new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue1));
+ DefaultVirtualDevice device2 =
+ new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue1));
+ DefaultVirtualDevice device3 =
+ new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue2));
+ DefaultVirtualDevice device4 =
+ new DefaultVirtualDevice(NetworkId.networkId(1), DeviceId.deviceId(deviceIdValue1));
+
+ new EqualsTester().addEqualityGroup(device1, device2).addEqualityGroup(device3)
+ .addEqualityGroup(device4).testEquals();
+ }
+}
diff --git a/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualLinkTest.java b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualLinkTest.java
new file mode 100644
index 0000000..5661cb9
--- /dev/null
+++ b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualLinkTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2016 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.incubator.net.virtual;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Test of the default virtual link model entity.
+ */
+public class DefaultVirtualLinkTest {
+ final String deviceIdValue1 = "DEVICE_ID1";
+ final String deviceIdValue2 = "DEVICE_ID2";
+
+ /**
+ * Checks that the DefaultVirtualLink class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(DefaultVirtualLink.class);
+ }
+
+ @Test
+ public void testEquality() {
+ DefaultVirtualDevice device1 =
+ new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue1));
+ DefaultVirtualDevice device2 =
+ new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue2));
+ ConnectPoint src = new ConnectPoint(device1.id(), PortNumber.portNumber(1));
+ ConnectPoint dst = new ConnectPoint(device2.id(), PortNumber.portNumber(2));
+
+ DefaultVirtualLink link1 = new DefaultVirtualLink(NetworkId.networkId(0), src, dst, TunnelId.valueOf(0));
+ DefaultVirtualLink link2 = new DefaultVirtualLink(NetworkId.networkId(0), src, dst, TunnelId.valueOf(0));
+ DefaultVirtualLink link3 = new DefaultVirtualLink(NetworkId.networkId(0), src, dst, TunnelId.valueOf(1));
+ DefaultVirtualLink link4 = new DefaultVirtualLink(NetworkId.networkId(1), src, dst, TunnelId.valueOf(0));
+
+ new EqualsTester().addEqualityGroup(link1, link2).addEqualityGroup(link3)
+ .addEqualityGroup(link4).testEquals();
+ }
+}
diff --git a/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetworkTest.java b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetworkTest.java
new file mode 100644
index 0000000..c8f79b1
--- /dev/null
+++ b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualNetworkTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 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.incubator.net.virtual;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Test of the default virtual network model entity.
+ */
+public class DefaultVirtualNetworkTest {
+ final String tenantIdValue1 = "TENANT_ID1";
+ final String tenantIdValue2 = "TENANT_ID2";
+
+ /**
+ * Checks that the DefaultVirtualNetwork class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(DefaultVirtualNetwork.class);
+ }
+
+ @Test
+ public void testEquality() {
+ DefaultVirtualNetwork network1 =
+ new DefaultVirtualNetwork(NetworkId.networkId(0), TenantId.tenantId(tenantIdValue1));
+ DefaultVirtualNetwork network2 =
+ new DefaultVirtualNetwork(NetworkId.networkId(0), TenantId.tenantId(tenantIdValue1));
+ DefaultVirtualNetwork network3 =
+ new DefaultVirtualNetwork(NetworkId.networkId(0), TenantId.tenantId(tenantIdValue2));
+ DefaultVirtualNetwork network4 =
+ new DefaultVirtualNetwork(NetworkId.networkId(1), TenantId.tenantId(tenantIdValue2));
+
+ new EqualsTester().addEqualityGroup(network1, network2).addEqualityGroup(network3)
+ .addEqualityGroup(network4).testEquals();
+ }
+}
diff --git a/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualPortTest.java b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualPortTest.java
new file mode 100644
index 0000000..6838ef5
--- /dev/null
+++ b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/DefaultVirtualPortTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2016 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.incubator.net.virtual;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Test of the default virtual port model entity.
+ */
+public class DefaultVirtualPortTest {
+ final String deviceIdValue1 = "DEVICE_ID1";
+ final String deviceIdValue2 = "DEVICE_ID2";
+
+ /**
+ * Checks that the DefaultVirtualPort class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(DefaultVirtualPort.class);
+ }
+
+ @Test
+ public void testEquality() {
+ DefaultVirtualDevice device1 =
+ new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue1));
+ DefaultVirtualDevice device2 =
+ new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue2));
+
+ Port portA = new DefaultPort(device1, PortNumber.portNumber(1), true);
+ Port portB = new DefaultPort(device1, PortNumber.portNumber(2), true);
+ Port portC = new DefaultPort(device2, PortNumber.portNumber(2), true);
+
+ DefaultVirtualPort port1 =
+ new DefaultVirtualPort(NetworkId.networkId(0), device1, PortNumber.portNumber(1), portA);
+ DefaultVirtualPort port2 =
+ new DefaultVirtualPort(NetworkId.networkId(0), device1, PortNumber.portNumber(1), portA);
+ DefaultVirtualPort port3 =
+ new DefaultVirtualPort(NetworkId.networkId(0), device1, PortNumber.portNumber(2), portB);
+ DefaultVirtualPort port4 =
+ new DefaultVirtualPort(NetworkId.networkId(1), device2, PortNumber.portNumber(2), portC);
+
+
+ new EqualsTester().addEqualityGroup(port1, port2).addEqualityGroup(port3)
+ .addEqualityGroup(port4).testEquals();
+ }
+}
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java
index fe9f884..f7c54d6 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Open Networking Laboratory
+ * Copyright 2016 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.
@@ -57,7 +57,7 @@
@Service
public class VirtualNetworkManager
extends AbstractListenerProviderRegistry<VirtualNetworkEvent, VirtualNetworkListener,
- VirtualNetworkProvider, VirtualNetworkProviderService>
+ VirtualNetworkProvider, VirtualNetworkProviderService>
implements VirtualNetworkService, VirtualNetworkAdminService, VirtualNetworkProviderRegistry {
private final Logger log = LoggerFactory.getLogger(getClass());
@@ -70,19 +70,23 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected VirtualNetworkStore store;
- private VirtualNetworkStoreDelegate delegate = new InternalStoreDelegate();
+ private VirtualNetworkStoreDelegate delegate = this::post;
// TODO: figure out how to coordinate "implementation" of a virtual network in a cluster
@Activate
protected void activate() {
store.setDelegate(delegate);
+ eventDispatcher.addSink(VirtualNetworkEvent.class, listenerRegistry);
+
log.info("Started");
}
@Deactivate
protected void deactivate() {
store.unsetDelegate(delegate);
+ eventDispatcher.removeSink(VirtualNetworkEvent.class);
+
log.info("Stopped");
}
@@ -211,13 +215,4 @@
}
}
- // Auxiliary store delegate to receive notification about changes in
- // the virtual network configuration store state - by the store itself.
- private class InternalStoreDelegate implements VirtualNetworkStoreDelegate {
- @Override
- public void notify(VirtualNetworkEvent event) {
- post(event);
- }
- }
-
}
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java
new file mode 100644
index 0000000..8976a7e
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright 2016 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.incubator.net.virtual.impl;
+
+import com.google.common.collect.Lists;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestTools;
+import org.onlab.junit.TestUtils;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.event.Event;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkListener;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.*;
+
+/**
+ * Junit tests for VirtualNetworkManager.
+ */
+public class VirtualNetworkManagerTest {
+ final String tenantIdValue1 = "TENANT_ID1";
+ final String tenantIdValue2 = "TENANT_ID2";
+ final String deviceIdValue1 = "DEVICE_ID1";
+ final String deviceIdValue2 = "DEVICE_ID2";
+
+ private VirtualNetworkManager manager;
+ private VirtualNetworkService virtualNetworkManagerService;
+ private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+ private CoreService coreService;
+ protected TestListener listener = new TestListener();
+
+ @Before
+ public void setUp() throws Exception {
+ virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+ coreService = new TestCoreService();
+ virtualNetworkManagerStore.setCoreService(coreService);
+ TestUtils.setField(coreService, "coreService", new TestCoreService());
+ TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+ virtualNetworkManagerStore.activate();
+
+ manager = new VirtualNetworkManager();
+ manager.store = virtualNetworkManagerStore;
+ manager.addListener(listener);
+ NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+ manager.activate();
+ virtualNetworkManagerService = manager;
+
+ }
+
+ @After
+ public void tearDown() {
+ virtualNetworkManagerStore.deactivate();
+ manager.removeListener(listener);
+ manager.deactivate();
+ NetTestTools.injectEventDispatcher(manager, null);
+ }
+
+ /**
+ * Tests registering a null tenant id.
+ */
+ @Test(expected = NullPointerException.class)
+ public void testRegisterNullTenantId() {
+ manager.registerTenantId(null);
+ }
+
+ /**
+ * Tests registering/unregistering a tenant id.
+ */
+ @Test
+ public void testRegisterUnregisterTenantId() {
+ manager.unregisterTenantId(TenantId.tenantId(tenantIdValue1));
+ manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+ manager.registerTenantId(TenantId.tenantId(tenantIdValue2));
+ Collection<TenantId> tenantIdCollection = manager.getTenantIds();
+ assertEquals("The tenantId set size did not match.", 2, tenantIdCollection.size());
+
+ manager.unregisterTenantId(TenantId.tenantId(tenantIdValue1));
+ manager.unregisterTenantId(TenantId.tenantId(tenantIdValue2));
+ tenantIdCollection = manager.getTenantIds();
+ assertTrue("The tenantId set should be empty.", tenantIdCollection.isEmpty());
+
+ // Validate that the events were all received in the correct order.
+ validateEvents(VirtualNetworkEvent.Type.TENANT_UNREGISTERED, VirtualNetworkEvent.Type.TENANT_REGISTERED,
+ VirtualNetworkEvent.Type.TENANT_REGISTERED, VirtualNetworkEvent.Type.TENANT_UNREGISTERED,
+ VirtualNetworkEvent.Type.TENANT_UNREGISTERED);
+ }
+
+ /**
+ * Tests adding a null virtual network.
+ */
+ @Test(expected = NullPointerException.class)
+ public void testCreateNullVirtualNetwork() {
+ manager.createVirtualNetwork(null);
+ }
+
+ /**
+ * Tests add and remove of virtual networks.
+ */
+ @Test
+ public void testAddRemoveVirtualNetwork() {
+ manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+ manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+ manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+ Set<VirtualNetwork> virtualNetworks = manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1));
+ assertNotNull("The virtual network set should not be null", virtualNetworks);
+ assertEquals("The virtual network set size did not match.", 2, virtualNetworks.size());
+
+ for (VirtualNetwork virtualNetwork : virtualNetworks) {
+ manager.removeVirtualNetwork(virtualNetwork.id());
+ // attempt to remove the same virtual network again.
+ manager.removeVirtualNetwork(virtualNetwork.id());
+ }
+ virtualNetworks = manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1));
+ assertTrue("The virtual network set should be empty.", virtualNetworks.isEmpty());
+
+ // Validate that the events were all received in the correct order.
+ validateEvents(VirtualNetworkEvent.Type.TENANT_REGISTERED, VirtualNetworkEvent.Type.NETWORK_ADDED,
+ VirtualNetworkEvent.Type.NETWORK_ADDED, VirtualNetworkEvent.Type.NETWORK_REMOVED,
+ VirtualNetworkEvent.Type.NETWORK_REMOVED);
+ }
+
+ /**
+ * Tests adding a null virtual device.
+ */
+ @Test(expected = NullPointerException.class)
+ public void testCreateNullVirtualDevice() {
+ manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+ VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+ manager.createVirtualDevice(virtualNetwork.id(), null);
+ }
+
+ /**
+ * Tests adding a virtual device where no virtual network exists.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testCreateVirtualDeviceWithNoNetwork() {
+ manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+ VirtualNetwork virtualNetwork = new DefaultVirtualNetwork(NetworkId.NONE, TenantId.tenantId(tenantIdValue1));
+
+ manager.createVirtualDevice(virtualNetwork.id(), DeviceId.deviceId(deviceIdValue1));
+ }
+
+ /**
+ * Tests add and remove of virtual devices.
+ */
+ @Test
+ public void testAddRemoveVirtualDevice() {
+ manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+ VirtualNetwork virtualNetwork1 = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+ VirtualNetwork virtualNetwork2 = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+ manager.createVirtualDevice(virtualNetwork1.id(), DeviceId.deviceId(deviceIdValue1));
+ manager.createVirtualDevice(virtualNetwork2.id(), DeviceId.deviceId(deviceIdValue2));
+
+ Set<VirtualDevice> virtualDevices1 = manager.getVirtualDevices(virtualNetwork1.id());
+ assertNotNull("The virtual device set should not be null", virtualDevices1);
+ assertEquals("The virtual device set size did not match.", 1, virtualDevices1.size());
+
+ Set<VirtualDevice> virtualDevices2 = manager.getVirtualDevices(virtualNetwork2.id());
+ assertNotNull("The virtual device set should not be null", virtualDevices2);
+ assertEquals("The virtual device set size did not match.", 1, virtualDevices2.size());
+
+ for (VirtualDevice virtualDevice : virtualDevices1) {
+ manager.removeVirtualDevice(virtualNetwork1.id(), virtualDevice.id());
+ // attempt to remove the same virtual device again.
+ manager.removeVirtualDevice(virtualNetwork1.id(), virtualDevice.id());
+ }
+ virtualDevices1 = manager.getVirtualDevices(virtualNetwork1.id());
+ assertTrue("The virtual device set should be empty.", virtualDevices1.isEmpty());
+
+ // Validate that the events were all received in the correct order.
+ validateEvents(VirtualNetworkEvent.Type.TENANT_REGISTERED, VirtualNetworkEvent.Type.NETWORK_ADDED,
+ VirtualNetworkEvent.Type.NETWORK_ADDED);
+ }
+
+ /**
+ * Tests add and remove of virtual links.
+ */
+ @Test
+ public void testAddRemoveVirtualLink() {
+ manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+ VirtualNetwork virtualNetwork1 = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+ VirtualDevice srcVirtualDevice =
+ manager.createVirtualDevice(virtualNetwork1.id(), DeviceId.deviceId(deviceIdValue1));
+ VirtualDevice dstVirtualDevice =
+ manager.createVirtualDevice(virtualNetwork1.id(), DeviceId.deviceId(deviceIdValue2));
+ ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
+ ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
+ manager.createVirtualLink(virtualNetwork1.id(), src, dst, TunnelId.valueOf(0));
+ manager.createVirtualLink(virtualNetwork1.id(), dst, src, TunnelId.valueOf(1));
+
+ Set<VirtualLink> virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
+ assertNotNull("The virtual link set should not be null", virtualLinks);
+ assertEquals("The virtual link set size did not match.", 2, virtualLinks.size());
+
+ for (VirtualLink virtualLink : virtualLinks) {
+ manager.removeVirtualLink(virtualLink.networkId(), virtualLink.src(), virtualLink.dst());
+ // attempt to remove the same virtual link again.
+ manager.removeVirtualLink(virtualLink.networkId(), virtualLink.src(), virtualLink.dst());
+ }
+ virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
+ assertTrue("The virtual link set should be empty.", virtualLinks.isEmpty());
+ }
+
+ /**
+ * Tests add and remove of virtual ports.
+ */
+ @Test
+ public void testAddRemoveVirtualPort() {
+ manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+ VirtualNetwork virtualNetwork1 = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+ VirtualDevice srcVirtualDevice =
+ manager.createVirtualDevice(virtualNetwork1.id(), DeviceId.deviceId(deviceIdValue1));
+ VirtualDevice dstVirtualDevice =
+ manager.createVirtualDevice(virtualNetwork1.id(), DeviceId.deviceId(deviceIdValue2));
+ Port port = new DefaultPort(srcVirtualDevice, PortNumber.portNumber(1), true);
+
+ manager.createVirtualPort(virtualNetwork1.id(), srcVirtualDevice.id(), PortNumber.portNumber(1), port);
+ manager.createVirtualPort(virtualNetwork1.id(), dstVirtualDevice.id(), PortNumber.portNumber(1), port);
+
+ Set<VirtualPort> virtualPorts = manager.getVirtualPorts(virtualNetwork1.id(), srcVirtualDevice.id());
+ assertNotNull("The virtual port set should not be null", virtualPorts);
+ assertEquals("The virtual port set size did not match.", 2, virtualPorts.size());
+
+ for (VirtualPort virtualPort : virtualPorts) {
+ manager.removeVirtualPort(virtualNetwork1.id(),
+ (DeviceId) virtualPort.element().id(), virtualPort.number());
+ // attempt to remove the same virtual port again.
+ manager.removeVirtualPort(virtualNetwork1.id(),
+ (DeviceId) virtualPort.element().id(), virtualPort.number());
+ }
+ virtualPorts = manager.getVirtualPorts(virtualNetwork1.id(), srcVirtualDevice.id());
+ assertTrue("The virtual port set should be empty.", virtualPorts.isEmpty());
+ }
+
+ /**
+ * Method to validate that the actual versus expected virtual network events were
+ * received correctly.
+ *
+ * @param types expected virtual network events.
+ */
+ private void validateEvents(Enum... types) {
+ TestTools.assertAfter(100, () -> {
+ int i = 0;
+ assertEquals("wrong events received", types.length, listener.events.size());
+ for (Event event : listener.events) {
+ assertEquals("incorrect event type", types[i], event.type());
+ i++;
+ }
+ listener.events.clear();
+ });
+ }
+
+ /**
+ * Test listener class to receive virtual network events.
+ */
+ private static class TestListener implements VirtualNetworkListener {
+
+ protected List<VirtualNetworkEvent> events = Lists.newArrayList();
+
+ @Override
+ public void event(VirtualNetworkEvent event) {
+ events.add(event);
+ }
+
+ }
+
+ private class TestCoreService extends CoreServiceAdapter {
+
+ @Override
+ public IdGenerator getIdGenerator(String topic) {
+ return new IdGenerator() {
+ private AtomicLong counter = new AtomicLong(0);
+
+ @Override
+ public long getNewId() {
+ return counter.getAndIncrement();
+ }
+ };
+ }
+ }
+}
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 69e56c0..65cee11 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Open Networking Laboratory
+ * Copyright 2016 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.
@@ -15,35 +15,59 @@
*/
package org.onosproject.incubator.store.virtual.impl;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
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.util.KryoNamespace;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
+import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
+import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
import org.onosproject.incubator.net.virtual.NetworkId;
import org.onosproject.incubator.net.virtual.TenantId;
import org.onosproject.incubator.net.virtual.VirtualDevice;
import org.onosproject.incubator.net.virtual.VirtualLink;
import org.onosproject.incubator.net.virtual.VirtualNetwork;
import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
import org.onosproject.incubator.net.virtual.VirtualNetworkStoreDelegate;
import org.onosproject.incubator.net.virtual.VirtualPort;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.store.AbstractStore;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.DistributedSet;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.MapEventListener;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.SetEvent;
+import org.onosproject.store.service.SetEventListener;
+import org.onosproject.store.service.StorageService;
import org.slf4j.Logger;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
import static org.slf4j.LoggerFactory.getLogger;
/**
- * Implementation of the network store.
+ * Implementation of the virtual network store.
*/
@Component(immediate = true)
@Service
@@ -53,95 +77,404 @@
private final Logger log = getLogger(getClass());
- // TODO: track tenants by ID
- // TODO: track networks by ID and by tenants
- // TODO: track devices by network ID and device ID
- // TODO: track devices by network ID
- // TODO: setup block allocator for network IDs
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected StorageService storageService;
- // TODO: notify delegate
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+ private IdGenerator idGenerator;
+
+ // Track tenants by ID
+ private DistributedSet<TenantId> tenantIdSet;
+
+ // Listener for tenant events
+ private final SetEventListener<TenantId> setListener = new InternalSetListener();
+
+ // Track virtual networks by network Id
+ private ConsistentMap<NetworkId, VirtualNetwork> networkIdVirtualNetworkConsistentMap;
+ private Map<NetworkId, VirtualNetwork> networkIdVirtualNetworkMap;
+
+ // Listener for virtual network events
+ private final MapEventListener<NetworkId, VirtualNetwork> virtualMapListener = new InternalMapListener();
+
+ // Track virtual network IDs by tenant Id
+ private ConsistentMap<TenantId, Set<NetworkId>> tenantIdNetworkIdSetConsistentMap;
+ private Map<TenantId, Set<NetworkId>> tenantIdNetworkIdSetMap;
+
+ // Track virtual devices by device Id
+ private ConsistentMap<DeviceId, VirtualDevice> deviceIdVirtualDeviceConsistentMap;
+ private Map<DeviceId, VirtualDevice> deviceIdVirtualDeviceMap;
+
+ // Track device IDs by network Id
+ private ConsistentMap<NetworkId, Set<DeviceId>> networkIdDeviceIdSetConsistentMap;
+ private Map<NetworkId, Set<DeviceId>> networkIdDeviceIdSetMap;
+
+ // Track virtual links by network Id
+ private ConsistentMap<NetworkId, Set<VirtualLink>> networkIdVirtualLinkSetConsistentMap;
+ private Map<NetworkId, Set<VirtualLink>> networkIdVirtualLinkSetMap;
+
+ // Track virtual ports by network Id
+ private ConsistentMap<NetworkId, Set<VirtualPort>> networkIdVirtualPortSetConsistentMap;
+ private Map<NetworkId, Set<VirtualPort>> networkIdVirtualPortSetMap;
+
+ private static final Serializer SERIALIZER = Serializer
+ .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
+ .register(TenantId.class)
+ .register(NetworkId.class).register(DeviceId.class)
+ .register(VirtualNetwork.class)
+ .register(VirtualDevice.class)
+ .register(VirtualLink.class)
+ .register(VirtualPort.class)
+ .register(DeviceId.class)
+ .register(Device.class)
+ .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID).build());
+
+ /**
+ * Distributed network store service activate method.
+ */
@Activate
public void activate() {
+ idGenerator = coreService.getIdGenerator(VirtualNetworkService.VIRTUAL_NETWORK_TOPIC);
+
+ tenantIdSet = storageService.<TenantId>setBuilder()
+ .withSerializer(SERIALIZER)
+ .withName("onos-tenantId")
+ .withRelaxedReadConsistency()
+ .build()
+ .asDistributedSet();
+ tenantIdSet.addListener(setListener);
+
+ networkIdVirtualNetworkConsistentMap = storageService.<NetworkId, VirtualNetwork>consistentMapBuilder()
+ .withSerializer(SERIALIZER)
+ .withName("onos-networkId-virtualnetwork")
+ .withRelaxedReadConsistency()
+ .build();
+ networkIdVirtualNetworkConsistentMap.addListener(virtualMapListener);
+ networkIdVirtualNetworkMap = networkIdVirtualNetworkConsistentMap.asJavaMap();
+
+ tenantIdNetworkIdSetConsistentMap = storageService.<TenantId, Set<NetworkId>>consistentMapBuilder()
+ .withSerializer(SERIALIZER)
+ .withName("onos-tenantId-networkIds")
+ .withRelaxedReadConsistency()
+ .build();
+ tenantIdNetworkIdSetMap = tenantIdNetworkIdSetConsistentMap.asJavaMap();
+
+ deviceIdVirtualDeviceConsistentMap = storageService.<DeviceId, VirtualDevice>consistentMapBuilder()
+ .withSerializer(SERIALIZER)
+ .withName("onos-deviceId-virtualdevice")
+ .withRelaxedReadConsistency()
+ .build();
+ deviceIdVirtualDeviceMap = deviceIdVirtualDeviceConsistentMap.asJavaMap();
+
+ networkIdDeviceIdSetConsistentMap = storageService.<NetworkId, Set<DeviceId>>consistentMapBuilder()
+ .withSerializer(SERIALIZER)
+ .withName("onos-networkId-deviceIds")
+ .withRelaxedReadConsistency()
+ .build();
+ networkIdDeviceIdSetMap = networkIdDeviceIdSetConsistentMap.asJavaMap();
+
+ networkIdVirtualLinkSetConsistentMap = storageService.<NetworkId, Set<VirtualLink>>consistentMapBuilder()
+ .withSerializer(SERIALIZER)
+ .withName("onos-networkId-virtuallinks")
+ .withRelaxedReadConsistency()
+ .build();
+ networkIdVirtualLinkSetMap = networkIdVirtualLinkSetConsistentMap.asJavaMap();
+
+ networkIdVirtualPortSetConsistentMap = storageService.<NetworkId, Set<VirtualPort>>consistentMapBuilder()
+ .withSerializer(SERIALIZER)
+ .withName("onos-networkId-virtualportss")
+ .withRelaxedReadConsistency()
+ .build();
+ networkIdVirtualPortSetMap = networkIdVirtualPortSetConsistentMap.asJavaMap();
+
log.info("Started");
}
+ /**
+ * Distributed network store service deactivate method.
+ */
@Deactivate
public void deactivate() {
+ tenantIdSet.removeListener(setListener);
+ networkIdVirtualNetworkConsistentMap.removeListener(virtualMapListener);
log.info("Stopped");
}
+ /**
+ * This method is used for Junit tests to set the CoreService instance, which
+ * is required to set the IdGenerator instance.
+ *
+ * @param coreService core service instance
+ */
+ public void setCoreService(CoreService coreService) {
+ this.coreService = coreService;
+ }
+
@Override
public void addTenantId(TenantId tenantId) {
+ tenantIdSet.add(tenantId);
}
@Override
public void removeTenantId(TenantId tenantId) {
+ tenantIdSet.remove(tenantId);
}
@Override
public Set<TenantId> getTenantIds() {
- return null;
+ return ImmutableSet.copyOf(tenantIdSet);
}
@Override
public VirtualNetwork addNetwork(TenantId tenantId) {
- return new DefaultVirtualNetwork(genNetworkId(), tenantId);
+
+ checkState(tenantIdSet.contains(tenantId), "The tenant has not been registered. " + tenantId.id());
+ VirtualNetwork virtualNetwork = new DefaultVirtualNetwork(genNetworkId(), tenantId);
+ //TODO update both maps in one transaction.
+ networkIdVirtualNetworkMap.put(virtualNetwork.id(), virtualNetwork);
+ Set<NetworkId> virtualNetworkSet = tenantIdNetworkIdSetMap.get(tenantId);
+ if (virtualNetworkSet == null) {
+ virtualNetworkSet = new HashSet<>();
+ }
+ virtualNetworkSet.add(virtualNetwork.id());
+ tenantIdNetworkIdSetMap.put(tenantId, virtualNetworkSet);
+ return virtualNetwork;
}
+ /**
+ * Returns a new network identifier from a virtual network block of identifiers.
+ *
+ * @return NetworkId network identifier
+ */
private NetworkId genNetworkId() {
- return NetworkId.networkId(0); // TODO: use a block allocator
+ return NetworkId.networkId(idGenerator.getNewId());
}
@Override
public void removeNetwork(NetworkId networkId) {
+ // Make sure that the virtual network exists before attempting to remove it.
+ if (networkExists(networkId)) {
+ VirtualNetwork virtualNetwork = networkIdVirtualNetworkMap.get(networkId);
+ if (virtualNetwork == null) {
+ return;
+ }
+ //TODO update both maps in one transaction.
+ TenantId tenantId = virtualNetwork.tenantId();
+ networkIdVirtualNetworkMap.compute(networkId, (id, existingVirtualNetwork) -> null);
+
+
+ Set<NetworkId> virtualNetworkSet = tenantIdNetworkIdSetMap.get(tenantId);
+ tenantIdNetworkIdSetMap.compute(virtualNetwork.tenantId(), (id, existingNetworkIds) -> {
+ if (existingNetworkIds == null || existingNetworkIds.isEmpty()) {
+ return ImmutableSet.of();
+ } else {
+ return ImmutableSet.<NetworkId>builder()
+ .addAll(Sets.difference(existingNetworkIds,
+ ImmutableSet.copyOf(virtualNetworkSet)))
+ .build();
+ }
+ });
+ }
+ }
+
+ /**
+ * Returns if the network identifier exists.
+ *
+ * @param networkId network identifier
+ * @return true if the network identifier exists, false otherwise.
+ */
+ private boolean networkExists(NetworkId networkId) {
+ return (networkIdVirtualNetworkMap.containsKey(networkId));
}
@Override
public VirtualDevice addDevice(NetworkId networkId, DeviceId deviceId) {
- return new DefaultVirtualDevice(networkId, deviceId);
+ checkState(networkExists(networkId), "The network has not been added.");
+ Set<DeviceId> deviceIdSet = networkIdDeviceIdSetMap.get(networkId);
+ if (deviceIdSet == null) {
+ deviceIdSet = new HashSet<>();
+ }
+ VirtualDevice virtualDevice = new DefaultVirtualDevice(networkId, deviceId);
+ //TODO update both maps in one transaction.
+ deviceIdVirtualDeviceMap.put(deviceId, virtualDevice);
+ deviceIdSet.add(deviceId);
+ networkIdDeviceIdSetMap.put(networkId, deviceIdSet);
+ return virtualDevice;
}
@Override
public void removeDevice(NetworkId networkId, DeviceId deviceId) {
+ checkState(networkExists(networkId), "The network has not been added.");
+ //TODO update both maps in one transaction.
+ Set<DeviceId> deviceIdSet = networkIdDeviceIdSetMap.get(networkId);
+ if (deviceIdSet != null) {
+ networkIdDeviceIdSetMap.compute(networkId, (id, existingDeviceIds) -> {
+ if (existingDeviceIds == null || existingDeviceIds.isEmpty()) {
+ return ImmutableSet.of();
+ } else {
+ return ImmutableSet.<DeviceId>builder()
+ .addAll(Sets.difference(existingDeviceIds,
+ ImmutableSet.copyOf(deviceIdSet)))
+ .build();
+ }
+ });
+
+ deviceIdVirtualDeviceMap.compute(deviceId, (id, existingVirtualDevice) -> null);
+
+ log.info("The deviceIdVirtualDeviceMap size is: " + getDevices(networkId));
+ }
}
@Override
public VirtualLink addLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId realizedBy) {
- return null;
+ checkState(networkExists(networkId), "The network has not been added.");
+ Set<VirtualLink> virtualLinkSet = networkIdVirtualLinkSetMap.get(networkId);
+ if (virtualLinkSet == null) {
+ virtualLinkSet = new HashSet<>();
+ }
+ VirtualLink virtualLink = new DefaultVirtualLink(networkId, src, dst, realizedBy);
+ virtualLinkSet.add(virtualLink);
+ networkIdVirtualLinkSetMap.put(networkId, virtualLinkSet);
+ return virtualLink;
}
@Override
public void removeLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
+ checkState(networkExists(networkId), "The network has not been added.");
+ Set<VirtualLink> virtualLinkSet = networkIdVirtualLinkSetMap.get(networkId);
+ if (virtualLinkSet != null) {
+ networkIdVirtualLinkSetMap.compute(networkId, (id, existingVirtualLinks) -> {
+ if (existingVirtualLinks == null || existingVirtualLinks.isEmpty()) {
+ return ImmutableSet.of();
+ } else {
+ return ImmutableSet.<VirtualLink>builder()
+ .addAll(Sets.difference(existingVirtualLinks,
+ ImmutableSet.copyOf(virtualLinkSet)))
+ .build();
+ }
+ });
+ }
}
@Override
public VirtualPort addPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber, Port realizedBy) {
- return null;
+ checkState(networkExists(networkId), "The network has not been added.");
+ Set<VirtualPort> virtualPortSet = networkIdVirtualPortSetMap.get(networkId);
+ if (virtualPortSet == null) {
+ virtualPortSet = new HashSet<>();
+ }
+ Device device = deviceIdVirtualDeviceMap.get(deviceId);
+ checkNotNull(device, "The device has not been created for deviceId: " + deviceId);
+ VirtualPort virtualPort = new DefaultVirtualPort(networkId, device, portNumber, realizedBy);
+ virtualPortSet.add(virtualPort);
+ networkIdVirtualPortSetMap.put(networkId, virtualPortSet);
+ return virtualPort;
}
@Override
public void removePort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
+ checkState(networkExists(networkId), "The network has not been added.");
+ Set<VirtualPort> virtualPortSet = networkIdVirtualPortSetMap.get(networkId);
+ if (virtualPortSet != null) {
+ networkIdVirtualPortSetMap.compute(networkId, (id, existingVirtualPorts) -> {
+ if (existingVirtualPorts == null || existingVirtualPorts.isEmpty()) {
+ return ImmutableSet.of();
+ } else {
+ return ImmutableSet.<VirtualPort>builder()
+ .addAll(Sets.difference(existingVirtualPorts,
+ ImmutableSet.copyOf(virtualPortSet)))
+ .build();
+ }
+ });
+ }
}
@Override
public Set<VirtualNetwork> getNetworks(TenantId tenantId) {
- return null;
+ Set<NetworkId> networkIdSet = tenantIdNetworkIdSetMap.get(tenantId);
+ Set<VirtualNetwork> virtualNetworkSet = new HashSet<>();
+ if (networkIdSet != null) {
+ networkIdSet.forEach(networkId -> virtualNetworkSet.add(networkIdVirtualNetworkMap.get(networkId)));
+ }
+ return ImmutableSet.copyOf(virtualNetworkSet);
}
@Override
public Set<VirtualDevice> getDevices(NetworkId networkId) {
- return null;
+ checkState(networkExists(networkId), "The network has not been added.");
+ Set<DeviceId> deviceIdSet = networkIdDeviceIdSetMap.get(networkId);
+ Set<VirtualDevice> virtualDeviceSet = new HashSet<>();
+ if (deviceIdSet != null) {
+ deviceIdSet.forEach(deviceId -> virtualDeviceSet.add(deviceIdVirtualDeviceMap.get(deviceId)));
+ }
+ return ImmutableSet.copyOf(virtualDeviceSet);
}
@Override
public Set<VirtualLink> getLinks(NetworkId networkId) {
- return null;
+ checkState(networkExists(networkId), "The network has not been added.");
+ Set<VirtualLink> virtualLinkSet = new HashSet<>();
+ virtualLinkSet.addAll(networkIdVirtualLinkSetMap.get(networkId));
+ return ImmutableSet.copyOf(virtualLinkSet);
}
@Override
public Set<VirtualPort> getPorts(NetworkId networkId, DeviceId deviceId) {
- return null;
+ checkState(networkExists(networkId), "The network has not been added.");
+ Set<VirtualPort> virtualPortSet = new HashSet<>();
+ virtualPortSet.addAll(networkIdVirtualPortSetMap.get(networkId));
+ return ImmutableSet.copyOf(virtualPortSet);
+ }
+
+ /**
+ * Listener class to map listener set events to the virtual network events.
+ */
+ private class InternalSetListener implements SetEventListener<TenantId> {
+ @Override
+ public void event(SetEvent<TenantId> event) {
+ VirtualNetworkEvent.Type type = null;
+ switch (event.type()) {
+ case ADD:
+ type = VirtualNetworkEvent.Type.TENANT_REGISTERED;
+ break;
+ case REMOVE:
+ type = VirtualNetworkEvent.Type.TENANT_UNREGISTERED;
+ break;
+ default:
+ log.error("Unsupported event type: " + event.type());
+ }
+ notifyDelegate(new VirtualNetworkEvent(type, null));
+ }
+ }
+
+ /**
+ * Listener class to map listener map events to the virtual network events.
+ */
+ private class InternalMapListener implements MapEventListener<NetworkId, VirtualNetwork> {
+ @Override
+ public void event(MapEvent<NetworkId, VirtualNetwork> event) {
+ NetworkId networkId = checkNotNull(event.key());
+ VirtualNetworkEvent.Type type = null;
+ switch (event.type()) {
+ case INSERT:
+ type = VirtualNetworkEvent.Type.NETWORK_ADDED;
+ break;
+ case UPDATE:
+ if ((event.oldValue().value() != null) && (event.newValue().value() == null)) {
+ type = VirtualNetworkEvent.Type.NETWORK_REMOVED;
+ } else {
+ type = VirtualNetworkEvent.Type.NETWORK_UPDATED;
+ }
+ break;
+ case REMOVE:
+ type = VirtualNetworkEvent.Type.NETWORK_REMOVED;
+ break;
+ default:
+ log.error("Unsupported event type: " + event.type());
+ }
+ notifyDelegate(new VirtualNetworkEvent(type, networkId));
+ }
}
}