Detangling incubator: virtual nets, tunnels, resource labels, oh my
- virtual networking moved to /apps/virtual; with CLI & REST API
- tunnels and labels moved to /apps/tunnel; with CLI & REST API; UI disabled for now
- protobuf/models moved to /core/protobuf/models
- defunct grpc/rpc registry stuff left under /graveyard
- compile dependencies on /incubator moved to respective modules for compilation
- run-time dependencies will need to be re-tested for dependent apps
- /graveyard will be removed in not-too-distant future
Change-Id: I0a0b995c635487edcf95a352f50dd162186b0b39
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java
new file mode 100644
index 0000000..8e11e6f
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.virtual.impl.provider;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.graph.ScalarWeight;
+import org.onlab.graph.Weight;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
+import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
+import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminServiceAdapter;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DefaultPath;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleServiceAdapter;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.topology.LinkWeigher;
+import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyServiceAdapter;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+
+public class DefaultVirtualFlowRuleProviderTest {
+ private static final ProviderId PID = new ProviderId("of", "foo");
+
+ private static final DeviceId DID1 = DeviceId.deviceId("of:001");
+ private static final DeviceId DID2 = DeviceId.deviceId("of:002");
+ private static final PortNumber PORT_NUM1 = PortNumber.portNumber(1);
+ private static final PortNumber PORT_NUM2 = PortNumber.portNumber(2);
+
+ private static final DefaultAnnotations ANNOTATIONS =
+ DefaultAnnotations.builder().set("foo", "bar").build();
+
+ private static final Device DEV1 =
+ new DefaultDevice(PID, DID1, Device.Type.SWITCH, "", "", "", "", null);
+ private static final Device DEV2 =
+ new DefaultDevice(PID, DID2, Device.Type.SWITCH, "", "", "", "", null);
+ private static final Port PORT11 =
+ new DefaultPort(DEV1, PORT_NUM1, true, ANNOTATIONS);
+ private static final Port PORT12 =
+ new DefaultPort(DEV1, PORT_NUM2, true, ANNOTATIONS);
+ private static final Port PORT21 =
+ new DefaultPort(DEV2, PORT_NUM1, true, ANNOTATIONS);
+ private static final Port PORT22 =
+ new DefaultPort(DEV2, PORT_NUM2, true, ANNOTATIONS);
+
+ private static final ConnectPoint CP11 = new ConnectPoint(DID1, PORT_NUM1);
+ private static final ConnectPoint CP12 = new ConnectPoint(DID1, PORT_NUM2);
+ private static final ConnectPoint CP21 = new ConnectPoint(DID2, PORT_NUM1);
+ private static final ConnectPoint CP22 = new ConnectPoint(DID2, PORT_NUM2);
+ private static final Link LINK1 = DefaultLink.builder()
+ .src(CP12).dst(CP21).providerId(PID).type(Link.Type.DIRECT).build();
+
+ private static final NetworkId VNET_ID = NetworkId.networkId(1);
+ private static final DeviceId VDID = DeviceId.deviceId("of:100");
+
+ private static final VirtualNetwork VNET = new DefaultVirtualNetwork(
+ VNET_ID, TenantId.tenantId("t1"));
+ private static final VirtualDevice VDEV =
+ new DefaultVirtualDevice(VNET_ID, VDID);
+ private static final VirtualPort VPORT1 =
+ new DefaultVirtualPort(VNET_ID, VDEV, PORT_NUM1, CP11);
+ private static final VirtualPort VPORT2 =
+ new DefaultVirtualPort(VNET_ID, VDEV, PORT_NUM2, CP22);
+
+ private static final int TIMEOUT = 10;
+
+ protected DefaultVirtualFlowRuleProvider virtualProvider;
+
+ private ApplicationId vAppId;
+
+ @Before
+ public void setUp() {
+ virtualProvider = new DefaultVirtualFlowRuleProvider();
+
+ virtualProvider.deviceService = new TestDeviceService();
+ virtualProvider.coreService = new TestCoreService();
+ virtualProvider.vnService =
+ new TestVirtualNetworkAdminService();
+ virtualProvider.topologyService = new TestTopologyService();
+ virtualProvider.flowRuleService = new TestFlowRuleService();
+ virtualProvider.providerRegistryService = new VirtualProviderManager();
+
+ virtualProvider.activate();
+ vAppId = new TestApplicationId(0, "Virtual App");
+ }
+
+ @After
+ public void tearDown() {
+ virtualProvider.deactivate();
+ virtualProvider.deviceService = null;
+ virtualProvider.coreService = null;
+ }
+
+ @Test
+ public void devirtualizeFlowRuleWithInPort() {
+ TrafficSelector ts = DefaultTrafficSelector.builder()
+ .matchInPort(PORT_NUM1).build();
+ TrafficTreatment tr = DefaultTrafficTreatment.builder()
+ .setOutput(PORT_NUM2).build();
+
+ FlowRule r1 = DefaultFlowRule.builder()
+ .forDevice(VDID)
+ .withSelector(ts)
+ .withTreatment(tr)
+ .withPriority(10)
+ .fromApp(vAppId)
+ .makeTemporary(TIMEOUT)
+ .build();
+
+ virtualProvider.applyFlowRule(VNET_ID, r1);
+
+ assertEquals("2 rules should exist", 2,
+ virtualProvider.flowRuleService.getFlowRuleCount());
+
+ Set<FlowEntry> phyRules = new HashSet<>();
+ for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID1)) {
+ phyRules.add(i);
+ }
+ for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID2)) {
+ phyRules.add(i);
+ }
+
+ FlowRule in = null;
+ FlowRule out = null;
+
+ for (FlowRule rule : phyRules) {
+
+ L2ModificationInstruction i = (L2ModificationInstruction)
+ rule.treatment().allInstructions().get(0);
+
+ if (i.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
+ in = rule;
+ } else {
+ out = rule;
+ }
+
+ }
+
+ assertEquals(DID1, in.deviceId());
+ assertEquals(DID2, out.deviceId());
+ }
+
+ @Test
+ public void devirtualizeFlowRuleWithoutInPort() {
+ TrafficSelector ts = DefaultTrafficSelector.builder().build();
+ TrafficTreatment tr = DefaultTrafficTreatment.builder()
+ .setOutput(PORT_NUM2).build();
+
+ FlowRule r1 = DefaultFlowRule.builder()
+ .forDevice(VDID)
+ .withSelector(ts)
+ .withTreatment(tr)
+ .withPriority(10)
+ .fromApp(vAppId)
+ .makeTemporary(TIMEOUT)
+ .build();
+
+ virtualProvider.applyFlowRule(VNET_ID, r1);
+
+ assertEquals("3 rules should exist", 3,
+ virtualProvider.flowRuleService.getFlowRuleCount());
+
+ FlowRule inFromDID1 = null;
+ FlowRule inFromDID2 = null;
+ FlowRule out = null;
+
+ Set<FlowEntry> phyRules = new HashSet<>();
+ for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID1)) {
+ phyRules.add(i);
+ }
+ for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID2)) {
+ phyRules.add(i);
+ }
+
+ for (FlowRule rule : phyRules) {
+ for (Instruction inst : rule.treatment().allInstructions()) {
+ if (inst.type() == Instruction.Type.L2MODIFICATION) {
+ L2ModificationInstruction i = (L2ModificationInstruction) inst;
+ if (i.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
+ inFromDID1 = rule;
+ break;
+ } else {
+ out = rule;
+ break;
+ }
+ } else {
+ inFromDID2 = rule;
+ break;
+ }
+ }
+ }
+
+ assertEquals(DID1, inFromDID1.deviceId());
+ assertEquals(DID2, inFromDID2.deviceId());
+ assertEquals(DID2, out.deviceId());
+ }
+
+ @Test
+ public void removeVirtualizeFlowRule() {
+ TrafficSelector ts = DefaultTrafficSelector.builder().build();
+ TrafficTreatment tr = DefaultTrafficTreatment.builder()
+ .setOutput(PORT_NUM2).build();
+
+ FlowRule r1 = DefaultFlowRule.builder()
+ .forDevice(VDID)
+ .withSelector(ts)
+ .withTreatment(tr)
+ .withPriority(10)
+ .fromApp(vAppId)
+ .makeTemporary(TIMEOUT)
+ .build();
+
+ virtualProvider.removeFlowRule(VNET_ID, r1);
+
+ assertEquals("0 rules should exist", 0,
+ virtualProvider.flowRuleService.getFlowRuleCount());
+ }
+
+
+ private static class TestDeviceService extends DeviceServiceAdapter {
+ @Override
+ public int getDeviceCount() {
+ return 2;
+ }
+
+ @Override
+ public Iterable<Device> getDevices() {
+ return ImmutableList.of(DEV1, DEV2);
+ }
+
+ @Override
+ public Iterable<Device> getAvailableDevices() {
+ return getDevices();
+ }
+
+ @Override
+ public Device getDevice(DeviceId deviceId) {
+ return deviceId.equals(DID2) ? DEV2 : DEV1;
+ }
+ }
+
+ private static class TestCoreService extends CoreServiceAdapter {
+
+ @Override
+ public ApplicationId registerApplication(String name) {
+ return new TestApplicationId(1, name);
+ }
+ }
+
+ private static class TestApplicationId extends DefaultApplicationId {
+ public TestApplicationId(int id, String name) {
+ super(id, name);
+ }
+ }
+
+ private class TestVirtualNetworkAdminService
+ extends VirtualNetworkAdminServiceAdapter {
+
+ @Override
+ public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
+ return ImmutableSet.of(VDEV);
+ }
+
+ @Override
+ public Set<VirtualLink> getVirtualLinks(NetworkId networkId) {
+ return new HashSet<>();
+ }
+
+ @Override
+ public Set<VirtualPort> getVirtualPorts(NetworkId networkId,
+ DeviceId deviceId) {
+ return ImmutableSet.of(VPORT1, VPORT2);
+ }
+
+ @Override
+ public ApplicationId getVirtualNetworkApplicationId(NetworkId networkId) {
+ return vAppId;
+ }
+ }
+
+ private static class TestTopologyService extends TopologyServiceAdapter {
+
+ Weight oneHundred = ScalarWeight.toWeight(100);
+ @Override
+ public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst) {
+ DefaultPath path = new DefaultPath(PID, ImmutableList.of(LINK1),
+ oneHundred, ANNOTATIONS);
+ return ImmutableSet.of(path);
+ }
+
+ @Override
+ public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst,
+ LinkWeigher weigher) {
+ DefaultPath path = new DefaultPath(PID, ImmutableList.of(LINK1),
+ oneHundred, ANNOTATIONS);
+ return ImmutableSet.of(path);
+ }
+
+ }
+
+ private static class TestFlowRuleService extends FlowRuleServiceAdapter {
+ static Set<FlowRule> ruleCollection = new HashSet<>();
+
+ @Override
+ public int getFlowRuleCount() {
+ return ruleCollection.size();
+ }
+
+ @Override
+ public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
+ return ruleCollection.stream()
+ .filter(r -> r.deviceId().equals(deviceId))
+ .map(DefaultFlowEntry::new)
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public void applyFlowRules(FlowRule... flowRules) {
+ ruleCollection.addAll(Arrays.asList(flowRules));
+ }
+
+ @Override
+ public void removeFlowRules(FlowRule... flowRules) {
+ Set<FlowRule> candidates = new HashSet<>();
+ for (FlowRule rule : flowRules) {
+ ruleCollection.stream()
+ .filter(r -> r.exactMatch(rule))
+ .forEach(candidates::add);
+ }
+ ruleCollection.removeAll(candidates);
+ }
+ }
+}