Brian Stanke
Committed by Gerrit Code Review

ONOS-4075 - Distributed virtual network store implementation,

and virtual network manager Junit tests.

Change-Id: Ic1f82822c894e3c394aa95df1e76ae59fe218120
...@@ -64,7 +64,7 @@ public class DistributedSetTest { ...@@ -64,7 +64,7 @@ public class DistributedSetTest {
64 public void basicTests() { 64 public void basicTests() {
65 set1.add("item1"); 65 set1.add("item1");
66 assertEquals("The set name should match.", SETNAME, set1.name()); 66 assertEquals("The set name should match.", SETNAME, set1.name());
67 - assertEquals("The set name should match.", DistributedPrimitive.Type.SET, set1.primitiveType()); 67 + assertEquals("The set primitive type should match.", DistributedPrimitive.Type.SET, set1.primitiveType());
68 68
69 set1.add("item2"); 69 set1.add("item2");
70 set1.add("item3"); 70 set1.add("item3");
......
...@@ -27,7 +27,7 @@ import static com.google.common.base.MoreObjects.*; ...@@ -27,7 +27,7 @@ import static com.google.common.base.MoreObjects.*;
27 /** 27 /**
28 * Default representation of a virtual device. 28 * Default representation of a virtual device.
29 */ 29 */
30 -public class DefaultVirtualDevice extends DefaultDevice implements VirtualDevice { 30 +public final class DefaultVirtualDevice extends DefaultDevice implements VirtualDevice {
31 31
32 private static final String VIRTUAL = "virtual"; 32 private static final String VIRTUAL = "virtual";
33 private static final ProviderId PID = new ProviderId(VIRTUAL, VIRTUAL); 33 private static final ProviderId PID = new ProviderId(VIRTUAL, VIRTUAL);
...@@ -53,7 +53,7 @@ public class DefaultVirtualDevice extends DefaultDevice implements VirtualDevice ...@@ -53,7 +53,7 @@ public class DefaultVirtualDevice extends DefaultDevice implements VirtualDevice
53 53
54 @Override 54 @Override
55 public int hashCode() { 55 public int hashCode() {
56 - return 31 * super.hashCode() + networkId.hashCode(); 56 + return Objects.hash(networkId);
57 } 57 }
58 58
59 @Override 59 @Override
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.incubator.net.virtual;
18 +
19 +import org.onosproject.incubator.net.tunnel.TunnelId;
20 +import org.onosproject.net.ConnectPoint;
21 +import org.onosproject.net.DefaultAnnotations;
22 +import org.onosproject.net.DefaultLink;
23 +import org.onosproject.net.provider.ProviderId;
24 +
25 +import java.util.Objects;
26 +
27 +import static com.google.common.base.MoreObjects.toStringHelper;
28 +
29 +/**
30 + * Default representation of a virtual link.
31 + */
32 +public final class DefaultVirtualLink extends DefaultLink implements VirtualLink {
33 +
34 + private static final String VIRTUAL = "virtual";
35 + private static final ProviderId PID = new ProviderId(VIRTUAL, VIRTUAL);
36 +
37 + private final NetworkId networkId;
38 + private final TunnelId tunnelId;
39 +
40 + /**
41 + * Constructor for a default virtual link.
42 + *
43 + * @param networkId network identifier
44 + * @param src source connection point
45 + * @param dst destination connection point
46 + * @param tunnelId tunnel identifier
47 + */
48 + public DefaultVirtualLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) {
49 + super(PID, src, dst, Type.VIRTUAL, DefaultAnnotations.builder().build());
50 + this.networkId = networkId;
51 + this.tunnelId = tunnelId;
52 + }
53 +
54 + @Override
55 + public NetworkId networkId() {
56 + return networkId;
57 + }
58 +
59 + /**
60 + * Returns the tunnel identifier.
61 + *
62 + * @return tunnel identifier.
63 + */
64 + public TunnelId tunnelId() {
65 + return tunnelId;
66 + }
67 +
68 + @Override
69 + public int hashCode() {
70 + return Objects.hash(networkId, tunnelId);
71 + }
72 +
73 + @Override
74 + public boolean equals(Object obj) {
75 + if (this == obj) {
76 + return true;
77 + }
78 + if (obj instanceof DefaultVirtualLink) {
79 + DefaultVirtualLink that = (DefaultVirtualLink) obj;
80 + return super.equals(that) &&
81 + Objects.equals(this.networkId, that.networkId) &&
82 + Objects.equals(this.tunnelId, that.tunnelId);
83 + }
84 + return false;
85 + }
86 +
87 + @Override
88 + public String toString() {
89 + return toStringHelper(this).add("networkId", networkId).add("tunnelId", tunnelId).toString();
90 + }
91 +}
...@@ -22,7 +22,7 @@ import static com.google.common.base.MoreObjects.toStringHelper; ...@@ -22,7 +22,7 @@ import static com.google.common.base.MoreObjects.toStringHelper;
22 /** 22 /**
23 * Default implementation of the virtual network descriptor. 23 * Default implementation of the virtual network descriptor.
24 */ 24 */
25 -public class DefaultVirtualNetwork implements VirtualNetwork { 25 +public final class DefaultVirtualNetwork implements VirtualNetwork {
26 26
27 private final NetworkId id; 27 private final NetworkId id;
28 private final TenantId tenantId; 28 private final TenantId tenantId;
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.incubator.net.virtual;
18 +
19 +import org.onosproject.net.DefaultAnnotations;
20 +import org.onosproject.net.DefaultPort;
21 +import org.onosproject.net.Device;
22 +import org.onosproject.net.Element;
23 +import org.onosproject.net.Port;
24 +import org.onosproject.net.PortNumber;
25 +
26 +import java.util.Objects;
27 +
28 +import static com.google.common.base.MoreObjects.toStringHelper;
29 +
30 +/**
31 + * Default representation of a virtual port.
32 + */
33 +public final class DefaultVirtualPort extends DefaultPort implements VirtualPort {
34 +
35 +
36 + private final NetworkId networkId;
37 + private final Port realizedBy;
38 +
39 + public DefaultVirtualPort(NetworkId networkId, Device device, PortNumber portNumber, Port realizedBy) {
40 + super((Element) device, portNumber, false, DefaultAnnotations.builder().build());
41 + this.networkId = networkId;
42 + this.realizedBy = realizedBy;
43 + }
44 +
45 + public NetworkId networkId() {
46 + return networkId;
47 + }
48 +
49 + @Override
50 + public Port realizedBy() {
51 + return realizedBy;
52 + }
53 +
54 + @Override
55 + public int hashCode() {
56 + return Objects.hash(networkId, realizedBy);
57 + }
58 +
59 + @Override
60 + public boolean equals(Object obj) {
61 + if (this == obj) {
62 + return true;
63 + }
64 + if (obj instanceof DefaultVirtualPort) {
65 + DefaultVirtualPort that = (DefaultVirtualPort) obj;
66 + return super.equals(that) &&
67 + Objects.equals(this.networkId, that.networkId) &&
68 + Objects.equals(this.realizedBy, that.realizedBy);
69 + }
70 + return false;
71 + }
72 +
73 + @Override
74 + public String toString() {
75 + return toStringHelper(this).add("networkId", networkId).add("realizedBy", realizedBy).toString();
76 + }
77 +
78 +}
...@@ -27,6 +27,11 @@ import java.util.Set; ...@@ -27,6 +27,11 @@ import java.util.Set;
27 public interface VirtualNetworkService { 27 public interface VirtualNetworkService {
28 28
29 /** 29 /**
30 + * The topic used for obtaining globally unique ids.
31 + */
32 + String VIRTUAL_NETWORK_TOPIC = "virtual-network-ids";
33 +
34 + /**
30 * Returns a collection of all virtual networks created on behalf of the 35 * Returns a collection of all virtual networks created on behalf of the
31 * specified tenant. 36 * specified tenant.
32 * 37 *
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.incubator.net.virtual;
18 +
19 +import com.google.common.testing.EqualsTester;
20 +import org.junit.Test;
21 +import org.onosproject.net.DeviceId;
22 +
23 +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
24 +
25 +/**
26 + * Test of the default virtual device model entity.
27 + */
28 +public class DefaultVirtualDeviceTest {
29 + final String deviceIdValue1 = "DEVICE_ID1";
30 + final String deviceIdValue2 = "DEVICE_ID2";
31 +
32 + /**
33 + * Checks that the DefaultVirtualDevice class is immutable.
34 + */
35 + @Test
36 + public void testImmutability() {
37 + assertThatClassIsImmutable(DefaultVirtualDevice.class);
38 + }
39 +
40 + @Test
41 + public void testEquality() {
42 + DefaultVirtualDevice device1 =
43 + new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue1));
44 + DefaultVirtualDevice device2 =
45 + new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue1));
46 + DefaultVirtualDevice device3 =
47 + new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue2));
48 + DefaultVirtualDevice device4 =
49 + new DefaultVirtualDevice(NetworkId.networkId(1), DeviceId.deviceId(deviceIdValue1));
50 +
51 + new EqualsTester().addEqualityGroup(device1, device2).addEqualityGroup(device3)
52 + .addEqualityGroup(device4).testEquals();
53 + }
54 +}
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.incubator.net.virtual;
18 +
19 +import com.google.common.testing.EqualsTester;
20 +import org.junit.Test;
21 +import org.onosproject.incubator.net.tunnel.TunnelId;
22 +import org.onosproject.net.ConnectPoint;
23 +import org.onosproject.net.DeviceId;
24 +import org.onosproject.net.PortNumber;
25 +
26 +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
27 +
28 +/**
29 + * Test of the default virtual link model entity.
30 + */
31 +public class DefaultVirtualLinkTest {
32 + final String deviceIdValue1 = "DEVICE_ID1";
33 + final String deviceIdValue2 = "DEVICE_ID2";
34 +
35 + /**
36 + * Checks that the DefaultVirtualLink class is immutable.
37 + */
38 + @Test
39 + public void testImmutability() {
40 + assertThatClassIsImmutable(DefaultVirtualLink.class);
41 + }
42 +
43 + @Test
44 + public void testEquality() {
45 + DefaultVirtualDevice device1 =
46 + new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue1));
47 + DefaultVirtualDevice device2 =
48 + new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue2));
49 + ConnectPoint src = new ConnectPoint(device1.id(), PortNumber.portNumber(1));
50 + ConnectPoint dst = new ConnectPoint(device2.id(), PortNumber.portNumber(2));
51 +
52 + DefaultVirtualLink link1 = new DefaultVirtualLink(NetworkId.networkId(0), src, dst, TunnelId.valueOf(0));
53 + DefaultVirtualLink link2 = new DefaultVirtualLink(NetworkId.networkId(0), src, dst, TunnelId.valueOf(0));
54 + DefaultVirtualLink link3 = new DefaultVirtualLink(NetworkId.networkId(0), src, dst, TunnelId.valueOf(1));
55 + DefaultVirtualLink link4 = new DefaultVirtualLink(NetworkId.networkId(1), src, dst, TunnelId.valueOf(0));
56 +
57 + new EqualsTester().addEqualityGroup(link1, link2).addEqualityGroup(link3)
58 + .addEqualityGroup(link4).testEquals();
59 + }
60 +}
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.incubator.net.virtual;
18 +
19 +import com.google.common.testing.EqualsTester;
20 +import org.junit.Test;
21 +
22 +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
23 +
24 +/**
25 + * Test of the default virtual network model entity.
26 + */
27 +public class DefaultVirtualNetworkTest {
28 + final String tenantIdValue1 = "TENANT_ID1";
29 + final String tenantIdValue2 = "TENANT_ID2";
30 +
31 + /**
32 + * Checks that the DefaultVirtualNetwork class is immutable.
33 + */
34 + @Test
35 + public void testImmutability() {
36 + assertThatClassIsImmutable(DefaultVirtualNetwork.class);
37 + }
38 +
39 + @Test
40 + public void testEquality() {
41 + DefaultVirtualNetwork network1 =
42 + new DefaultVirtualNetwork(NetworkId.networkId(0), TenantId.tenantId(tenantIdValue1));
43 + DefaultVirtualNetwork network2 =
44 + new DefaultVirtualNetwork(NetworkId.networkId(0), TenantId.tenantId(tenantIdValue1));
45 + DefaultVirtualNetwork network3 =
46 + new DefaultVirtualNetwork(NetworkId.networkId(0), TenantId.tenantId(tenantIdValue2));
47 + DefaultVirtualNetwork network4 =
48 + new DefaultVirtualNetwork(NetworkId.networkId(1), TenantId.tenantId(tenantIdValue2));
49 +
50 + new EqualsTester().addEqualityGroup(network1, network2).addEqualityGroup(network3)
51 + .addEqualityGroup(network4).testEquals();
52 + }
53 +}
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.incubator.net.virtual;
18 +
19 +import com.google.common.testing.EqualsTester;
20 +import org.junit.Test;
21 +import org.onosproject.net.DefaultPort;
22 +import org.onosproject.net.DeviceId;
23 +import org.onosproject.net.Port;
24 +import org.onosproject.net.PortNumber;
25 +
26 +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
27 +
28 +/**
29 + * Test of the default virtual port model entity.
30 + */
31 +public class DefaultVirtualPortTest {
32 + final String deviceIdValue1 = "DEVICE_ID1";
33 + final String deviceIdValue2 = "DEVICE_ID2";
34 +
35 + /**
36 + * Checks that the DefaultVirtualPort class is immutable.
37 + */
38 + @Test
39 + public void testImmutability() {
40 + assertThatClassIsImmutable(DefaultVirtualPort.class);
41 + }
42 +
43 + @Test
44 + public void testEquality() {
45 + DefaultVirtualDevice device1 =
46 + new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue1));
47 + DefaultVirtualDevice device2 =
48 + new DefaultVirtualDevice(NetworkId.networkId(0), DeviceId.deviceId(deviceIdValue2));
49 +
50 + Port portA = new DefaultPort(device1, PortNumber.portNumber(1), true);
51 + Port portB = new DefaultPort(device1, PortNumber.portNumber(2), true);
52 + Port portC = new DefaultPort(device2, PortNumber.portNumber(2), true);
53 +
54 + DefaultVirtualPort port1 =
55 + new DefaultVirtualPort(NetworkId.networkId(0), device1, PortNumber.portNumber(1), portA);
56 + DefaultVirtualPort port2 =
57 + new DefaultVirtualPort(NetworkId.networkId(0), device1, PortNumber.portNumber(1), portA);
58 + DefaultVirtualPort port3 =
59 + new DefaultVirtualPort(NetworkId.networkId(0), device1, PortNumber.portNumber(2), portB);
60 + DefaultVirtualPort port4 =
61 + new DefaultVirtualPort(NetworkId.networkId(1), device2, PortNumber.portNumber(2), portC);
62 +
63 +
64 + new EqualsTester().addEqualityGroup(port1, port2).addEqualityGroup(port3)
65 + .addEqualityGroup(port4).testEquals();
66 + }
67 +}
1 /* 1 /*
2 - * Copyright 2015 Open Networking Laboratory 2 + * Copyright 2016 Open Networking Laboratory
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
...@@ -57,7 +57,7 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -57,7 +57,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
57 @Service 57 @Service
58 public class VirtualNetworkManager 58 public class VirtualNetworkManager
59 extends AbstractListenerProviderRegistry<VirtualNetworkEvent, VirtualNetworkListener, 59 extends AbstractListenerProviderRegistry<VirtualNetworkEvent, VirtualNetworkListener,
60 - VirtualNetworkProvider, VirtualNetworkProviderService> 60 + VirtualNetworkProvider, VirtualNetworkProviderService>
61 implements VirtualNetworkService, VirtualNetworkAdminService, VirtualNetworkProviderRegistry { 61 implements VirtualNetworkService, VirtualNetworkAdminService, VirtualNetworkProviderRegistry {
62 62
63 private final Logger log = LoggerFactory.getLogger(getClass()); 63 private final Logger log = LoggerFactory.getLogger(getClass());
...@@ -70,19 +70,23 @@ public class VirtualNetworkManager ...@@ -70,19 +70,23 @@ public class VirtualNetworkManager
70 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 70 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
71 protected VirtualNetworkStore store; 71 protected VirtualNetworkStore store;
72 72
73 - private VirtualNetworkStoreDelegate delegate = new InternalStoreDelegate(); 73 + private VirtualNetworkStoreDelegate delegate = this::post;
74 74
75 // TODO: figure out how to coordinate "implementation" of a virtual network in a cluster 75 // TODO: figure out how to coordinate "implementation" of a virtual network in a cluster
76 76
77 @Activate 77 @Activate
78 protected void activate() { 78 protected void activate() {
79 store.setDelegate(delegate); 79 store.setDelegate(delegate);
80 + eventDispatcher.addSink(VirtualNetworkEvent.class, listenerRegistry);
81 +
80 log.info("Started"); 82 log.info("Started");
81 } 83 }
82 84
83 @Deactivate 85 @Deactivate
84 protected void deactivate() { 86 protected void deactivate() {
85 store.unsetDelegate(delegate); 87 store.unsetDelegate(delegate);
88 + eventDispatcher.removeSink(VirtualNetworkEvent.class);
89 +
86 log.info("Stopped"); 90 log.info("Stopped");
87 } 91 }
88 92
...@@ -211,13 +215,4 @@ public class VirtualNetworkManager ...@@ -211,13 +215,4 @@ public class VirtualNetworkManager
211 } 215 }
212 } 216 }
213 217
214 - // Auxiliary store delegate to receive notification about changes in
215 - // the virtual network configuration store state - by the store itself.
216 - private class InternalStoreDelegate implements VirtualNetworkStoreDelegate {
217 - @Override
218 - public void notify(VirtualNetworkEvent event) {
219 - post(event);
220 - }
221 - }
222 -
223 } 218 }
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.incubator.net.virtual.impl;
18 +
19 +import com.google.common.collect.Lists;
20 +import org.junit.After;
21 +import org.junit.Before;
22 +import org.junit.Test;
23 +import org.onlab.junit.TestTools;
24 +import org.onlab.junit.TestUtils;
25 +import org.onosproject.common.event.impl.TestEventDispatcher;
26 +import org.onosproject.core.CoreService;
27 +import org.onosproject.core.CoreServiceAdapter;
28 +import org.onosproject.core.IdGenerator;
29 +import org.onosproject.event.Event;
30 +import org.onosproject.incubator.net.tunnel.TunnelId;
31 +import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
32 +import org.onosproject.incubator.net.virtual.NetworkId;
33 +import org.onosproject.incubator.net.virtual.TenantId;
34 +import org.onosproject.incubator.net.virtual.VirtualDevice;
35 +import org.onosproject.incubator.net.virtual.VirtualLink;
36 +import org.onosproject.incubator.net.virtual.VirtualNetwork;
37 +import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
38 +import org.onosproject.incubator.net.virtual.VirtualNetworkListener;
39 +import org.onosproject.incubator.net.virtual.VirtualNetworkService;
40 +import org.onosproject.incubator.net.virtual.VirtualPort;
41 +import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
42 +import org.onosproject.net.ConnectPoint;
43 +import org.onosproject.net.DefaultPort;
44 +import org.onosproject.net.DeviceId;
45 +import org.onosproject.net.NetTestTools;
46 +import org.onosproject.net.Port;
47 +import org.onosproject.net.PortNumber;
48 +import org.onosproject.store.service.TestStorageService;
49 +
50 +import java.util.Collection;
51 +import java.util.List;
52 +import java.util.Set;
53 +import java.util.concurrent.atomic.AtomicLong;
54 +
55 +import static org.junit.Assert.*;
56 +
57 +/**
58 + * Junit tests for VirtualNetworkManager.
59 + */
60 +public class VirtualNetworkManagerTest {
61 + final String tenantIdValue1 = "TENANT_ID1";
62 + final String tenantIdValue2 = "TENANT_ID2";
63 + final String deviceIdValue1 = "DEVICE_ID1";
64 + final String deviceIdValue2 = "DEVICE_ID2";
65 +
66 + private VirtualNetworkManager manager;
67 + private VirtualNetworkService virtualNetworkManagerService;
68 + private DistributedVirtualNetworkStore virtualNetworkManagerStore;
69 + private CoreService coreService;
70 + protected TestListener listener = new TestListener();
71 +
72 + @Before
73 + public void setUp() throws Exception {
74 + virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
75 +
76 + coreService = new TestCoreService();
77 + virtualNetworkManagerStore.setCoreService(coreService);
78 + TestUtils.setField(coreService, "coreService", new TestCoreService());
79 + TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
80 + virtualNetworkManagerStore.activate();
81 +
82 + manager = new VirtualNetworkManager();
83 + manager.store = virtualNetworkManagerStore;
84 + manager.addListener(listener);
85 + NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
86 + manager.activate();
87 + virtualNetworkManagerService = manager;
88 +
89 + }
90 +
91 + @After
92 + public void tearDown() {
93 + virtualNetworkManagerStore.deactivate();
94 + manager.removeListener(listener);
95 + manager.deactivate();
96 + NetTestTools.injectEventDispatcher(manager, null);
97 + }
98 +
99 + /**
100 + * Tests registering a null tenant id.
101 + */
102 + @Test(expected = NullPointerException.class)
103 + public void testRegisterNullTenantId() {
104 + manager.registerTenantId(null);
105 + }
106 +
107 + /**
108 + * Tests registering/unregistering a tenant id.
109 + */
110 + @Test
111 + public void testRegisterUnregisterTenantId() {
112 + manager.unregisterTenantId(TenantId.tenantId(tenantIdValue1));
113 + manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
114 + manager.registerTenantId(TenantId.tenantId(tenantIdValue2));
115 + Collection<TenantId> tenantIdCollection = manager.getTenantIds();
116 + assertEquals("The tenantId set size did not match.", 2, tenantIdCollection.size());
117 +
118 + manager.unregisterTenantId(TenantId.tenantId(tenantIdValue1));
119 + manager.unregisterTenantId(TenantId.tenantId(tenantIdValue2));
120 + tenantIdCollection = manager.getTenantIds();
121 + assertTrue("The tenantId set should be empty.", tenantIdCollection.isEmpty());
122 +
123 + // Validate that the events were all received in the correct order.
124 + validateEvents(VirtualNetworkEvent.Type.TENANT_UNREGISTERED, VirtualNetworkEvent.Type.TENANT_REGISTERED,
125 + VirtualNetworkEvent.Type.TENANT_REGISTERED, VirtualNetworkEvent.Type.TENANT_UNREGISTERED,
126 + VirtualNetworkEvent.Type.TENANT_UNREGISTERED);
127 + }
128 +
129 + /**
130 + * Tests adding a null virtual network.
131 + */
132 + @Test(expected = NullPointerException.class)
133 + public void testCreateNullVirtualNetwork() {
134 + manager.createVirtualNetwork(null);
135 + }
136 +
137 + /**
138 + * Tests add and remove of virtual networks.
139 + */
140 + @Test
141 + public void testAddRemoveVirtualNetwork() {
142 + manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
143 + manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
144 + manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
145 + Set<VirtualNetwork> virtualNetworks = manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1));
146 + assertNotNull("The virtual network set should not be null", virtualNetworks);
147 + assertEquals("The virtual network set size did not match.", 2, virtualNetworks.size());
148 +
149 + for (VirtualNetwork virtualNetwork : virtualNetworks) {
150 + manager.removeVirtualNetwork(virtualNetwork.id());
151 + // attempt to remove the same virtual network again.
152 + manager.removeVirtualNetwork(virtualNetwork.id());
153 + }
154 + virtualNetworks = manager.getVirtualNetworks(TenantId.tenantId(tenantIdValue1));
155 + assertTrue("The virtual network set should be empty.", virtualNetworks.isEmpty());
156 +
157 + // Validate that the events were all received in the correct order.
158 + validateEvents(VirtualNetworkEvent.Type.TENANT_REGISTERED, VirtualNetworkEvent.Type.NETWORK_ADDED,
159 + VirtualNetworkEvent.Type.NETWORK_ADDED, VirtualNetworkEvent.Type.NETWORK_REMOVED,
160 + VirtualNetworkEvent.Type.NETWORK_REMOVED);
161 + }
162 +
163 + /**
164 + * Tests adding a null virtual device.
165 + */
166 + @Test(expected = NullPointerException.class)
167 + public void testCreateNullVirtualDevice() {
168 + manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
169 + VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
170 +
171 + manager.createVirtualDevice(virtualNetwork.id(), null);
172 + }
173 +
174 + /**
175 + * Tests adding a virtual device where no virtual network exists.
176 + */
177 + @Test(expected = IllegalStateException.class)
178 + public void testCreateVirtualDeviceWithNoNetwork() {
179 + manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
180 + VirtualNetwork virtualNetwork = new DefaultVirtualNetwork(NetworkId.NONE, TenantId.tenantId(tenantIdValue1));
181 +
182 + manager.createVirtualDevice(virtualNetwork.id(), DeviceId.deviceId(deviceIdValue1));
183 + }
184 +
185 + /**
186 + * Tests add and remove of virtual devices.
187 + */
188 + @Test
189 + public void testAddRemoveVirtualDevice() {
190 + manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
191 + VirtualNetwork virtualNetwork1 = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
192 + VirtualNetwork virtualNetwork2 = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
193 + manager.createVirtualDevice(virtualNetwork1.id(), DeviceId.deviceId(deviceIdValue1));
194 + manager.createVirtualDevice(virtualNetwork2.id(), DeviceId.deviceId(deviceIdValue2));
195 +
196 + Set<VirtualDevice> virtualDevices1 = manager.getVirtualDevices(virtualNetwork1.id());
197 + assertNotNull("The virtual device set should not be null", virtualDevices1);
198 + assertEquals("The virtual device set size did not match.", 1, virtualDevices1.size());
199 +
200 + Set<VirtualDevice> virtualDevices2 = manager.getVirtualDevices(virtualNetwork2.id());
201 + assertNotNull("The virtual device set should not be null", virtualDevices2);
202 + assertEquals("The virtual device set size did not match.", 1, virtualDevices2.size());
203 +
204 + for (VirtualDevice virtualDevice : virtualDevices1) {
205 + manager.removeVirtualDevice(virtualNetwork1.id(), virtualDevice.id());
206 + // attempt to remove the same virtual device again.
207 + manager.removeVirtualDevice(virtualNetwork1.id(), virtualDevice.id());
208 + }
209 + virtualDevices1 = manager.getVirtualDevices(virtualNetwork1.id());
210 + assertTrue("The virtual device set should be empty.", virtualDevices1.isEmpty());
211 +
212 + // Validate that the events were all received in the correct order.
213 + validateEvents(VirtualNetworkEvent.Type.TENANT_REGISTERED, VirtualNetworkEvent.Type.NETWORK_ADDED,
214 + VirtualNetworkEvent.Type.NETWORK_ADDED);
215 + }
216 +
217 + /**
218 + * Tests add and remove of virtual links.
219 + */
220 + @Test
221 + public void testAddRemoveVirtualLink() {
222 + manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
223 + VirtualNetwork virtualNetwork1 = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
224 + VirtualDevice srcVirtualDevice =
225 + manager.createVirtualDevice(virtualNetwork1.id(), DeviceId.deviceId(deviceIdValue1));
226 + VirtualDevice dstVirtualDevice =
227 + manager.createVirtualDevice(virtualNetwork1.id(), DeviceId.deviceId(deviceIdValue2));
228 + ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1));
229 + ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2));
230 + manager.createVirtualLink(virtualNetwork1.id(), src, dst, TunnelId.valueOf(0));
231 + manager.createVirtualLink(virtualNetwork1.id(), dst, src, TunnelId.valueOf(1));
232 +
233 + Set<VirtualLink> virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
234 + assertNotNull("The virtual link set should not be null", virtualLinks);
235 + assertEquals("The virtual link set size did not match.", 2, virtualLinks.size());
236 +
237 + for (VirtualLink virtualLink : virtualLinks) {
238 + manager.removeVirtualLink(virtualLink.networkId(), virtualLink.src(), virtualLink.dst());
239 + // attempt to remove the same virtual link again.
240 + manager.removeVirtualLink(virtualLink.networkId(), virtualLink.src(), virtualLink.dst());
241 + }
242 + virtualLinks = manager.getVirtualLinks(virtualNetwork1.id());
243 + assertTrue("The virtual link set should be empty.", virtualLinks.isEmpty());
244 + }
245 +
246 + /**
247 + * Tests add and remove of virtual ports.
248 + */
249 + @Test
250 + public void testAddRemoveVirtualPort() {
251 + manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
252 + VirtualNetwork virtualNetwork1 = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
253 + VirtualDevice srcVirtualDevice =
254 + manager.createVirtualDevice(virtualNetwork1.id(), DeviceId.deviceId(deviceIdValue1));
255 + VirtualDevice dstVirtualDevice =
256 + manager.createVirtualDevice(virtualNetwork1.id(), DeviceId.deviceId(deviceIdValue2));
257 + Port port = new DefaultPort(srcVirtualDevice, PortNumber.portNumber(1), true);
258 +
259 + manager.createVirtualPort(virtualNetwork1.id(), srcVirtualDevice.id(), PortNumber.portNumber(1), port);
260 + manager.createVirtualPort(virtualNetwork1.id(), dstVirtualDevice.id(), PortNumber.portNumber(1), port);
261 +
262 + Set<VirtualPort> virtualPorts = manager.getVirtualPorts(virtualNetwork1.id(), srcVirtualDevice.id());
263 + assertNotNull("The virtual port set should not be null", virtualPorts);
264 + assertEquals("The virtual port set size did not match.", 2, virtualPorts.size());
265 +
266 + for (VirtualPort virtualPort : virtualPorts) {
267 + manager.removeVirtualPort(virtualNetwork1.id(),
268 + (DeviceId) virtualPort.element().id(), virtualPort.number());
269 + // attempt to remove the same virtual port again.
270 + manager.removeVirtualPort(virtualNetwork1.id(),
271 + (DeviceId) virtualPort.element().id(), virtualPort.number());
272 + }
273 + virtualPorts = manager.getVirtualPorts(virtualNetwork1.id(), srcVirtualDevice.id());
274 + assertTrue("The virtual port set should be empty.", virtualPorts.isEmpty());
275 + }
276 +
277 + /**
278 + * Method to validate that the actual versus expected virtual network events were
279 + * received correctly.
280 + *
281 + * @param types expected virtual network events.
282 + */
283 + private void validateEvents(Enum... types) {
284 + TestTools.assertAfter(100, () -> {
285 + int i = 0;
286 + assertEquals("wrong events received", types.length, listener.events.size());
287 + for (Event event : listener.events) {
288 + assertEquals("incorrect event type", types[i], event.type());
289 + i++;
290 + }
291 + listener.events.clear();
292 + });
293 + }
294 +
295 + /**
296 + * Test listener class to receive virtual network events.
297 + */
298 + private static class TestListener implements VirtualNetworkListener {
299 +
300 + protected List<VirtualNetworkEvent> events = Lists.newArrayList();
301 +
302 + @Override
303 + public void event(VirtualNetworkEvent event) {
304 + events.add(event);
305 + }
306 +
307 + }
308 +
309 + private class TestCoreService extends CoreServiceAdapter {
310 +
311 + @Override
312 + public IdGenerator getIdGenerator(String topic) {
313 + return new IdGenerator() {
314 + private AtomicLong counter = new AtomicLong(0);
315 +
316 + @Override
317 + public long getNewId() {
318 + return counter.getAndIncrement();
319 + }
320 + };
321 + }
322 + }
323 +}
1 /* 1 /*
2 - * Copyright 2015 Open Networking Laboratory 2 + * Copyright 2016 Open Networking Laboratory
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
...@@ -15,35 +15,59 @@ ...@@ -15,35 +15,59 @@
15 */ 15 */
16 package org.onosproject.incubator.store.virtual.impl; 16 package org.onosproject.incubator.store.virtual.impl;
17 17
18 +import com.google.common.collect.ImmutableSet;
19 +import com.google.common.collect.Sets;
18 import org.apache.felix.scr.annotations.Activate; 20 import org.apache.felix.scr.annotations.Activate;
19 import org.apache.felix.scr.annotations.Component; 21 import org.apache.felix.scr.annotations.Component;
20 import org.apache.felix.scr.annotations.Deactivate; 22 import org.apache.felix.scr.annotations.Deactivate;
23 +import org.apache.felix.scr.annotations.Reference;
24 +import org.apache.felix.scr.annotations.ReferenceCardinality;
21 import org.apache.felix.scr.annotations.Service; 25 import org.apache.felix.scr.annotations.Service;
26 +import org.onlab.util.KryoNamespace;
27 +import org.onosproject.core.CoreService;
28 +import org.onosproject.core.IdGenerator;
22 import org.onosproject.incubator.net.tunnel.TunnelId; 29 import org.onosproject.incubator.net.tunnel.TunnelId;
23 import org.onosproject.incubator.net.virtual.DefaultVirtualDevice; 30 import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
31 +import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
24 import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork; 32 import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
33 +import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
25 import org.onosproject.incubator.net.virtual.NetworkId; 34 import org.onosproject.incubator.net.virtual.NetworkId;
26 import org.onosproject.incubator.net.virtual.TenantId; 35 import org.onosproject.incubator.net.virtual.TenantId;
27 import org.onosproject.incubator.net.virtual.VirtualDevice; 36 import org.onosproject.incubator.net.virtual.VirtualDevice;
28 import org.onosproject.incubator.net.virtual.VirtualLink; 37 import org.onosproject.incubator.net.virtual.VirtualLink;
29 import org.onosproject.incubator.net.virtual.VirtualNetwork; 38 import org.onosproject.incubator.net.virtual.VirtualNetwork;
30 import org.onosproject.incubator.net.virtual.VirtualNetworkEvent; 39 import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
40 +import org.onosproject.incubator.net.virtual.VirtualNetworkService;
31 import org.onosproject.incubator.net.virtual.VirtualNetworkStore; 41 import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
32 import org.onosproject.incubator.net.virtual.VirtualNetworkStoreDelegate; 42 import org.onosproject.incubator.net.virtual.VirtualNetworkStoreDelegate;
33 import org.onosproject.incubator.net.virtual.VirtualPort; 43 import org.onosproject.incubator.net.virtual.VirtualPort;
34 import org.onosproject.net.ConnectPoint; 44 import org.onosproject.net.ConnectPoint;
45 +import org.onosproject.net.Device;
35 import org.onosproject.net.DeviceId; 46 import org.onosproject.net.DeviceId;
36 import org.onosproject.net.Port; 47 import org.onosproject.net.Port;
37 import org.onosproject.net.PortNumber; 48 import org.onosproject.net.PortNumber;
38 import org.onosproject.store.AbstractStore; 49 import org.onosproject.store.AbstractStore;
50 +import org.onosproject.store.serializers.KryoNamespaces;
51 +import org.onosproject.store.service.ConsistentMap;
52 +import org.onosproject.store.service.DistributedSet;
53 +import org.onosproject.store.service.MapEvent;
54 +import org.onosproject.store.service.MapEventListener;
55 +import org.onosproject.store.service.Serializer;
56 +import org.onosproject.store.service.SetEvent;
57 +import org.onosproject.store.service.SetEventListener;
58 +import org.onosproject.store.service.StorageService;
39 import org.slf4j.Logger; 59 import org.slf4j.Logger;
40 60
61 +import java.util.HashSet;
62 +import java.util.Map;
41 import java.util.Set; 63 import java.util.Set;
42 64
65 +import static com.google.common.base.Preconditions.checkNotNull;
66 +import static com.google.common.base.Preconditions.checkState;
43 import static org.slf4j.LoggerFactory.getLogger; 67 import static org.slf4j.LoggerFactory.getLogger;
44 68
45 /** 69 /**
46 - * Implementation of the network store. 70 + * Implementation of the virtual network store.
47 */ 71 */
48 @Component(immediate = true) 72 @Component(immediate = true)
49 @Service 73 @Service
...@@ -53,95 +77,404 @@ public class DistributedVirtualNetworkStore ...@@ -53,95 +77,404 @@ public class DistributedVirtualNetworkStore
53 77
54 private final Logger log = getLogger(getClass()); 78 private final Logger log = getLogger(getClass());
55 79
56 - // TODO: track tenants by ID 80 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57 - // TODO: track networks by ID and by tenants 81 + protected StorageService storageService;
58 - // TODO: track devices by network ID and device ID
59 - // TODO: track devices by network ID
60 - // TODO: setup block allocator for network IDs
61 82
62 - // TODO: notify delegate 83 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
84 + protected CoreService coreService;
63 85
86 + private IdGenerator idGenerator;
87 +
88 + // Track tenants by ID
89 + private DistributedSet<TenantId> tenantIdSet;
90 +
91 + // Listener for tenant events
92 + private final SetEventListener<TenantId> setListener = new InternalSetListener();
93 +
94 + // Track virtual networks by network Id
95 + private ConsistentMap<NetworkId, VirtualNetwork> networkIdVirtualNetworkConsistentMap;
96 + private Map<NetworkId, VirtualNetwork> networkIdVirtualNetworkMap;
97 +
98 + // Listener for virtual network events
99 + private final MapEventListener<NetworkId, VirtualNetwork> virtualMapListener = new InternalMapListener();
100 +
101 + // Track virtual network IDs by tenant Id
102 + private ConsistentMap<TenantId, Set<NetworkId>> tenantIdNetworkIdSetConsistentMap;
103 + private Map<TenantId, Set<NetworkId>> tenantIdNetworkIdSetMap;
104 +
105 + // Track virtual devices by device Id
106 + private ConsistentMap<DeviceId, VirtualDevice> deviceIdVirtualDeviceConsistentMap;
107 + private Map<DeviceId, VirtualDevice> deviceIdVirtualDeviceMap;
108 +
109 + // Track device IDs by network Id
110 + private ConsistentMap<NetworkId, Set<DeviceId>> networkIdDeviceIdSetConsistentMap;
111 + private Map<NetworkId, Set<DeviceId>> networkIdDeviceIdSetMap;
112 +
113 + // Track virtual links by network Id
114 + private ConsistentMap<NetworkId, Set<VirtualLink>> networkIdVirtualLinkSetConsistentMap;
115 + private Map<NetworkId, Set<VirtualLink>> networkIdVirtualLinkSetMap;
116 +
117 + // Track virtual ports by network Id
118 + private ConsistentMap<NetworkId, Set<VirtualPort>> networkIdVirtualPortSetConsistentMap;
119 + private Map<NetworkId, Set<VirtualPort>> networkIdVirtualPortSetMap;
120 +
121 + private static final Serializer SERIALIZER = Serializer
122 + .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
123 + .register(TenantId.class)
124 + .register(NetworkId.class).register(DeviceId.class)
125 + .register(VirtualNetwork.class)
126 + .register(VirtualDevice.class)
127 + .register(VirtualLink.class)
128 + .register(VirtualPort.class)
129 + .register(DeviceId.class)
130 + .register(Device.class)
131 + .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID).build());
132 +
133 + /**
134 + * Distributed network store service activate method.
135 + */
64 @Activate 136 @Activate
65 public void activate() { 137 public void activate() {
138 + idGenerator = coreService.getIdGenerator(VirtualNetworkService.VIRTUAL_NETWORK_TOPIC);
139 +
140 + tenantIdSet = storageService.<TenantId>setBuilder()
141 + .withSerializer(SERIALIZER)
142 + .withName("onos-tenantId")
143 + .withRelaxedReadConsistency()
144 + .build()
145 + .asDistributedSet();
146 + tenantIdSet.addListener(setListener);
147 +
148 + networkIdVirtualNetworkConsistentMap = storageService.<NetworkId, VirtualNetwork>consistentMapBuilder()
149 + .withSerializer(SERIALIZER)
150 + .withName("onos-networkId-virtualnetwork")
151 + .withRelaxedReadConsistency()
152 + .build();
153 + networkIdVirtualNetworkConsistentMap.addListener(virtualMapListener);
154 + networkIdVirtualNetworkMap = networkIdVirtualNetworkConsistentMap.asJavaMap();
155 +
156 + tenantIdNetworkIdSetConsistentMap = storageService.<TenantId, Set<NetworkId>>consistentMapBuilder()
157 + .withSerializer(SERIALIZER)
158 + .withName("onos-tenantId-networkIds")
159 + .withRelaxedReadConsistency()
160 + .build();
161 + tenantIdNetworkIdSetMap = tenantIdNetworkIdSetConsistentMap.asJavaMap();
162 +
163 + deviceIdVirtualDeviceConsistentMap = storageService.<DeviceId, VirtualDevice>consistentMapBuilder()
164 + .withSerializer(SERIALIZER)
165 + .withName("onos-deviceId-virtualdevice")
166 + .withRelaxedReadConsistency()
167 + .build();
168 + deviceIdVirtualDeviceMap = deviceIdVirtualDeviceConsistentMap.asJavaMap();
169 +
170 + networkIdDeviceIdSetConsistentMap = storageService.<NetworkId, Set<DeviceId>>consistentMapBuilder()
171 + .withSerializer(SERIALIZER)
172 + .withName("onos-networkId-deviceIds")
173 + .withRelaxedReadConsistency()
174 + .build();
175 + networkIdDeviceIdSetMap = networkIdDeviceIdSetConsistentMap.asJavaMap();
176 +
177 + networkIdVirtualLinkSetConsistentMap = storageService.<NetworkId, Set<VirtualLink>>consistentMapBuilder()
178 + .withSerializer(SERIALIZER)
179 + .withName("onos-networkId-virtuallinks")
180 + .withRelaxedReadConsistency()
181 + .build();
182 + networkIdVirtualLinkSetMap = networkIdVirtualLinkSetConsistentMap.asJavaMap();
183 +
184 + networkIdVirtualPortSetConsistentMap = storageService.<NetworkId, Set<VirtualPort>>consistentMapBuilder()
185 + .withSerializer(SERIALIZER)
186 + .withName("onos-networkId-virtualportss")
187 + .withRelaxedReadConsistency()
188 + .build();
189 + networkIdVirtualPortSetMap = networkIdVirtualPortSetConsistentMap.asJavaMap();
190 +
66 log.info("Started"); 191 log.info("Started");
67 } 192 }
68 193
194 + /**
195 + * Distributed network store service deactivate method.
196 + */
69 @Deactivate 197 @Deactivate
70 public void deactivate() { 198 public void deactivate() {
199 + tenantIdSet.removeListener(setListener);
200 + networkIdVirtualNetworkConsistentMap.removeListener(virtualMapListener);
71 log.info("Stopped"); 201 log.info("Stopped");
72 } 202 }
73 203
204 + /**
205 + * This method is used for Junit tests to set the CoreService instance, which
206 + * is required to set the IdGenerator instance.
207 + *
208 + * @param coreService core service instance
209 + */
210 + public void setCoreService(CoreService coreService) {
211 + this.coreService = coreService;
212 + }
213 +
74 @Override 214 @Override
75 public void addTenantId(TenantId tenantId) { 215 public void addTenantId(TenantId tenantId) {
216 + tenantIdSet.add(tenantId);
76 } 217 }
77 218
78 @Override 219 @Override
79 public void removeTenantId(TenantId tenantId) { 220 public void removeTenantId(TenantId tenantId) {
221 + tenantIdSet.remove(tenantId);
80 } 222 }
81 223
82 @Override 224 @Override
83 public Set<TenantId> getTenantIds() { 225 public Set<TenantId> getTenantIds() {
84 - return null; 226 + return ImmutableSet.copyOf(tenantIdSet);
85 } 227 }
86 228
87 @Override 229 @Override
88 public VirtualNetwork addNetwork(TenantId tenantId) { 230 public VirtualNetwork addNetwork(TenantId tenantId) {
89 - return new DefaultVirtualNetwork(genNetworkId(), tenantId); 231 +
232 + checkState(tenantIdSet.contains(tenantId), "The tenant has not been registered. " + tenantId.id());
233 + VirtualNetwork virtualNetwork = new DefaultVirtualNetwork(genNetworkId(), tenantId);
234 + //TODO update both maps in one transaction.
235 + networkIdVirtualNetworkMap.put(virtualNetwork.id(), virtualNetwork);
236 + Set<NetworkId> virtualNetworkSet = tenantIdNetworkIdSetMap.get(tenantId);
237 + if (virtualNetworkSet == null) {
238 + virtualNetworkSet = new HashSet<>();
239 + }
240 + virtualNetworkSet.add(virtualNetwork.id());
241 + tenantIdNetworkIdSetMap.put(tenantId, virtualNetworkSet);
242 + return virtualNetwork;
90 } 243 }
91 244
245 + /**
246 + * Returns a new network identifier from a virtual network block of identifiers.
247 + *
248 + * @return NetworkId network identifier
249 + */
92 private NetworkId genNetworkId() { 250 private NetworkId genNetworkId() {
93 - return NetworkId.networkId(0); // TODO: use a block allocator 251 + return NetworkId.networkId(idGenerator.getNewId());
94 } 252 }
95 253
96 254
97 @Override 255 @Override
98 public void removeNetwork(NetworkId networkId) { 256 public void removeNetwork(NetworkId networkId) {
257 + // Make sure that the virtual network exists before attempting to remove it.
258 + if (networkExists(networkId)) {
259 + VirtualNetwork virtualNetwork = networkIdVirtualNetworkMap.get(networkId);
260 + if (virtualNetwork == null) {
261 + return;
262 + }
263 + //TODO update both maps in one transaction.
264 + TenantId tenantId = virtualNetwork.tenantId();
265 + networkIdVirtualNetworkMap.compute(networkId, (id, existingVirtualNetwork) -> null);
266 +
267 +
268 + Set<NetworkId> virtualNetworkSet = tenantIdNetworkIdSetMap.get(tenantId);
269 + tenantIdNetworkIdSetMap.compute(virtualNetwork.tenantId(), (id, existingNetworkIds) -> {
270 + if (existingNetworkIds == null || existingNetworkIds.isEmpty()) {
271 + return ImmutableSet.of();
272 + } else {
273 + return ImmutableSet.<NetworkId>builder()
274 + .addAll(Sets.difference(existingNetworkIds,
275 + ImmutableSet.copyOf(virtualNetworkSet)))
276 + .build();
277 + }
278 + });
279 + }
280 + }
281 +
282 + /**
283 + * Returns if the network identifier exists.
284 + *
285 + * @param networkId network identifier
286 + * @return true if the network identifier exists, false otherwise.
287 + */
288 + private boolean networkExists(NetworkId networkId) {
289 + return (networkIdVirtualNetworkMap.containsKey(networkId));
99 } 290 }
100 291
101 @Override 292 @Override
102 public VirtualDevice addDevice(NetworkId networkId, DeviceId deviceId) { 293 public VirtualDevice addDevice(NetworkId networkId, DeviceId deviceId) {
103 - return new DefaultVirtualDevice(networkId, deviceId); 294 + checkState(networkExists(networkId), "The network has not been added.");
295 + Set<DeviceId> deviceIdSet = networkIdDeviceIdSetMap.get(networkId);
296 + if (deviceIdSet == null) {
297 + deviceIdSet = new HashSet<>();
298 + }
299 + VirtualDevice virtualDevice = new DefaultVirtualDevice(networkId, deviceId);
300 + //TODO update both maps in one transaction.
301 + deviceIdVirtualDeviceMap.put(deviceId, virtualDevice);
302 + deviceIdSet.add(deviceId);
303 + networkIdDeviceIdSetMap.put(networkId, deviceIdSet);
304 + return virtualDevice;
104 } 305 }
105 306
106 @Override 307 @Override
107 public void removeDevice(NetworkId networkId, DeviceId deviceId) { 308 public void removeDevice(NetworkId networkId, DeviceId deviceId) {
309 + checkState(networkExists(networkId), "The network has not been added.");
310 + //TODO update both maps in one transaction.
311 + Set<DeviceId> deviceIdSet = networkIdDeviceIdSetMap.get(networkId);
312 + if (deviceIdSet != null) {
313 + networkIdDeviceIdSetMap.compute(networkId, (id, existingDeviceIds) -> {
314 + if (existingDeviceIds == null || existingDeviceIds.isEmpty()) {
315 + return ImmutableSet.of();
316 + } else {
317 + return ImmutableSet.<DeviceId>builder()
318 + .addAll(Sets.difference(existingDeviceIds,
319 + ImmutableSet.copyOf(deviceIdSet)))
320 + .build();
321 + }
322 + });
323 +
324 + deviceIdVirtualDeviceMap.compute(deviceId, (id, existingVirtualDevice) -> null);
325 +
326 + log.info("The deviceIdVirtualDeviceMap size is: " + getDevices(networkId));
327 + }
108 } 328 }
109 329
110 @Override 330 @Override
111 public VirtualLink addLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId realizedBy) { 331 public VirtualLink addLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId realizedBy) {
112 - return null; 332 + checkState(networkExists(networkId), "The network has not been added.");
333 + Set<VirtualLink> virtualLinkSet = networkIdVirtualLinkSetMap.get(networkId);
334 + if (virtualLinkSet == null) {
335 + virtualLinkSet = new HashSet<>();
336 + }
337 + VirtualLink virtualLink = new DefaultVirtualLink(networkId, src, dst, realizedBy);
338 + virtualLinkSet.add(virtualLink);
339 + networkIdVirtualLinkSetMap.put(networkId, virtualLinkSet);
340 + return virtualLink;
113 } 341 }
114 342
115 @Override 343 @Override
116 public void removeLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) { 344 public void removeLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
345 + checkState(networkExists(networkId), "The network has not been added.");
346 + Set<VirtualLink> virtualLinkSet = networkIdVirtualLinkSetMap.get(networkId);
347 + if (virtualLinkSet != null) {
348 + networkIdVirtualLinkSetMap.compute(networkId, (id, existingVirtualLinks) -> {
349 + if (existingVirtualLinks == null || existingVirtualLinks.isEmpty()) {
350 + return ImmutableSet.of();
351 + } else {
352 + return ImmutableSet.<VirtualLink>builder()
353 + .addAll(Sets.difference(existingVirtualLinks,
354 + ImmutableSet.copyOf(virtualLinkSet)))
355 + .build();
356 + }
357 + });
358 + }
117 } 359 }
118 360
119 @Override 361 @Override
120 public VirtualPort addPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber, Port realizedBy) { 362 public VirtualPort addPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber, Port realizedBy) {
121 - return null; 363 + checkState(networkExists(networkId), "The network has not been added.");
364 + Set<VirtualPort> virtualPortSet = networkIdVirtualPortSetMap.get(networkId);
365 + if (virtualPortSet == null) {
366 + virtualPortSet = new HashSet<>();
367 + }
368 + Device device = deviceIdVirtualDeviceMap.get(deviceId);
369 + checkNotNull(device, "The device has not been created for deviceId: " + deviceId);
370 + VirtualPort virtualPort = new DefaultVirtualPort(networkId, device, portNumber, realizedBy);
371 + virtualPortSet.add(virtualPort);
372 + networkIdVirtualPortSetMap.put(networkId, virtualPortSet);
373 + return virtualPort;
122 } 374 }
123 375
124 @Override 376 @Override
125 public void removePort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) { 377 public void removePort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
378 + checkState(networkExists(networkId), "The network has not been added.");
379 + Set<VirtualPort> virtualPortSet = networkIdVirtualPortSetMap.get(networkId);
380 + if (virtualPortSet != null) {
381 + networkIdVirtualPortSetMap.compute(networkId, (id, existingVirtualPorts) -> {
382 + if (existingVirtualPorts == null || existingVirtualPorts.isEmpty()) {
383 + return ImmutableSet.of();
384 + } else {
385 + return ImmutableSet.<VirtualPort>builder()
386 + .addAll(Sets.difference(existingVirtualPorts,
387 + ImmutableSet.copyOf(virtualPortSet)))
388 + .build();
389 + }
390 + });
391 + }
126 } 392 }
127 393
128 @Override 394 @Override
129 public Set<VirtualNetwork> getNetworks(TenantId tenantId) { 395 public Set<VirtualNetwork> getNetworks(TenantId tenantId) {
130 - return null; 396 + Set<NetworkId> networkIdSet = tenantIdNetworkIdSetMap.get(tenantId);
397 + Set<VirtualNetwork> virtualNetworkSet = new HashSet<>();
398 + if (networkIdSet != null) {
399 + networkIdSet.forEach(networkId -> virtualNetworkSet.add(networkIdVirtualNetworkMap.get(networkId)));
400 + }
401 + return ImmutableSet.copyOf(virtualNetworkSet);
131 } 402 }
132 403
133 @Override 404 @Override
134 public Set<VirtualDevice> getDevices(NetworkId networkId) { 405 public Set<VirtualDevice> getDevices(NetworkId networkId) {
135 - return null; 406 + checkState(networkExists(networkId), "The network has not been added.");
407 + Set<DeviceId> deviceIdSet = networkIdDeviceIdSetMap.get(networkId);
408 + Set<VirtualDevice> virtualDeviceSet = new HashSet<>();
409 + if (deviceIdSet != null) {
410 + deviceIdSet.forEach(deviceId -> virtualDeviceSet.add(deviceIdVirtualDeviceMap.get(deviceId)));
411 + }
412 + return ImmutableSet.copyOf(virtualDeviceSet);
136 } 413 }
137 414
138 @Override 415 @Override
139 public Set<VirtualLink> getLinks(NetworkId networkId) { 416 public Set<VirtualLink> getLinks(NetworkId networkId) {
140 - return null; 417 + checkState(networkExists(networkId), "The network has not been added.");
418 + Set<VirtualLink> virtualLinkSet = new HashSet<>();
419 + virtualLinkSet.addAll(networkIdVirtualLinkSetMap.get(networkId));
420 + return ImmutableSet.copyOf(virtualLinkSet);
141 } 421 }
142 422
143 @Override 423 @Override
144 public Set<VirtualPort> getPorts(NetworkId networkId, DeviceId deviceId) { 424 public Set<VirtualPort> getPorts(NetworkId networkId, DeviceId deviceId) {
145 - return null; 425 + checkState(networkExists(networkId), "The network has not been added.");
426 + Set<VirtualPort> virtualPortSet = new HashSet<>();
427 + virtualPortSet.addAll(networkIdVirtualPortSetMap.get(networkId));
428 + return ImmutableSet.copyOf(virtualPortSet);
429 + }
430 +
431 + /**
432 + * Listener class to map listener set events to the virtual network events.
433 + */
434 + private class InternalSetListener implements SetEventListener<TenantId> {
435 + @Override
436 + public void event(SetEvent<TenantId> event) {
437 + VirtualNetworkEvent.Type type = null;
438 + switch (event.type()) {
439 + case ADD:
440 + type = VirtualNetworkEvent.Type.TENANT_REGISTERED;
441 + break;
442 + case REMOVE:
443 + type = VirtualNetworkEvent.Type.TENANT_UNREGISTERED;
444 + break;
445 + default:
446 + log.error("Unsupported event type: " + event.type());
447 + }
448 + notifyDelegate(new VirtualNetworkEvent(type, null));
449 + }
450 + }
451 +
452 + /**
453 + * Listener class to map listener map events to the virtual network events.
454 + */
455 + private class InternalMapListener implements MapEventListener<NetworkId, VirtualNetwork> {
456 + @Override
457 + public void event(MapEvent<NetworkId, VirtualNetwork> event) {
458 + NetworkId networkId = checkNotNull(event.key());
459 + VirtualNetworkEvent.Type type = null;
460 + switch (event.type()) {
461 + case INSERT:
462 + type = VirtualNetworkEvent.Type.NETWORK_ADDED;
463 + break;
464 + case UPDATE:
465 + if ((event.oldValue().value() != null) && (event.newValue().value() == null)) {
466 + type = VirtualNetworkEvent.Type.NETWORK_REMOVED;
467 + } else {
468 + type = VirtualNetworkEvent.Type.NETWORK_UPDATED;
469 + }
470 + break;
471 + case REMOVE:
472 + type = VirtualNetworkEvent.Type.NETWORK_REMOVED;
473 + break;
474 + default:
475 + log.error("Unsupported event type: " + event.type());
476 + }
477 + notifyDelegate(new VirtualNetworkEvent(type, networkId));
478 + }
146 } 479 }
147 } 480 }
......