Committed by
Gerrit Code Review
ONOS-2184 - Implementation of virtual network topology provider.
Change-Id: I846ba56c138187c6e5435692798e709b74a78020
Showing
14 changed files
with
921 additions
and
43 deletions
| ... | @@ -37,6 +37,7 @@ public abstract class TestDeviceParams { | ... | @@ -37,6 +37,7 @@ public abstract class TestDeviceParams { |
| 37 | protected static final DeviceId DID2 = deviceId("of:bar"); | 37 | protected static final DeviceId DID2 = deviceId("of:bar"); |
| 38 | protected static final DeviceId DID3 = deviceId("of:who"); | 38 | protected static final DeviceId DID3 = deviceId("of:who"); |
| 39 | protected static final DeviceId DID4 = deviceId("of:what"); | 39 | protected static final DeviceId DID4 = deviceId("of:what"); |
| 40 | + protected static final DeviceId DID5 = deviceId("of:when"); | ||
| 40 | protected static final MacAddress MAC1 = MacAddress.valueOf("00:11:00:00:00:01"); | 41 | protected static final MacAddress MAC1 = MacAddress.valueOf("00:11:00:00:00:01"); |
| 41 | protected static final MacAddress MAC2 = MacAddress.valueOf("00:22:00:00:00:02"); | 42 | protected static final MacAddress MAC2 = MacAddress.valueOf("00:22:00:00:00:02"); |
| 42 | protected static final VlanId VLAN1 = VlanId.vlanId((short) 11); | 43 | protected static final VlanId VLAN1 = VlanId.vlanId((short) 11); | ... | ... |
| ... | @@ -31,15 +31,12 @@ import org.onosproject.incubator.net.virtual.VirtualNetworkService; | ... | @@ -31,15 +31,12 @@ import org.onosproject.incubator.net.virtual.VirtualNetworkService; |
| 31 | import org.onosproject.incubator.net.virtual.VirtualNetworkStore; | 31 | import org.onosproject.incubator.net.virtual.VirtualNetworkStore; |
| 32 | import org.onosproject.incubator.net.virtual.VirtualPort; | 32 | import org.onosproject.incubator.net.virtual.VirtualPort; |
| 33 | import org.onosproject.net.ConnectPoint; | 33 | import org.onosproject.net.ConnectPoint; |
| 34 | -import org.onosproject.net.EncapsulationType; | ||
| 35 | import org.onosproject.net.Link; | 34 | import org.onosproject.net.Link; |
| 36 | import org.onosproject.net.Path; | 35 | import org.onosproject.net.Path; |
| 37 | -import org.onosproject.net.intent.Constraint; | ||
| 38 | import org.onosproject.net.intent.Intent; | 36 | import org.onosproject.net.intent.Intent; |
| 39 | import org.onosproject.net.intent.IntentService; | 37 | import org.onosproject.net.intent.IntentService; |
| 40 | import org.onosproject.net.intent.Key; | 38 | import org.onosproject.net.intent.Key; |
| 41 | import org.onosproject.net.intent.PointToPointIntent; | 39 | import org.onosproject.net.intent.PointToPointIntent; |
| 42 | -import org.onosproject.net.intent.constraint.EncapsulationConstraint; | ||
| 43 | import org.onosproject.net.intent.impl.IntentCompilationException; | 40 | import org.onosproject.net.intent.impl.IntentCompilationException; |
| 44 | import org.onosproject.net.topology.TopologyService; | 41 | import org.onosproject.net.topology.TopologyService; |
| 45 | import org.slf4j.Logger; | 42 | import org.slf4j.Logger; |
| ... | @@ -93,12 +90,32 @@ public class VirtualNetworkIntentCompiler | ... | @@ -93,12 +90,32 @@ public class VirtualNetworkIntentCompiler |
| 93 | Optional<Path> path = getPaths(intent).stream() | 90 | Optional<Path> path = getPaths(intent).stream() |
| 94 | .findFirst(); | 91 | .findFirst(); |
| 95 | if (path != null && path.isPresent()) { | 92 | if (path != null && path.isPresent()) { |
| 96 | - path.get().links().forEach(link -> { | 93 | + List<Link> links = path.get().links(); |
| 97 | - Intent physicalIntent = createPtPtIntent(intent, link); | ||
| 98 | - intents.add(physicalIntent); | ||
| 99 | 94 | ||
| 100 | - // store the virtual intent to physical intent tunnelId mapping | 95 | + // First create an intent between the intent ingress CP and the first link source CP, |
| 101 | - store.addTunnelId(intent, TunnelId.valueOf(physicalIntent.key().toString())); | 96 | + // only if the two CPs are not the same. |
| 97 | + Link firstLink = links.get(0); | ||
| 98 | + if (!intent.ingressPoint().equals(firstLink.src())) { | ||
| 99 | + intents.add(createPtPtIntent(intent, intent.ingressPoint(), firstLink.src())); | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + // Next create an intent between the intent egress CP and the last link destination CP, | ||
| 103 | + // only if the two CPs are not the same. | ||
| 104 | + Link lastLink = links.get(links.size() - 1); | ||
| 105 | + if (!intent.egressPoint().equals(lastLink.dst())) { | ||
| 106 | + intents.add(createPtPtIntent(intent, lastLink.dst(), intent.egressPoint())); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + // Now loop through all of the virtual links in the path and create an intent. | ||
| 110 | + // An intent is also created connecting two virtual links. | ||
| 111 | + final int[] index = {0}; | ||
| 112 | + links.forEach(link -> { | ||
| 113 | + intents.add(createPtPtIntent(intent, link.src(), link.dst())); | ||
| 114 | + if (index[0] > 0) { | ||
| 115 | + Link previousLink = links.get(index[0] - 1); | ||
| 116 | + intents.add(createPtPtIntent(intent, previousLink.dst(), link.src())); | ||
| 117 | + } | ||
| 118 | + index[0]++; | ||
| 102 | }); | 119 | }); |
| 103 | } else { | 120 | } else { |
| 104 | throw new IntentCompilationException("Unable to find a path for intent " + intent); | 121 | throw new IntentCompilationException("Unable to find a path for intent " + intent); |
| ... | @@ -124,7 +141,7 @@ public class VirtualNetworkIntentCompiler | ... | @@ -124,7 +141,7 @@ public class VirtualNetworkIntentCompiler |
| 124 | } | 141 | } |
| 125 | 142 | ||
| 126 | /** | 143 | /** |
| 127 | - * Encodes the key using the network identifier, application identifer, source and destination | 144 | + * Encodes the key using the network identifier, application identifier, source and destination |
| 128 | * connect points. | 145 | * connect points. |
| 129 | * | 146 | * |
| 130 | * @param networkId virtual network identifier | 147 | * @param networkId virtual network identifier |
| ... | @@ -133,26 +150,26 @@ public class VirtualNetworkIntentCompiler | ... | @@ -133,26 +150,26 @@ public class VirtualNetworkIntentCompiler |
| 133 | * @param dst destination connect point | 150 | * @param dst destination connect point |
| 134 | * @return encoded key | 151 | * @return encoded key |
| 135 | */ | 152 | */ |
| 153 | + | ||
| 136 | private static Key encodeKey(NetworkId networkId, ApplicationId applicationId, ConnectPoint src, ConnectPoint dst) { | 154 | private static Key encodeKey(NetworkId networkId, ApplicationId applicationId, ConnectPoint src, ConnectPoint dst) { |
| 137 | String key = String.format(KEY_FORMAT, networkId, src, dst); | 155 | String key = String.format(KEY_FORMAT, networkId, src, dst); |
| 138 | return Key.of(key, applicationId); | 156 | return Key.of(key, applicationId); |
| 139 | } | 157 | } |
| 140 | 158 | ||
| 141 | /** | 159 | /** |
| 142 | - * Creates a point-to-point intent from the virtual network intent and virtual link. | 160 | + * Creates a point-to-point intent using the virtual network intent between the source and destination |
| 161 | + * connect point. | ||
| 143 | * | 162 | * |
| 144 | * @param intent virtual network intent | 163 | * @param intent virtual network intent |
| 145 | - * @param link virtual link | 164 | + * @param src source connect point |
| 165 | + * @param dst destination connect point | ||
| 146 | * @return point to point intent | 166 | * @return point to point intent |
| 147 | */ | 167 | */ |
| 148 | - private Intent createPtPtIntent(VirtualNetworkIntent intent, Link link) { | 168 | + private Intent createPtPtIntent(VirtualNetworkIntent intent, ConnectPoint src, ConnectPoint dst) { |
| 149 | - ConnectPoint ingressPoint = mapVirtualToPhysicalPort(intent.networkId(), link.src()); | 169 | + ConnectPoint ingressPoint = mapVirtualToPhysicalPort(intent.networkId(), src); |
| 150 | - ConnectPoint egressPoint = mapVirtualToPhysicalPort(intent.networkId(), link.dst()); | 170 | + ConnectPoint egressPoint = mapVirtualToPhysicalPort(intent.networkId(), dst); |
| 151 | Key intentKey = encodeKey(intent.networkId(), intent.appId(), ingressPoint, egressPoint); | 171 | Key intentKey = encodeKey(intent.networkId(), intent.appId(), ingressPoint, egressPoint); |
| 152 | 172 | ||
| 153 | - List<Constraint> constraints = new ArrayList<>(); | ||
| 154 | - constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN)); | ||
| 155 | - | ||
| 156 | // TODO Currently there can only be one intent between the ingress and egress across | 173 | // TODO Currently there can only be one intent between the ingress and egress across |
| 157 | // all virtual networks. We may want to support multiple intents between the same src/dst pairs. | 174 | // all virtual networks. We may want to support multiple intents between the same src/dst pairs. |
| 158 | PointToPointIntent physicalIntent = PointToPointIntent.builder() | 175 | PointToPointIntent physicalIntent = PointToPointIntent.builder() |
| ... | @@ -160,11 +177,16 @@ public class VirtualNetworkIntentCompiler | ... | @@ -160,11 +177,16 @@ public class VirtualNetworkIntentCompiler |
| 160 | .appId(intent.appId()) | 177 | .appId(intent.appId()) |
| 161 | .ingressPoint(ingressPoint) | 178 | .ingressPoint(ingressPoint) |
| 162 | .egressPoint(egressPoint) | 179 | .egressPoint(egressPoint) |
| 163 | - .constraints(constraints) | 180 | + .constraints(intent.constraints()) |
| 181 | + .selector(intent.selector()) | ||
| 182 | + .treatment(intent.treatment()) | ||
| 164 | .build(); | 183 | .build(); |
| 165 | log.debug("Submitting physical intent: " + physicalIntent); | 184 | log.debug("Submitting physical intent: " + physicalIntent); |
| 166 | intentService.submit(physicalIntent); | 185 | intentService.submit(physicalIntent); |
| 167 | 186 | ||
| 187 | + // Store the physical intent against this virtual intent. | ||
| 188 | + store.addTunnelId(intent, TunnelId.valueOf(physicalIntent.key().toString())); | ||
| 189 | + | ||
| 168 | return physicalIntent; | 190 | return physicalIntent; |
| 169 | } | 191 | } |
| 170 | 192 | ... | ... |
| ... | @@ -39,13 +39,11 @@ import org.onosproject.incubator.net.virtual.impl.VirtualNetworkManager; | ... | @@ -39,13 +39,11 @@ import org.onosproject.incubator.net.virtual.impl.VirtualNetworkManager; |
| 39 | import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore; | 39 | import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore; |
| 40 | import org.onosproject.net.ConnectPoint; | 40 | import org.onosproject.net.ConnectPoint; |
| 41 | import org.onosproject.net.DefaultPort; | 41 | import org.onosproject.net.DefaultPort; |
| 42 | -import org.onosproject.net.EncapsulationType; | ||
| 43 | import org.onosproject.net.Link; | 42 | import org.onosproject.net.Link; |
| 44 | import org.onosproject.net.NetTestTools; | 43 | import org.onosproject.net.NetTestTools; |
| 45 | import org.onosproject.net.Port; | 44 | import org.onosproject.net.Port; |
| 46 | import org.onosproject.net.PortNumber; | 45 | import org.onosproject.net.PortNumber; |
| 47 | import org.onosproject.net.TestDeviceParams; | 46 | import org.onosproject.net.TestDeviceParams; |
| 48 | -import org.onosproject.net.intent.Constraint; | ||
| 49 | import org.onosproject.net.intent.FakeIntentManager; | 47 | import org.onosproject.net.intent.FakeIntentManager; |
| 50 | import org.onosproject.net.intent.Intent; | 48 | import org.onosproject.net.intent.Intent; |
| 51 | import org.onosproject.net.intent.IntentExtensionService; | 49 | import org.onosproject.net.intent.IntentExtensionService; |
| ... | @@ -53,10 +51,8 @@ import org.onosproject.net.intent.IntentService; | ... | @@ -53,10 +51,8 @@ import org.onosproject.net.intent.IntentService; |
| 53 | import org.onosproject.net.intent.Key; | 51 | import org.onosproject.net.intent.Key; |
| 54 | import org.onosproject.net.intent.MockIdGenerator; | 52 | import org.onosproject.net.intent.MockIdGenerator; |
| 55 | import org.onosproject.net.intent.TestableIntentService; | 53 | import org.onosproject.net.intent.TestableIntentService; |
| 56 | -import org.onosproject.net.intent.constraint.EncapsulationConstraint; | ||
| 57 | import org.onosproject.store.service.TestStorageService; | 54 | import org.onosproject.store.service.TestStorageService; |
| 58 | 55 | ||
| 59 | -import java.util.ArrayList; | ||
| 60 | import java.util.Collections; | 56 | import java.util.Collections; |
| 61 | import java.util.List; | 57 | import java.util.List; |
| 62 | import java.util.concurrent.atomic.AtomicLong; | 58 | import java.util.concurrent.atomic.AtomicLong; |
| ... | @@ -192,6 +188,9 @@ public class VirtualNetworkIntentCompilerTest extends TestDeviceParams { | ... | @@ -192,6 +188,9 @@ public class VirtualNetworkIntentCompilerTest extends TestDeviceParams { |
| 192 | return virtualNetwork; | 188 | return virtualNetwork; |
| 193 | } | 189 | } |
| 194 | 190 | ||
| 191 | + /** | ||
| 192 | + * Tests the virtual network intent compiler. | ||
| 193 | + */ | ||
| 195 | @Test | 194 | @Test |
| 196 | public void testCompiler() { | 195 | public void testCompiler() { |
| 197 | compiler.activate(); | 196 | compiler.activate(); |
| ... | @@ -199,20 +198,16 @@ public class VirtualNetworkIntentCompilerTest extends TestDeviceParams { | ... | @@ -199,20 +198,16 @@ public class VirtualNetworkIntentCompilerTest extends TestDeviceParams { |
| 199 | 198 | ||
| 200 | Key intentKey = Key.of("test", APP_ID); | 199 | Key intentKey = Key.of("test", APP_ID); |
| 201 | 200 | ||
| 202 | - List<Constraint> constraints = new ArrayList<>(); | ||
| 203 | - constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN)); | ||
| 204 | - | ||
| 205 | VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder() | 201 | VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder() |
| 206 | .networkId(virtualNetwork.id()) | 202 | .networkId(virtualNetwork.id()) |
| 207 | .key(intentKey) | 203 | .key(intentKey) |
| 208 | .appId(APP_ID) | 204 | .appId(APP_ID) |
| 209 | - .ingressPoint(cp1) | 205 | + .ingressPoint(cp2) |
| 210 | - .egressPoint(cp5) | 206 | + .egressPoint(cp6) |
| 211 | - .constraints(constraints) | ||
| 212 | .build(); | 207 | .build(); |
| 213 | 208 | ||
| 214 | List<Intent> compiled = compiler.compile(virtualIntent, Collections.emptyList()); | 209 | List<Intent> compiled = compiler.compile(virtualIntent, Collections.emptyList()); |
| 215 | - assertEquals("The virtual intents size is not as expected.", 2, compiled.size()); | 210 | + assertEquals("The virtual intents size is not as expected.", 5, compiled.size()); |
| 216 | 211 | ||
| 217 | compiler.deactivate(); | 212 | compiler.deactivate(); |
| 218 | } | 213 | } | ... | ... |
| ... | @@ -26,6 +26,18 @@ import org.onosproject.net.provider.Provider; | ... | @@ -26,6 +26,18 @@ import org.onosproject.net.provider.Provider; |
| 26 | public interface VirtualNetworkProvider extends Provider { | 26 | public interface VirtualNetworkProvider extends Provider { |
| 27 | 27 | ||
| 28 | /** | 28 | /** |
| 29 | + * Indicates whether or not the specified connect points on the underlying | ||
| 30 | + * network are traversable/reachable. | ||
| 31 | + * | ||
| 32 | + * @param src source connection point | ||
| 33 | + * @param dst destination connection point | ||
| 34 | + * @return true if the destination is reachable from the source | ||
| 35 | + */ | ||
| 36 | + boolean isTraversable(ConnectPoint src, ConnectPoint dst); | ||
| 37 | + | ||
| 38 | + // TODO: Further enhance this interface to support the virtual intent programming across this boundary. | ||
| 39 | + | ||
| 40 | + /** | ||
| 29 | * Creates a network tunnel for all traffic from the specified source | 41 | * Creates a network tunnel for all traffic from the specified source |
| 30 | * connection point to the indicated destination connection point. | 42 | * connection point to the indicated destination connection point. |
| 31 | * | 43 | * | ... | ... |
incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderService.java
| ... | @@ -19,6 +19,8 @@ import org.onosproject.incubator.net.tunnel.TunnelId; | ... | @@ -19,6 +19,8 @@ import org.onosproject.incubator.net.tunnel.TunnelId; |
| 19 | import org.onosproject.net.ConnectPoint; | 19 | import org.onosproject.net.ConnectPoint; |
| 20 | import org.onosproject.net.provider.ProviderService; | 20 | import org.onosproject.net.provider.ProviderService; |
| 21 | 21 | ||
| 22 | +import java.util.Set; | ||
| 23 | + | ||
| 22 | /** | 24 | /** |
| 23 | * Service through which virtual network providers can inject information into | 25 | * Service through which virtual network providers can inject information into |
| 24 | * the core. | 26 | * the core. |
| ... | @@ -26,6 +28,18 @@ import org.onosproject.net.provider.ProviderService; | ... | @@ -26,6 +28,18 @@ import org.onosproject.net.provider.ProviderService; |
| 26 | public interface VirtualNetworkProviderService extends ProviderService<VirtualNetworkProvider> { | 28 | public interface VirtualNetworkProviderService extends ProviderService<VirtualNetworkProvider> { |
| 27 | 29 | ||
| 28 | /** | 30 | /** |
| 31 | + * Set of separate topology clusters expressed in terms of connect points which | ||
| 32 | + * belong to the same SCC of the underlying topology. | ||
| 33 | + * | ||
| 34 | + * @param clusters set of sets of mutually reachable connection points; | ||
| 35 | + * the outer sets are not mutually reachable | ||
| 36 | + */ | ||
| 37 | + void topologyChanged(Set<Set<ConnectPoint>> clusters); | ||
| 38 | + | ||
| 39 | + // TBD: Is the above sufficient to determine health/viability of virtual entities based on | ||
| 40 | + // clustering (SCC) of the physical ones? | ||
| 41 | + | ||
| 42 | + /** | ||
| 29 | * This method is used to notify the VirtualNetwork service that a tunnel is now ACTIVE. | 43 | * This method is used to notify the VirtualNetwork service that a tunnel is now ACTIVE. |
| 30 | * | 44 | * |
| 31 | * @param networkId network identifier | 45 | * @param networkId network identifier | ... | ... |
| ... | @@ -108,6 +108,11 @@ public class PtToPtIntentVirtualNetworkProvider extends AbstractProvider | ... | @@ -108,6 +108,11 @@ public class PtToPtIntentVirtualNetworkProvider extends AbstractProvider |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | @Override | 110 | @Override |
| 111 | + public boolean isTraversable(ConnectPoint src, ConnectPoint dst) { | ||
| 112 | + return false; | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + @Override | ||
| 111 | public TunnelId createTunnel(NetworkId networkId, ConnectPoint src, ConnectPoint dst) { | 116 | public TunnelId createTunnel(NetworkId networkId, ConnectPoint src, ConnectPoint dst) { |
| 112 | checkNotNull(networkId, NETWORK_ID_NULL); | 117 | checkNotNull(networkId, NETWORK_ID_NULL); |
| 113 | checkNotNull(src, CONNECT_POINT_NULL); | 118 | checkNotNull(src, CONNECT_POINT_NULL); | ... | ... |
| ... | @@ -46,7 +46,7 @@ import java.util.Optional; | ... | @@ -46,7 +46,7 @@ import java.util.Optional; |
| 46 | import static com.google.common.base.Preconditions.*; | 46 | import static com.google.common.base.Preconditions.*; |
| 47 | 47 | ||
| 48 | /** | 48 | /** |
| 49 | - * intent service implementation built on the virtual network service. | 49 | + * Intent service implementation built on the virtual network service. |
| 50 | */ | 50 | */ |
| 51 | public class VirtualNetworkIntentService extends AbstractListenerManager<IntentEvent, IntentListener> | 51 | public class VirtualNetworkIntentService extends AbstractListenerManager<IntentEvent, IntentListener> |
| 52 | implements IntentService, VnetService { | 52 | implements IntentService, VnetService { |
| ... | @@ -148,18 +148,17 @@ public class VirtualNetworkIntentService extends AbstractListenerManager<IntentE | ... | @@ -148,18 +148,17 @@ public class VirtualNetworkIntentService extends AbstractListenerManager<IntentE |
| 148 | public void withdraw(Intent intent) { | 148 | public void withdraw(Intent intent) { |
| 149 | checkNotNull(intent, INTENT_NULL); | 149 | checkNotNull(intent, INTENT_NULL); |
| 150 | // Withdraws the physical intents created due to the virtual intents. | 150 | // Withdraws the physical intents created due to the virtual intents. |
| 151 | - store.getTunnelIds(intent) | 151 | + store.getTunnelIds(intent).forEach(tunnelId -> { |
| 152 | - .forEach(tunnelId -> { | ||
| 153 | Key intentKey = Key.of(tunnelId.id(), intent.appId()); | 152 | Key intentKey = Key.of(tunnelId.id(), intent.appId()); |
| 154 | Intent physicalIntent = intentService.getIntent(intentKey); | 153 | Intent physicalIntent = intentService.getIntent(intentKey); |
| 155 | checkNotNull(physicalIntent, INTENT_NULL); | 154 | checkNotNull(physicalIntent, INTENT_NULL); |
| 156 | 155 | ||
| 157 | // Withdraw the physical intent(s) | 156 | // Withdraw the physical intent(s) |
| 158 | - log.info("Withdrawing pt-pt intent: " + physicalIntent); | 157 | + log.debug("Withdrawing pt-pt intent: " + physicalIntent); |
| 159 | intentService.withdraw(physicalIntent); | 158 | intentService.withdraw(physicalIntent); |
| 160 | }); | 159 | }); |
| 161 | // Now withdraw the virtual intent | 160 | // Now withdraw the virtual intent |
| 162 | - log.info("Withdrawing virtual intent: " + intent); | 161 | + log.debug("Withdrawing virtual intent: " + intent); |
| 163 | intentService.withdraw(intent); | 162 | intentService.withdraw(intent); |
| 164 | } | 163 | } |
| 165 | 164 | ... | ... |
| ... | @@ -27,6 +27,7 @@ import org.onlab.packet.IpAddress; | ... | @@ -27,6 +27,7 @@ import org.onlab.packet.IpAddress; |
| 27 | import org.onlab.packet.MacAddress; | 27 | import org.onlab.packet.MacAddress; |
| 28 | import org.onlab.packet.VlanId; | 28 | import org.onlab.packet.VlanId; |
| 29 | import org.onosproject.incubator.net.tunnel.TunnelId; | 29 | import org.onosproject.incubator.net.tunnel.TunnelId; |
| 30 | +import org.onosproject.incubator.net.virtual.DefaultVirtualLink; | ||
| 30 | import org.onosproject.incubator.net.virtual.NetworkId; | 31 | import org.onosproject.incubator.net.virtual.NetworkId; |
| 31 | import org.onosproject.incubator.net.virtual.TenantId; | 32 | import org.onosproject.incubator.net.virtual.TenantId; |
| 32 | import org.onosproject.incubator.net.virtual.VirtualDevice; | 33 | import org.onosproject.incubator.net.virtual.VirtualDevice; |
| ... | @@ -197,7 +198,36 @@ public class VirtualNetworkManager | ... | @@ -197,7 +198,36 @@ public class VirtualNetworkManager |
| 197 | checkNotNull(networkId, NETWORK_NULL); | 198 | checkNotNull(networkId, NETWORK_NULL); |
| 198 | checkNotNull(src, LINK_POINT_NULL); | 199 | checkNotNull(src, LINK_POINT_NULL); |
| 199 | checkNotNull(dst, LINK_POINT_NULL); | 200 | checkNotNull(dst, LINK_POINT_NULL); |
| 200 | - return store.addLink(networkId, src, dst, Link.State.ACTIVE, null); | 201 | + ConnectPoint physicalSrc = mapVirtualToPhysicalPort(networkId, src); |
| 202 | + checkNotNull(physicalSrc, LINK_POINT_NULL); | ||
| 203 | + ConnectPoint physicalDst = mapVirtualToPhysicalPort(networkId, dst); | ||
| 204 | + checkNotNull(physicalDst, LINK_POINT_NULL); | ||
| 205 | + | ||
| 206 | + VirtualNetworkProvider provider = getProvider(DefaultVirtualLink.PID); | ||
| 207 | + Link.State state = Link.State.INACTIVE; | ||
| 208 | + if (provider != null) { | ||
| 209 | + boolean traversable = provider.isTraversable(physicalSrc, physicalDst); | ||
| 210 | + state = traversable ? Link.State.ACTIVE : Link.State.INACTIVE; | ||
| 211 | + } | ||
| 212 | + return store.addLink(networkId, src, dst, state, null); | ||
| 213 | + } | ||
| 214 | + | ||
| 215 | + /** | ||
| 216 | + * Maps the virtual connect point to a physical connect point. | ||
| 217 | + * | ||
| 218 | + * @param networkId network identifier | ||
| 219 | + * @param virtualCp virtual connect point | ||
| 220 | + * @return physical connect point | ||
| 221 | + */ | ||
| 222 | + private ConnectPoint mapVirtualToPhysicalPort(NetworkId networkId, | ||
| 223 | + ConnectPoint virtualCp) { | ||
| 224 | + Set<VirtualPort> ports = store.getPorts(networkId, virtualCp.deviceId()); | ||
| 225 | + for (VirtualPort port : ports) { | ||
| 226 | + if (port.number().equals(virtualCp.port())) { | ||
| 227 | + return new ConnectPoint(port.realizedBy().element().id(), port.realizedBy().number()); | ||
| 228 | + } | ||
| 229 | + } | ||
| 230 | + return null; | ||
| 201 | } | 231 | } |
| 202 | 232 | ||
| 203 | /** | 233 | /** |
| ... | @@ -441,16 +471,73 @@ public class VirtualNetworkManager | ... | @@ -441,16 +471,73 @@ public class VirtualNetworkManager |
| 441 | return new InternalVirtualNetworkProviderService(provider); | 471 | return new InternalVirtualNetworkProviderService(provider); |
| 442 | } | 472 | } |
| 443 | 473 | ||
| 444 | - // Service issued to registered virtual network providers so that they | 474 | + /** |
| 445 | - // can interact with the core. | 475 | + * Service issued to registered virtual network providers so that they |
| 476 | + * can interact with the core. | ||
| 477 | + */ | ||
| 446 | private class InternalVirtualNetworkProviderService | 478 | private class InternalVirtualNetworkProviderService |
| 447 | extends AbstractProviderService<VirtualNetworkProvider> | 479 | extends AbstractProviderService<VirtualNetworkProvider> |
| 448 | implements VirtualNetworkProviderService { | 480 | implements VirtualNetworkProviderService { |
| 481 | + /** | ||
| 482 | + * Constructor. | ||
| 483 | + * @param provider virtual network provider | ||
| 484 | + */ | ||
| 449 | InternalVirtualNetworkProviderService(VirtualNetworkProvider provider) { | 485 | InternalVirtualNetworkProviderService(VirtualNetworkProvider provider) { |
| 450 | super(provider); | 486 | super(provider); |
| 451 | } | 487 | } |
| 452 | 488 | ||
| 453 | @Override | 489 | @Override |
| 490 | + public void topologyChanged(Set<Set<ConnectPoint>> clusters) { | ||
| 491 | + | ||
| 492 | + Set<TenantId> tenantIds = getTenantIds(); | ||
| 493 | + tenantIds.forEach(tenantId -> { | ||
| 494 | + Set<VirtualNetwork> virtualNetworks = getVirtualNetworks(tenantId); | ||
| 495 | + | ||
| 496 | + virtualNetworks.forEach(virtualNetwork -> { | ||
| 497 | + Set<VirtualLink> virtualLinks = getVirtualLinks(virtualNetwork.id()); | ||
| 498 | + | ||
| 499 | + virtualLinks.forEach(virtualLink -> { | ||
| 500 | + if (isVirtualLinkInCluster(virtualNetwork.id(), virtualLink, clusters)) { | ||
| 501 | + store.updateLink(virtualLink, virtualLink.tunnelId(), Link.State.ACTIVE); | ||
| 502 | + } else { | ||
| 503 | + store.updateLink(virtualLink, virtualLink.tunnelId(), Link.State.INACTIVE); | ||
| 504 | + } | ||
| 505 | + }); | ||
| 506 | + }); | ||
| 507 | + }); | ||
| 508 | + } | ||
| 509 | + | ||
| 510 | + /** | ||
| 511 | + * Determines if the virtual link (both source and destination connect point) is in a cluster. | ||
| 512 | + * | ||
| 513 | + * @param networkId virtual network identifier | ||
| 514 | + * @param virtualLink virtual link | ||
| 515 | + * @param clusters topology clusters | ||
| 516 | + * @return true if the virtual link is in a cluster. | ||
| 517 | + */ | ||
| 518 | + private boolean isVirtualLinkInCluster(NetworkId networkId, VirtualLink virtualLink, | ||
| 519 | + Set<Set<ConnectPoint>> clusters) { | ||
| 520 | + ConnectPoint srcPhysicalCp = mapVirtualToPhysicalPort(networkId, virtualLink.src()); | ||
| 521 | + ConnectPoint dstPhysicalCp = mapVirtualToPhysicalPort(networkId, virtualLink.dst()); | ||
| 522 | + | ||
| 523 | + final boolean[] foundSrc = {false}; | ||
| 524 | + final boolean[] foundDst = {false}; | ||
| 525 | + clusters.forEach(connectPoints -> { | ||
| 526 | + connectPoints.forEach(connectPoint -> { | ||
| 527 | + if (connectPoint.equals(srcPhysicalCp)) { | ||
| 528 | + foundSrc[0] = true; | ||
| 529 | + } else if (connectPoint.equals(dstPhysicalCp)) { | ||
| 530 | + foundDst[0] = true; | ||
| 531 | + } | ||
| 532 | + }); | ||
| 533 | + if (foundSrc[0] && foundDst[0]) { | ||
| 534 | + return; | ||
| 535 | + } | ||
| 536 | + }); | ||
| 537 | + return foundSrc[0] && foundDst[0]; | ||
| 538 | + } | ||
| 539 | + | ||
| 540 | + @Override | ||
| 454 | public void tunnelUp(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) { | 541 | public void tunnelUp(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) { |
| 455 | 542 | ||
| 456 | ConnectPoint srcVirtualCp = mapPhysicalToVirtualToPort(networkId, src); | 543 | ConnectPoint srcVirtualCp = mapPhysicalToVirtualToPort(networkId, src); | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2016-present 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 org.apache.felix.scr.annotations.Activate; | ||
| 20 | +import org.apache.felix.scr.annotations.Component; | ||
| 21 | +import org.apache.felix.scr.annotations.Deactivate; | ||
| 22 | +import org.apache.felix.scr.annotations.Reference; | ||
| 23 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
| 24 | +import org.apache.felix.scr.annotations.Service; | ||
| 25 | +import org.onosproject.incubator.net.tunnel.TunnelId; | ||
| 26 | +import org.onosproject.incubator.net.virtual.DefaultVirtualLink; | ||
| 27 | +import org.onosproject.incubator.net.virtual.NetworkId; | ||
| 28 | +import org.onosproject.incubator.net.virtual.VirtualNetworkProvider; | ||
| 29 | +import org.onosproject.incubator.net.virtual.VirtualNetworkProviderRegistry; | ||
| 30 | +import org.onosproject.incubator.net.virtual.VirtualNetworkProviderService; | ||
| 31 | +import org.onosproject.net.ConnectPoint; | ||
| 32 | +import org.onosproject.net.Link; | ||
| 33 | +import org.onosproject.net.Path; | ||
| 34 | +import org.onosproject.net.link.LinkEvent; | ||
| 35 | +import org.onosproject.net.provider.AbstractProvider; | ||
| 36 | +import org.onosproject.net.topology.Topology; | ||
| 37 | +import org.onosproject.net.topology.TopologyCluster; | ||
| 38 | +import org.onosproject.net.topology.TopologyEvent; | ||
| 39 | +import org.onosproject.net.topology.TopologyListener; | ||
| 40 | +import org.onosproject.net.topology.TopologyService; | ||
| 41 | +import org.slf4j.Logger; | ||
| 42 | + | ||
| 43 | +import java.util.HashSet; | ||
| 44 | +import java.util.Set; | ||
| 45 | + | ||
| 46 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 47 | + | ||
| 48 | +/** | ||
| 49 | + * Virtual network topology provider. | ||
| 50 | + */ | ||
| 51 | +@Component(immediate = true) | ||
| 52 | +@Service | ||
| 53 | +public class VirtualNetworkTopologyProvider extends AbstractProvider implements VirtualNetworkProvider { | ||
| 54 | + | ||
| 55 | + private final Logger log = getLogger(VirtualNetworkTopologyProvider.class); | ||
| 56 | + | ||
| 57 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 58 | + protected VirtualNetworkProviderRegistry providerRegistry; | ||
| 59 | + | ||
| 60 | + private VirtualNetworkProviderService providerService; | ||
| 61 | + | ||
| 62 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 63 | + protected TopologyService topologyService; | ||
| 64 | + | ||
| 65 | + protected TopologyListener topologyListener = new InternalTopologyListener(); | ||
| 66 | + | ||
| 67 | + /** | ||
| 68 | + * Default constructor. | ||
| 69 | + */ | ||
| 70 | + public VirtualNetworkTopologyProvider() { | ||
| 71 | + super(DefaultVirtualLink.PID); | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + @Activate | ||
| 75 | + public void activate() { | ||
| 76 | + providerService = providerRegistry.register(this); | ||
| 77 | + topologyService.addListener(topologyListener); | ||
| 78 | + | ||
| 79 | + log.info("Started"); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + @Deactivate | ||
| 83 | + public void deactivate() { | ||
| 84 | + topologyService.removeListener(topologyListener); | ||
| 85 | + providerRegistry.unregister(this); | ||
| 86 | + providerService = null; | ||
| 87 | + log.info("Stopped"); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + @Override | ||
| 91 | + public boolean isTraversable(ConnectPoint src, ConnectPoint dst) { | ||
| 92 | + final boolean[] foundSrc = new boolean[1]; | ||
| 93 | + final boolean[] foundDst = new boolean[1]; | ||
| 94 | + Topology topology = topologyService.currentTopology(); | ||
| 95 | + Set<Path> paths = topologyService.getPaths(topology, src.deviceId(), dst.deviceId()); | ||
| 96 | + paths.forEach(path -> { | ||
| 97 | + foundDst[0] = false; | ||
| 98 | + foundSrc[0] = false; | ||
| 99 | + // Traverse the links in each path to determine if both the src and dst connection | ||
| 100 | + // point are in the path, if so then this src/dst pair are traversable. | ||
| 101 | + path.links().forEach(link -> { | ||
| 102 | + if (link.src().equals(src)) { | ||
| 103 | + foundSrc[0] = true; | ||
| 104 | + } | ||
| 105 | + if (link.dst().equals(dst)) { | ||
| 106 | + foundDst[0] = true; | ||
| 107 | + } | ||
| 108 | + }); | ||
| 109 | + if (foundSrc[0] && foundDst[0]) { | ||
| 110 | + return; | ||
| 111 | + } | ||
| 112 | + }); | ||
| 113 | + return foundSrc[0] && foundDst[0]; | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + @Override | ||
| 117 | + public TunnelId createTunnel(NetworkId networkId, ConnectPoint src, ConnectPoint dst) { | ||
| 118 | + return null; | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + @Override | ||
| 122 | + public void destroyTunnel(NetworkId networkId, TunnelId tunnelId) { | ||
| 123 | + | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + /** | ||
| 127 | + * Returns a set of set of interconnected connect points in the default topology. | ||
| 128 | + * The inner set represents the interconnected connect points, and the outerset | ||
| 129 | + * represents separate clusters. | ||
| 130 | + * | ||
| 131 | + * @param topology the default topology | ||
| 132 | + * @return set of set of interconnected connect points. | ||
| 133 | + */ | ||
| 134 | + protected Set<Set<ConnectPoint>> getConnectPoints(Topology topology) { | ||
| 135 | + Set<Set<ConnectPoint>> clusters = new HashSet<>(); | ||
| 136 | + Set<TopologyCluster> topologyClusters = topologyService.getClusters(topology); | ||
| 137 | + topologyClusters.forEach(topologyCluster -> { | ||
| 138 | + Set<ConnectPoint> connectPointSet = new HashSet<>(); | ||
| 139 | + Set<Link> clusterLinks = topologyService.getClusterLinks(topology, topologyCluster); | ||
| 140 | + clusterLinks.forEach(link -> { | ||
| 141 | + connectPointSet.add(link.src()); | ||
| 142 | + connectPointSet.add(link.dst()); | ||
| 143 | + }); | ||
| 144 | + if (!connectPointSet.isEmpty()) { | ||
| 145 | + clusters.add(connectPointSet); | ||
| 146 | + } | ||
| 147 | + }); | ||
| 148 | + return clusters; | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + /** | ||
| 152 | + * Topology event listener. | ||
| 153 | + */ | ||
| 154 | + private class InternalTopologyListener implements TopologyListener { | ||
| 155 | + @Override | ||
| 156 | + public void event(TopologyEvent event) { | ||
| 157 | + if (!isRelevant(event)) { | ||
| 158 | + return; | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + Topology topology = event.subject(); | ||
| 162 | + providerService.topologyChanged(getConnectPoints(topology)); | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + @Override | ||
| 166 | + public boolean isRelevant(TopologyEvent event) { | ||
| 167 | + final boolean[] relevant = {false}; | ||
| 168 | + if (event.type().equals(TopologyEvent.Type.TOPOLOGY_CHANGED)) { | ||
| 169 | + event.reasons().forEach(event1 -> { | ||
| 170 | + // Only LinkEvents are relevant events, ie: DeviceEvents and others are ignored. | ||
| 171 | + if (event1 instanceof LinkEvent) { | ||
| 172 | + relevant[0] = true; | ||
| 173 | + return; | ||
| 174 | + } | ||
| 175 | + }); | ||
| 176 | + } | ||
| 177 | + return relevant[0]; | ||
| 178 | + } | ||
| 179 | + } | ||
| 180 | +} |
| ... | @@ -220,6 +220,11 @@ public class PtToPtIntentVirtualNetworkProviderTest { | ... | @@ -220,6 +220,11 @@ public class PtToPtIntentVirtualNetworkProviderTest { |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | @Override | 222 | @Override |
| 223 | + public void topologyChanged(Set<Set<ConnectPoint>> clusters) { | ||
| 224 | + | ||
| 225 | + } | ||
| 226 | + | ||
| 227 | + @Override | ||
| 223 | public void tunnelUp(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) { | 228 | public void tunnelUp(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) { |
| 224 | // Release one permit on the created semaphore since the tunnelUp method was called. | 229 | // Release one permit on the created semaphore since the tunnelUp method was called. |
| 225 | created.release(); | 230 | created.release(); | ... | ... |
| ... | @@ -31,6 +31,7 @@ import org.onosproject.incubator.net.virtual.VirtualLink; | ... | @@ -31,6 +31,7 @@ import org.onosproject.incubator.net.virtual.VirtualLink; |
| 31 | import org.onosproject.incubator.net.virtual.VirtualNetwork; | 31 | import org.onosproject.incubator.net.virtual.VirtualNetwork; |
| 32 | import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore; | 32 | import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore; |
| 33 | import org.onosproject.net.ConnectPoint; | 33 | import org.onosproject.net.ConnectPoint; |
| 34 | +import org.onosproject.net.DefaultPort; | ||
| 34 | import org.onosproject.net.Link; | 35 | import org.onosproject.net.Link; |
| 35 | import org.onosproject.net.NetTestTools; | 36 | import org.onosproject.net.NetTestTools; |
| 36 | import org.onosproject.net.PortNumber; | 37 | import org.onosproject.net.PortNumber; |
| ... | @@ -97,7 +98,13 @@ public class VirtualNetworkLinkServiceTest extends TestDeviceParams { | ... | @@ -97,7 +98,13 @@ public class VirtualNetworkLinkServiceTest extends TestDeviceParams { |
| 97 | VirtualDevice dstVirtualDevice = | 98 | VirtualDevice dstVirtualDevice = |
| 98 | manager.createVirtualDevice(virtualNetwork.id(), DID2); | 99 | manager.createVirtualDevice(virtualNetwork.id(), DID2); |
| 99 | ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1)); | 100 | ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1)); |
| 101 | + manager.createVirtualPort(virtualNetwork.id(), src.deviceId(), src.port(), | ||
| 102 | + new DefaultPort(srcVirtualDevice, src.port(), true)); | ||
| 103 | + | ||
| 100 | ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2)); | 104 | ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2)); |
| 105 | + manager.createVirtualPort(virtualNetwork.id(), dst.deviceId(), dst.port(), | ||
| 106 | + new DefaultPort(dstVirtualDevice, dst.port(), true)); | ||
| 107 | + | ||
| 101 | VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), src, dst); | 108 | VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), src, dst); |
| 102 | VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), dst, src); | 109 | VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), dst, src); |
| 103 | 110 | ||
| ... | @@ -107,12 +114,12 @@ public class VirtualNetworkLinkServiceTest extends TestDeviceParams { | ... | @@ -107,12 +114,12 @@ public class VirtualNetworkLinkServiceTest extends TestDeviceParams { |
| 107 | Iterator<Link> it = linkService.getLinks().iterator(); | 114 | Iterator<Link> it = linkService.getLinks().iterator(); |
| 108 | assertEquals("The link set size did not match.", 2, Iterators.size(it)); | 115 | assertEquals("The link set size did not match.", 2, Iterators.size(it)); |
| 109 | 116 | ||
| 110 | - // test the getActiveLinks() method where all links are ACTIVE | 117 | + // test the getActiveLinks() method where all links are INACTIVE |
| 111 | Iterator<Link> it2 = linkService.getActiveLinks().iterator(); | 118 | Iterator<Link> it2 = linkService.getActiveLinks().iterator(); |
| 112 | - assertEquals("The link set size did not match.", 2, Iterators.size(it2)); | 119 | + assertEquals("The link set size did not match.", 0, Iterators.size(it2)); |
| 113 | 120 | ||
| 114 | // test the getActiveLinks() method where one link is ACTIVE | 121 | // test the getActiveLinks() method where one link is ACTIVE |
| 115 | - virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.INACTIVE); | 122 | + virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE); |
| 116 | Iterator<Link> it3 = linkService.getActiveLinks().iterator(); | 123 | Iterator<Link> it3 = linkService.getActiveLinks().iterator(); |
| 117 | assertEquals("The link set size did not match.", 1, Iterators.size(it3)); | 124 | assertEquals("The link set size did not match.", 1, Iterators.size(it3)); |
| 118 | 125 | ... | ... |
| ... | @@ -38,12 +38,13 @@ import org.onosproject.incubator.net.virtual.VirtualNetwork; | ... | @@ -38,12 +38,13 @@ import org.onosproject.incubator.net.virtual.VirtualNetwork; |
| 38 | import org.onosproject.incubator.net.virtual.VirtualNetworkEvent; | 38 | import org.onosproject.incubator.net.virtual.VirtualNetworkEvent; |
| 39 | import org.onosproject.incubator.net.virtual.VirtualNetworkIntent; | 39 | import org.onosproject.incubator.net.virtual.VirtualNetworkIntent; |
| 40 | import org.onosproject.incubator.net.virtual.VirtualNetworkListener; | 40 | import org.onosproject.incubator.net.virtual.VirtualNetworkListener; |
| 41 | -import org.onosproject.incubator.net.virtual.VirtualNetworkService; | 41 | +import org.onosproject.incubator.net.virtual.VirtualNetworkProviderService; |
| 42 | import org.onosproject.incubator.net.virtual.VirtualPort; | 42 | import org.onosproject.incubator.net.virtual.VirtualPort; |
| 43 | import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore; | 43 | import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore; |
| 44 | import org.onosproject.net.ConnectPoint; | 44 | import org.onosproject.net.ConnectPoint; |
| 45 | import org.onosproject.net.DefaultPort; | 45 | import org.onosproject.net.DefaultPort; |
| 46 | import org.onosproject.net.DeviceId; | 46 | import org.onosproject.net.DeviceId; |
| 47 | +import org.onosproject.net.Link; | ||
| 47 | import org.onosproject.net.NetTestTools; | 48 | import org.onosproject.net.NetTestTools; |
| 48 | import org.onosproject.net.Port; | 49 | import org.onosproject.net.Port; |
| 49 | import org.onosproject.net.PortNumber; | 50 | import org.onosproject.net.PortNumber; |
| ... | @@ -54,8 +55,11 @@ import org.onosproject.net.intent.IntentState; | ... | @@ -54,8 +55,11 @@ import org.onosproject.net.intent.IntentState; |
| 54 | import org.onosproject.net.intent.Key; | 55 | import org.onosproject.net.intent.Key; |
| 55 | import org.onosproject.net.intent.MockIdGenerator; | 56 | import org.onosproject.net.intent.MockIdGenerator; |
| 56 | import org.onosproject.net.intent.TestableIntentService; | 57 | import org.onosproject.net.intent.TestableIntentService; |
| 58 | +import org.onosproject.net.topology.Topology; | ||
| 59 | +import org.onosproject.net.topology.TopologyService; | ||
| 57 | import org.onosproject.store.service.TestStorageService; | 60 | import org.onosproject.store.service.TestStorageService; |
| 58 | 61 | ||
| 62 | +import java.util.ArrayList; | ||
| 59 | import java.util.Collection; | 63 | import java.util.Collection; |
| 60 | import java.util.List; | 64 | import java.util.List; |
| 61 | import java.util.Set; | 65 | import java.util.Set; |
| ... | @@ -72,13 +76,17 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { | ... | @@ -72,13 +76,17 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { |
| 72 | private final String tenantIdValue2 = "TENANT_ID2"; | 76 | private final String tenantIdValue2 = "TENANT_ID2"; |
| 73 | 77 | ||
| 74 | private VirtualNetworkManager manager; | 78 | private VirtualNetworkManager manager; |
| 75 | - private VirtualNetworkService virtualNetworkManagerService; | 79 | + private VirtualNetworkTopologyProvider topologyProvider; |
| 76 | private DistributedVirtualNetworkStore virtualNetworkManagerStore; | 80 | private DistributedVirtualNetworkStore virtualNetworkManagerStore; |
| 77 | private CoreService coreService; | 81 | private CoreService coreService; |
| 78 | private TestListener listener = new TestListener(); | 82 | private TestListener listener = new TestListener(); |
| 79 | private TestableIntentService intentService = new FakeIntentManager(); | 83 | private TestableIntentService intentService = new FakeIntentManager(); |
| 84 | + private TopologyService topologyService; | ||
| 80 | private IdGenerator idGenerator = new MockIdGenerator(); | 85 | private IdGenerator idGenerator = new MockIdGenerator(); |
| 81 | 86 | ||
| 87 | + private ConnectPoint cp6; | ||
| 88 | + private ConnectPoint cp7; | ||
| 89 | + | ||
| 82 | @Before | 90 | @Before |
| 83 | public void setUp() throws Exception { | 91 | public void setUp() throws Exception { |
| 84 | virtualNetworkManagerStore = new DistributedVirtualNetworkStore(); | 92 | virtualNetworkManagerStore = new DistributedVirtualNetworkStore(); |
| ... | @@ -96,7 +104,6 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { | ... | @@ -96,7 +104,6 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { |
| 96 | manager.intentService = intentService; | 104 | manager.intentService = intentService; |
| 97 | NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher()); | 105 | NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher()); |
| 98 | manager.activate(); | 106 | manager.activate(); |
| 99 | - virtualNetworkManagerService = manager; | ||
| 100 | } | 107 | } |
| 101 | 108 | ||
| 102 | @After | 109 | @After |
| ... | @@ -313,7 +320,13 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { | ... | @@ -313,7 +320,13 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { |
| 313 | VirtualDevice dstVirtualDevice = | 320 | VirtualDevice dstVirtualDevice = |
| 314 | manager.createVirtualDevice(virtualNetwork1.id(), DID2); | 321 | manager.createVirtualDevice(virtualNetwork1.id(), DID2); |
| 315 | ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1)); | 322 | ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1)); |
| 323 | + manager.createVirtualPort(virtualNetwork1.id(), src.deviceId(), src.port(), | ||
| 324 | + new DefaultPort(srcVirtualDevice, src.port(), true)); | ||
| 325 | + | ||
| 316 | ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2)); | 326 | ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2)); |
| 327 | + manager.createVirtualPort(virtualNetwork1.id(), dst.deviceId(), dst.port(), | ||
| 328 | + new DefaultPort(dstVirtualDevice, dst.port(), true)); | ||
| 329 | + | ||
| 317 | manager.createVirtualLink(virtualNetwork1.id(), src, dst); | 330 | manager.createVirtualLink(virtualNetwork1.id(), src, dst); |
| 318 | manager.createVirtualLink(virtualNetwork1.id(), dst, src); | 331 | manager.createVirtualLink(virtualNetwork1.id(), dst, src); |
| 319 | 332 | ||
| ... | @@ -348,7 +361,13 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { | ... | @@ -348,7 +361,13 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { |
| 348 | VirtualDevice dstVirtualDevice = | 361 | VirtualDevice dstVirtualDevice = |
| 349 | manager.createVirtualDevice(virtualNetwork1.id(), DID2); | 362 | manager.createVirtualDevice(virtualNetwork1.id(), DID2); |
| 350 | ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1)); | 363 | ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1)); |
| 364 | + manager.createVirtualPort(virtualNetwork1.id(), src.deviceId(), src.port(), | ||
| 365 | + new DefaultPort(srcVirtualDevice, src.port(), true)); | ||
| 366 | + | ||
| 351 | ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2)); | 367 | ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2)); |
| 368 | + manager.createVirtualPort(virtualNetwork1.id(), dst.deviceId(), dst.port(), | ||
| 369 | + new DefaultPort(dstVirtualDevice, dst.port(), true)); | ||
| 370 | + | ||
| 352 | manager.createVirtualLink(virtualNetwork1.id(), src, dst); | 371 | manager.createVirtualLink(virtualNetwork1.id(), src, dst); |
| 353 | manager.createVirtualLink(virtualNetwork1.id(), src, dst); | 372 | manager.createVirtualLink(virtualNetwork1.id(), src, dst); |
| 354 | } | 373 | } |
| ... | @@ -479,6 +498,126 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { | ... | @@ -479,6 +498,126 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { |
| 479 | assertTrue("The tunnels should be empty.", manager.store.getTunnelIds(virtualIntent).isEmpty()); | 498 | assertTrue("The tunnels should be empty.", manager.store.getTunnelIds(virtualIntent).isEmpty()); |
| 480 | } | 499 | } |
| 481 | 500 | ||
| 501 | + | ||
| 502 | + /** | ||
| 503 | + * Method to create the virtual network for further testing. | ||
| 504 | + **/ | ||
| 505 | + private VirtualNetwork setupVirtualNetworkTopology() { | ||
| 506 | + manager.registerTenantId(TenantId.tenantId(tenantIdValue1)); | ||
| 507 | + VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1)); | ||
| 508 | + | ||
| 509 | + VirtualDevice virtualDevice1 = | ||
| 510 | + manager.createVirtualDevice(virtualNetwork.id(), DID1); | ||
| 511 | + VirtualDevice virtualDevice2 = | ||
| 512 | + manager.createVirtualDevice(virtualNetwork.id(), DID2); | ||
| 513 | + VirtualDevice virtualDevice3 = | ||
| 514 | + manager.createVirtualDevice(virtualNetwork.id(), DID3); | ||
| 515 | + VirtualDevice virtualDevice4 = | ||
| 516 | + manager.createVirtualDevice(virtualNetwork.id(), DID4); | ||
| 517 | + VirtualDevice virtualDevice5 = | ||
| 518 | + manager.createVirtualDevice(virtualNetwork.id(), DID5); | ||
| 519 | + | ||
| 520 | + ConnectPoint cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1)); | ||
| 521 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), | ||
| 522 | + PortNumber.portNumber(1), | ||
| 523 | + new DefaultPort(virtualDevice1, PortNumber.portNumber(1), true)); | ||
| 524 | + | ||
| 525 | + ConnectPoint cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2)); | ||
| 526 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), | ||
| 527 | + PortNumber.portNumber(2), | ||
| 528 | + new DefaultPort(virtualDevice1, PortNumber.portNumber(2), true)); | ||
| 529 | + | ||
| 530 | + ConnectPoint cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3)); | ||
| 531 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), | ||
| 532 | + PortNumber.portNumber(3), | ||
| 533 | + new DefaultPort(virtualDevice2, PortNumber.portNumber(3), true)); | ||
| 534 | + | ||
| 535 | + ConnectPoint cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4)); | ||
| 536 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), | ||
| 537 | + PortNumber.portNumber(4), | ||
| 538 | + new DefaultPort(virtualDevice2, PortNumber.portNumber(4), true)); | ||
| 539 | + | ||
| 540 | + ConnectPoint cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5)); | ||
| 541 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), | ||
| 542 | + PortNumber.portNumber(5), | ||
| 543 | + new DefaultPort(virtualDevice3, PortNumber.portNumber(5), true)); | ||
| 544 | + | ||
| 545 | + cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6)); | ||
| 546 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), | ||
| 547 | + PortNumber.portNumber(6), | ||
| 548 | + new DefaultPort(virtualDevice3, PortNumber.portNumber(6), true)); | ||
| 549 | + | ||
| 550 | + cp7 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(7)); | ||
| 551 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(), | ||
| 552 | + PortNumber.portNumber(7), | ||
| 553 | + new DefaultPort(virtualDevice4, PortNumber.portNumber(7), true)); | ||
| 554 | + | ||
| 555 | + ConnectPoint cp8 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(8)); | ||
| 556 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(), | ||
| 557 | + PortNumber.portNumber(8), | ||
| 558 | + new DefaultPort(virtualDevice4, PortNumber.portNumber(8), true)); | ||
| 559 | + | ||
| 560 | + ConnectPoint cp9 = new ConnectPoint(virtualDevice5.id(), PortNumber.portNumber(9)); | ||
| 561 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice5.id(), | ||
| 562 | + PortNumber.portNumber(9), | ||
| 563 | + new DefaultPort(virtualDevice5, PortNumber.portNumber(9), true)); | ||
| 564 | + | ||
| 565 | + VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3); | ||
| 566 | + virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE); | ||
| 567 | + VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1); | ||
| 568 | + virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE); | ||
| 569 | + VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5); | ||
| 570 | + virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE); | ||
| 571 | + VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4); | ||
| 572 | + virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE); | ||
| 573 | + VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp8, cp9); | ||
| 574 | + virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE); | ||
| 575 | + VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp9, cp8); | ||
| 576 | + virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE); | ||
| 577 | + | ||
| 578 | + topologyService = manager.get(virtualNetwork.id(), TopologyService.class); | ||
| 579 | + topologyProvider = new VirtualNetworkTopologyProvider(); | ||
| 580 | + topologyProvider.topologyService = topologyService; | ||
| 581 | + | ||
| 582 | + return virtualNetwork; | ||
| 583 | + } | ||
| 584 | + | ||
| 585 | + /** | ||
| 586 | + * Test the topologyChanged() method. | ||
| 587 | + */ | ||
| 588 | + @Test | ||
| 589 | + public void testTopologyChanged() { | ||
| 590 | + VirtualNetwork virtualNetwork = setupVirtualNetworkTopology(); | ||
| 591 | + VirtualNetworkProviderService providerService = manager.createProviderService(topologyProvider); | ||
| 592 | + | ||
| 593 | + // Initial setup is two clusters of devices/links. | ||
| 594 | + assertEquals("The cluster count did not match.", 2, topologyService.currentTopology().clusterCount()); | ||
| 595 | + | ||
| 596 | + // Adding this link will join the two clusters together. | ||
| 597 | + List<Event> reasons = new ArrayList<>(); | ||
| 598 | + VirtualLink link = manager.createVirtualLink(virtualNetwork.id(), cp6, cp7); | ||
| 599 | + virtualNetworkManagerStore.updateLink(link, link.tunnelId(), Link.State.ACTIVE); | ||
| 600 | + VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp7, cp6); | ||
| 601 | + virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE); | ||
| 602 | + | ||
| 603 | + Topology topology = topologyService.currentTopology(); | ||
| 604 | + providerService.topologyChanged(topologyProvider.getConnectPoints(topology)); | ||
| 605 | + | ||
| 606 | + // Validate that all links are still active. | ||
| 607 | + manager.getVirtualLinks(virtualNetwork.id()).forEach(virtualLink -> { | ||
| 608 | + assertTrue("The virtual link should be active.", virtualLink.state().equals(Link.State.ACTIVE)); | ||
| 609 | + }); | ||
| 610 | + | ||
| 611 | + virtualNetworkManagerStore.updateLink(link, link.tunnelId(), Link.State.INACTIVE); | ||
| 612 | + virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.INACTIVE); | ||
| 613 | + providerService.topologyChanged(topologyProvider.getConnectPoints(topology)); | ||
| 614 | + | ||
| 615 | + // Validate that all links are active again. | ||
| 616 | + manager.getVirtualLinks(virtualNetwork.id()).forEach(virtualLink -> { | ||
| 617 | + assertTrue("The virtual link should be active.", virtualLink.state().equals(Link.State.ACTIVE)); | ||
| 618 | + }); | ||
| 619 | + } | ||
| 620 | + | ||
| 482 | /** | 621 | /** |
| 483 | * Method to validate that the actual versus expected virtual network events were | 622 | * Method to validate that the actual versus expected virtual network events were |
| 484 | * received correctly. | 623 | * received correctly. | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2016-present 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 org.junit.After; | ||
| 20 | +import org.junit.Before; | ||
| 21 | +import org.junit.Test; | ||
| 22 | +import org.onlab.junit.TestUtils; | ||
| 23 | +import org.onosproject.common.event.impl.TestEventDispatcher; | ||
| 24 | +import org.onosproject.core.CoreService; | ||
| 25 | +import org.onosproject.core.CoreServiceAdapter; | ||
| 26 | +import org.onosproject.core.IdGenerator; | ||
| 27 | +import org.onosproject.event.Event; | ||
| 28 | +import org.onosproject.incubator.net.tunnel.TunnelId; | ||
| 29 | +import org.onosproject.incubator.net.virtual.NetworkId; | ||
| 30 | +import org.onosproject.incubator.net.virtual.TenantId; | ||
| 31 | +import org.onosproject.incubator.net.virtual.VirtualDevice; | ||
| 32 | +import org.onosproject.incubator.net.virtual.VirtualLink; | ||
| 33 | +import org.onosproject.incubator.net.virtual.VirtualNetwork; | ||
| 34 | +import org.onosproject.incubator.net.virtual.VirtualNetworkProvider; | ||
| 35 | +import org.onosproject.incubator.net.virtual.VirtualNetworkProviderRegistry; | ||
| 36 | +import org.onosproject.incubator.net.virtual.VirtualNetworkProviderService; | ||
| 37 | +import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore; | ||
| 38 | +import org.onosproject.net.ConnectPoint; | ||
| 39 | +import org.onosproject.net.DefaultPort; | ||
| 40 | +import org.onosproject.net.Link; | ||
| 41 | +import org.onosproject.net.NetTestTools; | ||
| 42 | +import org.onosproject.net.PortNumber; | ||
| 43 | +import org.onosproject.net.TestDeviceParams; | ||
| 44 | +import org.onosproject.net.intent.FakeIntentManager; | ||
| 45 | +import org.onosproject.net.intent.TestableIntentService; | ||
| 46 | +import org.onosproject.net.link.LinkEvent; | ||
| 47 | +import org.onosproject.net.provider.AbstractProviderService; | ||
| 48 | +import org.onosproject.net.provider.ProviderId; | ||
| 49 | +import org.onosproject.net.topology.TopologyEvent; | ||
| 50 | +import org.onosproject.net.topology.TopologyService; | ||
| 51 | +import org.onosproject.store.service.TestStorageService; | ||
| 52 | + | ||
| 53 | +import java.util.ArrayList; | ||
| 54 | +import java.util.List; | ||
| 55 | +import java.util.Set; | ||
| 56 | +import java.util.concurrent.Semaphore; | ||
| 57 | +import java.util.concurrent.TimeUnit; | ||
| 58 | +import java.util.concurrent.atomic.AtomicLong; | ||
| 59 | + | ||
| 60 | +import static org.junit.Assert.*; | ||
| 61 | + | ||
| 62 | +/** | ||
| 63 | + * Junit tests for VirtualNetworkTopologyProvider. | ||
| 64 | + */ | ||
| 65 | +public class VirtualNetworkTopologyProviderTest extends TestDeviceParams { | ||
| 66 | + | ||
| 67 | + private final String tenantIdValue1 = "TENANT_ID1"; | ||
| 68 | + | ||
| 69 | + private VirtualNetwork virtualNetwork; | ||
| 70 | + private VirtualDevice virtualDevice1; | ||
| 71 | + private VirtualDevice virtualDevice2; | ||
| 72 | + private VirtualDevice virtualDevice3; | ||
| 73 | + private VirtualDevice virtualDevice4; | ||
| 74 | + private VirtualDevice virtualDevice5; | ||
| 75 | + private ConnectPoint cp1; | ||
| 76 | + private ConnectPoint cp2; | ||
| 77 | + private ConnectPoint cp3; | ||
| 78 | + private ConnectPoint cp4; | ||
| 79 | + private ConnectPoint cp5; | ||
| 80 | + private ConnectPoint cp6; | ||
| 81 | + private ConnectPoint cp7; | ||
| 82 | + private ConnectPoint cp8; | ||
| 83 | + private ConnectPoint cp9; | ||
| 84 | + | ||
| 85 | + private VirtualNetworkManager manager; | ||
| 86 | + private DistributedVirtualNetworkStore virtualNetworkManagerStore; | ||
| 87 | + private CoreService coreService; | ||
| 88 | + private VirtualNetworkTopologyProvider topologyProvider; | ||
| 89 | + private TopologyService topologyService; | ||
| 90 | + private TestableIntentService intentService = new FakeIntentManager(); | ||
| 91 | + private final VirtualNetworkRegistryAdapter virtualNetworkRegistry = new VirtualNetworkRegistryAdapter(); | ||
| 92 | + | ||
| 93 | + private static final int MAX_WAIT_TIME = 5; | ||
| 94 | + private static final int MAX_PERMITS = 1; | ||
| 95 | + private static Semaphore changed; | ||
| 96 | + | ||
| 97 | + private Set<Set<ConnectPoint>> clusters; | ||
| 98 | + | ||
| 99 | + @Before | ||
| 100 | + public void setUp() throws Exception { | ||
| 101 | + | ||
| 102 | + virtualNetworkManagerStore = new DistributedVirtualNetworkStore(); | ||
| 103 | + | ||
| 104 | + coreService = new VirtualNetworkTopologyProviderTest.TestCoreService(); | ||
| 105 | + | ||
| 106 | + virtualNetworkManagerStore.setCoreService(coreService); | ||
| 107 | + TestUtils.setField(coreService, "coreService", new VirtualNetworkTopologyProviderTest.TestCoreService()); | ||
| 108 | + TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService()); | ||
| 109 | + virtualNetworkManagerStore.activate(); | ||
| 110 | + | ||
| 111 | + manager = new VirtualNetworkManager(); | ||
| 112 | + manager.store = virtualNetworkManagerStore; | ||
| 113 | + manager.intentService = intentService; | ||
| 114 | + NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher()); | ||
| 115 | + manager.activate(); | ||
| 116 | + | ||
| 117 | + manager.registerTenantId(TenantId.tenantId(tenantIdValue1)); | ||
| 118 | + virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1)); | ||
| 119 | + | ||
| 120 | + topologyService = manager.get(virtualNetwork.id(), TopologyService.class); | ||
| 121 | + topologyProvider = new VirtualNetworkTopologyProvider(); | ||
| 122 | + topologyProvider.topologyService = topologyService; | ||
| 123 | + topologyProvider.providerRegistry = virtualNetworkRegistry; | ||
| 124 | + topologyProvider.activate(); | ||
| 125 | + | ||
| 126 | + setupVirtualNetworkTopology(); | ||
| 127 | + changed = new Semaphore(0, true); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + @After | ||
| 131 | + public void tearDown() { | ||
| 132 | + topologyProvider.deactivate(); | ||
| 133 | + virtualNetworkManagerStore.deactivate(); | ||
| 134 | + manager.deactivate(); | ||
| 135 | + NetTestTools.injectEventDispatcher(manager, null); | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + /** | ||
| 139 | + * Method to create the virtual network for further testing. | ||
| 140 | + **/ | ||
| 141 | + private void setupVirtualNetworkTopology() { | ||
| 142 | + virtualDevice1 = | ||
| 143 | + manager.createVirtualDevice(virtualNetwork.id(), DID1); | ||
| 144 | + virtualDevice2 = | ||
| 145 | + manager.createVirtualDevice(virtualNetwork.id(), DID2); | ||
| 146 | + virtualDevice3 = | ||
| 147 | + manager.createVirtualDevice(virtualNetwork.id(), DID3); | ||
| 148 | + virtualDevice4 = | ||
| 149 | + manager.createVirtualDevice(virtualNetwork.id(), DID4); | ||
| 150 | + virtualDevice5 = | ||
| 151 | + manager.createVirtualDevice(virtualNetwork.id(), DID5); | ||
| 152 | + | ||
| 153 | + cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1)); | ||
| 154 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), | ||
| 155 | + PortNumber.portNumber(1), | ||
| 156 | + new DefaultPort(virtualDevice1, PortNumber.portNumber(1), true)); | ||
| 157 | + | ||
| 158 | + cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2)); | ||
| 159 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), | ||
| 160 | + PortNumber.portNumber(2), | ||
| 161 | + new DefaultPort(virtualDevice1, PortNumber.portNumber(2), true)); | ||
| 162 | + | ||
| 163 | + cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3)); | ||
| 164 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), | ||
| 165 | + PortNumber.portNumber(3), | ||
| 166 | + new DefaultPort(virtualDevice2, PortNumber.portNumber(3), true)); | ||
| 167 | + | ||
| 168 | + cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4)); | ||
| 169 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), | ||
| 170 | + PortNumber.portNumber(4), | ||
| 171 | + new DefaultPort(virtualDevice2, PortNumber.portNumber(4), true)); | ||
| 172 | + | ||
| 173 | + cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5)); | ||
| 174 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), | ||
| 175 | + PortNumber.portNumber(5), | ||
| 176 | + new DefaultPort(virtualDevice3, PortNumber.portNumber(5), true)); | ||
| 177 | + | ||
| 178 | + cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6)); | ||
| 179 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), | ||
| 180 | + PortNumber.portNumber(6), | ||
| 181 | + new DefaultPort(virtualDevice3, PortNumber.portNumber(6), true)); | ||
| 182 | + | ||
| 183 | + cp7 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(7)); | ||
| 184 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(), | ||
| 185 | + PortNumber.portNumber(7), | ||
| 186 | + new DefaultPort(virtualDevice4, PortNumber.portNumber(7), true)); | ||
| 187 | + | ||
| 188 | + cp8 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(8)); | ||
| 189 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(), | ||
| 190 | + PortNumber.portNumber(8), | ||
| 191 | + new DefaultPort(virtualDevice4, PortNumber.portNumber(8), true)); | ||
| 192 | + | ||
| 193 | + cp9 = new ConnectPoint(virtualDevice5.id(), PortNumber.portNumber(9)); | ||
| 194 | + manager.createVirtualPort(virtualNetwork.id(), virtualDevice5.id(), | ||
| 195 | + PortNumber.portNumber(9), | ||
| 196 | + new DefaultPort(virtualDevice5, PortNumber.portNumber(9), true)); | ||
| 197 | + | ||
| 198 | + VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3); | ||
| 199 | + virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE); | ||
| 200 | + VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1); | ||
| 201 | + virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE); | ||
| 202 | + VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5); | ||
| 203 | + virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE); | ||
| 204 | + VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4); | ||
| 205 | + virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE); | ||
| 206 | + VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp8, cp9); | ||
| 207 | + virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE); | ||
| 208 | + VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp9, cp8); | ||
| 209 | + virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE); | ||
| 210 | + | ||
| 211 | + clusters = null; | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + /** | ||
| 215 | + * Test isTraversable() method using a null source connect point. | ||
| 216 | + */ | ||
| 217 | + @Test(expected = NullPointerException.class) | ||
| 218 | + public void testIsTraversableNullSrc() { | ||
| 219 | + // test the isTraversable() method with a null source connect point. | ||
| 220 | + topologyProvider.isTraversable(null, cp3); | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + /** | ||
| 224 | + * Test isTraversable() method using a null destination connect point. | ||
| 225 | + */ | ||
| 226 | + @Test(expected = NullPointerException.class) | ||
| 227 | + public void testIsTraversableNullDst() { | ||
| 228 | + // test the isTraversable() method with a null destination connect point. | ||
| 229 | + topologyProvider.isTraversable(cp1, null); | ||
| 230 | + } | ||
| 231 | + | ||
| 232 | + /** | ||
| 233 | + * Test isTraversable() method. | ||
| 234 | + */ | ||
| 235 | + @Test | ||
| 236 | + public void testIsTraversable() { | ||
| 237 | + // test the isTraversable() method. | ||
| 238 | + assertTrue("These two connect points should be traversable.", | ||
| 239 | + topologyProvider.isTraversable(new ConnectPoint(cp1.elementId(), cp1.port()), | ||
| 240 | + new ConnectPoint(cp3.elementId(), cp3.port()))); | ||
| 241 | + assertTrue("These two connect points should be traversable.", | ||
| 242 | + topologyProvider.isTraversable(new ConnectPoint(cp1.elementId(), cp1.port()), | ||
| 243 | + new ConnectPoint(cp5.elementId(), cp5.port()))); | ||
| 244 | + assertFalse("These two connect points should not be traversable.", | ||
| 245 | + topologyProvider.isTraversable(new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1)), | ||
| 246 | + new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(6)))); | ||
| 247 | + } | ||
| 248 | + | ||
| 249 | + /** | ||
| 250 | + * Test the topologyChanged() method. | ||
| 251 | + */ | ||
| 252 | + @Test | ||
| 253 | + public void testTopologyChanged() { | ||
| 254 | + // Initial setup is two clusters of devices/links. | ||
| 255 | + assertEquals("The cluster count did not match.", 2, topologyService.currentTopology().clusterCount()); | ||
| 256 | + | ||
| 257 | + // Adding this link will join the two clusters together. | ||
| 258 | + List<Event> reasons = new ArrayList<>(); | ||
| 259 | + VirtualLink link = manager.createVirtualLink(virtualNetwork.id(), cp6, cp7); | ||
| 260 | + virtualNetworkManagerStore.updateLink(link, link.tunnelId(), Link.State.ACTIVE); | ||
| 261 | + VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp7, cp6); | ||
| 262 | + virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE); | ||
| 263 | + | ||
| 264 | + reasons.add(new LinkEvent(LinkEvent.Type.LINK_ADDED, link)); | ||
| 265 | + reasons.add(new LinkEvent(LinkEvent.Type.LINK_ADDED, link2)); | ||
| 266 | + TopologyEvent event = new TopologyEvent( | ||
| 267 | + TopologyEvent.Type.TOPOLOGY_CHANGED, | ||
| 268 | + topologyService.currentTopology(), | ||
| 269 | + reasons); | ||
| 270 | + | ||
| 271 | + topologyProvider.topologyListener.event(event); | ||
| 272 | + | ||
| 273 | + // Wait for the topology changed event, and that the topologyChanged method was called. | ||
| 274 | + try { | ||
| 275 | + if (!changed.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) { | ||
| 276 | + fail("Failed to wait for topology changed event."); | ||
| 277 | + } | ||
| 278 | + } catch (InterruptedException e) { | ||
| 279 | + fail("Semaphore exception." + e.getMessage()); | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + // Validate that the topology changed method received a single cluster of connect points. | ||
| 283 | + // This means that the two previous clusters have now joined into a single cluster. | ||
| 284 | + assertEquals("The cluster count did not match.", 1, this.clusters.size()); | ||
| 285 | + assertEquals("The cluster count did not match.", 1, topologyService.currentTopology().clusterCount()); | ||
| 286 | + | ||
| 287 | + // Now remove the virtual link to split it back into two clusters. | ||
| 288 | + manager.removeVirtualLink(virtualNetwork.id(), link.src(), link.dst()); | ||
| 289 | + manager.removeVirtualLink(virtualNetwork.id(), link2.src(), link2.dst()); | ||
| 290 | + assertEquals("The cluster count did not match.", 2, topologyService.currentTopology().clusterCount()); | ||
| 291 | + | ||
| 292 | + reasons = new ArrayList<>(); | ||
| 293 | + reasons.add(new LinkEvent(LinkEvent.Type.LINK_REMOVED, link)); | ||
| 294 | + reasons.add(new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2)); | ||
| 295 | + event = new TopologyEvent( | ||
| 296 | + TopologyEvent.Type.TOPOLOGY_CHANGED, | ||
| 297 | + topologyService.currentTopology(), | ||
| 298 | + reasons); | ||
| 299 | + | ||
| 300 | + topologyProvider.topologyListener.event(event); | ||
| 301 | + | ||
| 302 | + // Wait for the topology changed event, and that the topologyChanged method was called. | ||
| 303 | + try { | ||
| 304 | + if (!changed.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) { | ||
| 305 | + fail("Failed to wait for topology changed event."); | ||
| 306 | + } | ||
| 307 | + } catch (InterruptedException e) { | ||
| 308 | + fail("Semaphore exception." + e.getMessage()); | ||
| 309 | + } | ||
| 310 | + | ||
| 311 | + // Validate that the topology changed method received two clusters of connect points. | ||
| 312 | + // This means that the single previous clusters has now split into two clusters. | ||
| 313 | + assertEquals("The cluster count did not match.", 2, this.clusters.size()); | ||
| 314 | + } | ||
| 315 | + | ||
| 316 | + /** | ||
| 317 | + * Virtual network registry implementation for this test class. | ||
| 318 | + */ | ||
| 319 | + private class VirtualNetworkRegistryAdapter implements VirtualNetworkProviderRegistry { | ||
| 320 | + private VirtualNetworkProvider provider; | ||
| 321 | + | ||
| 322 | + @Override | ||
| 323 | + public VirtualNetworkProviderService register(VirtualNetworkProvider theProvider) { | ||
| 324 | + this.provider = theProvider; | ||
| 325 | + return new TestVirtualNetworkProviderService(theProvider); | ||
| 326 | + } | ||
| 327 | + | ||
| 328 | + @Override | ||
| 329 | + public void unregister(VirtualNetworkProvider theProvider) { | ||
| 330 | + this.provider = null; | ||
| 331 | + } | ||
| 332 | + | ||
| 333 | + @Override | ||
| 334 | + public Set<ProviderId> getProviders() { | ||
| 335 | + return null; | ||
| 336 | + } | ||
| 337 | + } | ||
| 338 | + | ||
| 339 | + | ||
| 340 | + /** | ||
| 341 | + * Virtual network provider service implementation for this test class. | ||
| 342 | + */ | ||
| 343 | + private class TestVirtualNetworkProviderService | ||
| 344 | + extends AbstractProviderService<VirtualNetworkProvider> | ||
| 345 | + implements VirtualNetworkProviderService { | ||
| 346 | + | ||
| 347 | + /** | ||
| 348 | + * Constructor. | ||
| 349 | + * | ||
| 350 | + * @param provider virtual network test provider | ||
| 351 | + */ | ||
| 352 | + protected TestVirtualNetworkProviderService(VirtualNetworkProvider provider) { | ||
| 353 | + super(provider); | ||
| 354 | + } | ||
| 355 | + | ||
| 356 | + @Override | ||
| 357 | + public void topologyChanged(Set<Set<ConnectPoint>> theClusters) { | ||
| 358 | + clusters = theClusters; | ||
| 359 | + changed.release(); | ||
| 360 | + } | ||
| 361 | + | ||
| 362 | + @Override | ||
| 363 | + public void tunnelUp(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) { | ||
| 364 | + } | ||
| 365 | + | ||
| 366 | + @Override | ||
| 367 | + public void tunnelDown(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) { | ||
| 368 | + } | ||
| 369 | + } | ||
| 370 | + | ||
| 371 | + /** | ||
| 372 | + * Core service test class. | ||
| 373 | + */ | ||
| 374 | + private class TestCoreService extends CoreServiceAdapter { | ||
| 375 | + | ||
| 376 | + @Override | ||
| 377 | + public IdGenerator getIdGenerator(String topic) { | ||
| 378 | + return new IdGenerator() { | ||
| 379 | + private AtomicLong counter = new AtomicLong(0); | ||
| 380 | + | ||
| 381 | + @Override | ||
| 382 | + public long getNewId() { | ||
| 383 | + return counter.getAndIncrement(); | ||
| 384 | + } | ||
| 385 | + }; | ||
| 386 | + } | ||
| 387 | + } | ||
| 388 | +} |
| ... | @@ -31,6 +31,7 @@ import org.onosproject.incubator.net.virtual.VirtualLink; | ... | @@ -31,6 +31,7 @@ import org.onosproject.incubator.net.virtual.VirtualLink; |
| 31 | import org.onosproject.incubator.net.virtual.VirtualNetwork; | 31 | import org.onosproject.incubator.net.virtual.VirtualNetwork; |
| 32 | import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore; | 32 | import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore; |
| 33 | import org.onosproject.net.ConnectPoint; | 33 | import org.onosproject.net.ConnectPoint; |
| 34 | +import org.onosproject.net.DefaultPort; | ||
| 34 | import org.onosproject.net.DeviceId; | 35 | import org.onosproject.net.DeviceId; |
| 35 | import org.onosproject.net.DisjointPath; | 36 | import org.onosproject.net.DisjointPath; |
| 36 | import org.onosproject.net.Link; | 37 | import org.onosproject.net.Link; |
| ... | @@ -108,11 +109,29 @@ public class VirtualNetworkTopologyServiceTest extends TestDeviceParams { | ... | @@ -108,11 +109,29 @@ public class VirtualNetworkTopologyServiceTest extends TestDeviceParams { |
| 108 | manager.createVirtualDevice(virtualNetwork.id(), DID4); | 109 | manager.createVirtualDevice(virtualNetwork.id(), DID4); |
| 109 | 110 | ||
| 110 | ConnectPoint cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1)); | 111 | ConnectPoint cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1)); |
| 112 | + manager.createVirtualPort(virtualNetwork.id(), cp1.deviceId(), cp1.port(), | ||
| 113 | + new DefaultPort(virtualDevice1, cp1.port(), true)); | ||
| 114 | + | ||
| 111 | ConnectPoint cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2)); | 115 | ConnectPoint cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2)); |
| 116 | + manager.createVirtualPort(virtualNetwork.id(), cp2.deviceId(), cp2.port(), | ||
| 117 | + new DefaultPort(virtualDevice1, cp2.port(), true)); | ||
| 118 | + | ||
| 112 | ConnectPoint cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3)); | 119 | ConnectPoint cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3)); |
| 120 | + manager.createVirtualPort(virtualNetwork.id(), cp3.deviceId(), cp3.port(), | ||
| 121 | + new DefaultPort(virtualDevice2, cp3.port(), true)); | ||
| 122 | + | ||
| 113 | ConnectPoint cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4)); | 123 | ConnectPoint cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4)); |
| 124 | + manager.createVirtualPort(virtualNetwork.id(), cp4.deviceId(), cp4.port(), | ||
| 125 | + new DefaultPort(virtualDevice2, cp4.port(), true)); | ||
| 126 | + | ||
| 114 | ConnectPoint cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5)); | 127 | ConnectPoint cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5)); |
| 128 | + manager.createVirtualPort(virtualNetwork.id(), cp5.deviceId(), cp5.port(), | ||
| 129 | + new DefaultPort(virtualDevice3, cp5.port(), true)); | ||
| 130 | + | ||
| 115 | ConnectPoint cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6)); | 131 | ConnectPoint cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6)); |
| 132 | + manager.createVirtualPort(virtualNetwork.id(), cp6.deviceId(), cp6.port(), | ||
| 133 | + new DefaultPort(virtualDevice3, cp6.port(), true)); | ||
| 134 | + | ||
| 116 | VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3); | 135 | VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3); |
| 117 | virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE); | 136 | virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE); |
| 118 | VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1); | 137 | VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1); |
| ... | @@ -177,7 +196,12 @@ public class VirtualNetworkTopologyServiceTest extends TestDeviceParams { | ... | @@ -177,7 +196,12 @@ public class VirtualNetworkTopologyServiceTest extends TestDeviceParams { |
| 177 | 196 | ||
| 178 | topology = topologyService.currentTopology(); | 197 | topology = topologyService.currentTopology(); |
| 179 | ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1)); | 198 | ConnectPoint src = new ConnectPoint(srcVirtualDevice.id(), PortNumber.portNumber(1)); |
| 199 | + manager.createVirtualPort(virtualNetwork.id(), src.deviceId(), src.port(), | ||
| 200 | + new DefaultPort(srcVirtualDevice, src.port(), true)); | ||
| 201 | + | ||
| 180 | ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2)); | 202 | ConnectPoint dst = new ConnectPoint(dstVirtualDevice.id(), PortNumber.portNumber(2)); |
| 203 | + manager.createVirtualPort(virtualNetwork.id(), dst.deviceId(), dst.port(), | ||
| 204 | + new DefaultPort(dstVirtualDevice, dst.port(), true)); | ||
| 181 | VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), src, dst); | 205 | VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), src, dst); |
| 182 | 206 | ||
| 183 | // test the isLatest() method where a new link has been added to the current topology. | 207 | // test the isLatest() method where a new link has been added to the current topology. | ... | ... |
-
Please register or login to post a comment