(vCord) Add a convenience method for providing a list of physical device

Change-Id: Ibc33ced05ee15a068e06c531240fa5cb6af16e38
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java
index 07775dd..06d164c 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java
@@ -21,8 +21,11 @@
 import org.onosproject.event.ListenerService;
 import org.onosproject.net.DeviceId;
 
+import java.util.HashSet;
 import java.util.Set;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 /**
  * Service for querying virtual network inventory.
  */
@@ -85,6 +88,32 @@
     Set<VirtualPort> getVirtualPorts(NetworkId networkId, DeviceId deviceId);
 
     /**
+     * Returns list of physical device identifier mapping with the virtual
+     * device in the specified network. The physical devices are specified by
+     * port mapping mechanism.
+     *
+     * @param networkId network identifier
+     * @param virtualDevice the virtual device
+     * @return collection of the specified device's identifier
+     */
+    default Set<DeviceId> getPhysicalDevices(NetworkId networkId,
+                                             VirtualDevice virtualDevice) {
+        checkNotNull(networkId, "Network ID cannot be null");
+        checkNotNull(virtualDevice, "Virtual device cannot be null");
+        Set<VirtualPort> virtualPortSet =
+                getVirtualPorts(networkId, virtualDevice.id());
+        Set<DeviceId> physicalDeviceSet = new HashSet<>();
+
+        virtualPortSet.forEach(virtualPort -> {
+            if (virtualPort.realizedBy() != null) {
+                physicalDeviceSet.add(virtualPort.realizedBy().deviceId());
+            }
+        });
+
+        return physicalDeviceSet;
+    }
+
+    /**
      * Returns implementation of the specified service class for operating
      * in the context of the given network.
      * <p>
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java
index 629dd56..dbb036b 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java
@@ -48,7 +48,6 @@
 import org.onosproject.net.Link;
 import org.onosproject.net.NetTestTools;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.TestDeviceParams;
 import org.onosproject.net.intent.FakeIntentManager;
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentState;
@@ -59,10 +58,11 @@
 import org.onosproject.net.topology.TopologyService;
 import org.onosproject.store.service.TestStorageService;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.ArrayList;
 import java.util.Set;
+import java.util.HashSet;
 import java.util.concurrent.atomic.AtomicLong;
 
 import static org.junit.Assert.*;
@@ -71,7 +71,7 @@
 /**
  * Junit tests for VirtualNetworkManager.
  */
-public class VirtualNetworkManagerTest extends TestDeviceParams {
+public class VirtualNetworkManagerTest extends VirtualNetworkTestUtil {
     private final String tenantIdValue1 = "TENANT_ID1";
     private final String tenantIdValue2 = "TENANT_ID2";
 
@@ -280,6 +280,105 @@
     }
 
     /**
+     * Tests getting a collection of physical device identifier corresponding to
+     * the specified virtual device.
+     */
+    @Test
+    public void testGetPhysicalDevices() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue2));
+
+        VirtualNetwork virtualNetwork1 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork2 =
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue2));
+
+        // two virtual device in first virtual network
+        VirtualDevice vDevice1InVnet1 =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID1);
+        VirtualDevice vDevice2InVnet1 =
+                manager.createVirtualDevice(virtualNetwork1.id(), DID2);
+        // Two virtual device in second virtual network
+        VirtualDevice vDevice1InVnet2 =
+                manager.createVirtualDevice(virtualNetwork2.id(), DID1);
+        VirtualDevice vDevice2InVnet2 =
+                manager.createVirtualDevice(virtualNetwork2.id(), DID2);
+
+        // Connection Point from each physical device
+        // Virtual network 1
+        ConnectPoint cp1InVnet1 =
+                new ConnectPoint(PHYDID1, PortNumber.portNumber(10));
+        ConnectPoint cp2InVnet1 =
+                new ConnectPoint(PHYDID2, PortNumber.portNumber(20));
+        ConnectPoint cp3InVnet1 =
+                new ConnectPoint(PHYDID3, PortNumber.portNumber(30));
+        ConnectPoint cp4InVnet1 =
+                new ConnectPoint(PHYDID4, PortNumber.portNumber(40));
+        // Virtual network 2
+        ConnectPoint cp1InVnet2 =
+                new ConnectPoint(PHYDID1, PortNumber.portNumber(10));
+        ConnectPoint cp2InVnet2 =
+                new ConnectPoint(PHYDID2, PortNumber.portNumber(20));
+        ConnectPoint cp3InVnet2 =
+                new ConnectPoint(PHYDID3, PortNumber.portNumber(30));
+        ConnectPoint cp4InVnet2 =
+                new ConnectPoint(PHYDID4, PortNumber.portNumber(40));
+
+        // Make simple BigSwitch by mapping two phyDevice to one vDevice
+        // First vDevice in first virtual network
+        manager.createVirtualPort(virtualNetwork1.id(),
+                vDevice1InVnet1.id(), PortNumber.portNumber(1), cp1InVnet1);
+        manager.createVirtualPort(virtualNetwork1.id(),
+                vDevice1InVnet1.id(), PortNumber.portNumber(2), cp2InVnet1);
+        // Second vDevice in first virtual network
+        manager.createVirtualPort(virtualNetwork1.id(),
+                vDevice2InVnet1.id(), PortNumber.portNumber(1), cp3InVnet1);
+        manager.createVirtualPort(virtualNetwork1.id(),
+                vDevice2InVnet1.id(), PortNumber.portNumber(2), cp4InVnet1);
+        // First vDevice in second virtual network
+        manager.createVirtualPort(virtualNetwork2.id(),
+                vDevice1InVnet2.id(), PortNumber.portNumber(1), cp1InVnet2);
+        manager.createVirtualPort(virtualNetwork2.id(),
+                vDevice1InVnet2.id(), PortNumber.portNumber(2), cp2InVnet2);
+        // Second vDevice in second virtual network
+        manager.createVirtualPort(virtualNetwork2.id(),
+                vDevice2InVnet2.id(), PortNumber.portNumber(1), cp3InVnet2);
+        manager.createVirtualPort(virtualNetwork2.id(),
+                vDevice2InVnet2.id(), PortNumber.portNumber(2), cp4InVnet2);
+
+
+        Set<DeviceId> physicalDeviceSet;
+        Set<DeviceId> testSet = new HashSet<>();
+        physicalDeviceSet = manager.getPhysicalDevices(virtualNetwork1.id(), vDevice1InVnet1);
+        testSet.add(PHYDID1);
+        testSet.add(PHYDID2);
+        assertEquals("The physical devices 1 did not match", testSet, physicalDeviceSet);
+        physicalDeviceSet.clear();
+        testSet.clear();
+
+        physicalDeviceSet = manager.getPhysicalDevices(virtualNetwork1.id(), vDevice2InVnet1);
+        testSet.add(PHYDID3);
+        testSet.add(PHYDID4);
+        assertEquals("The physical devices 2 did not match", testSet, physicalDeviceSet);
+        physicalDeviceSet.clear();
+        testSet.clear();
+
+        physicalDeviceSet = manager.getPhysicalDevices(virtualNetwork2.id(), vDevice1InVnet2);
+        testSet.add(PHYDID1);
+        testSet.add(PHYDID2);
+        assertEquals("The physical devices 1 did not match", testSet, physicalDeviceSet);
+        physicalDeviceSet.clear();
+        testSet.clear();
+
+        physicalDeviceSet = manager.getPhysicalDevices(virtualNetwork2.id(), vDevice2InVnet2);
+        testSet.add(PHYDID3);
+        testSet.add(PHYDID4);
+        assertEquals("The physical devices 2 did not match", testSet, physicalDeviceSet);
+        physicalDeviceSet.clear();
+        testSet.clear();
+    }
+
+    /**
      * Tests adding a null virtual host.
      */
     @Test(expected = NullPointerException.class)
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTestUtil.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTestUtil.java
index 487cb6e..a52ca85 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTestUtil.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTestUtil.java
@@ -39,6 +39,11 @@
     protected static final DeviceId VDID3 = deviceId("of:who_v");
     protected static final DeviceId VDID4 = deviceId("of:what_v");
 
+    protected static final DeviceId PHYDID1 = deviceId("physical:1");
+    protected static final DeviceId PHYDID2 = deviceId("physical:2");
+    protected static final DeviceId PHYDID3 = deviceId("physical:3");
+    protected static final DeviceId PHYDID4 = deviceId("physical:4");
+
     /**
      * Method to create the virtual network for further testing.
      *
diff --git a/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/DistributedVirtualNetworkStore.java b/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/DistributedVirtualNetworkStore.java
index b4c1fee..d3390a6 100644
--- a/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/DistributedVirtualNetworkStore.java
+++ b/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/DistributedVirtualNetworkStore.java
@@ -114,12 +114,29 @@
     private final MapEventListener<NetworkId, VirtualNetwork> virtualNetworkMapListener =
             new InternalMapListener<>((mapEventType, virtualNetwork) -> {
                 VirtualNetworkEvent.Type eventType =
-                    mapEventType.equals(MapEvent.Type.INSERT) ? VirtualNetworkEvent.Type.NETWORK_ADDED :
-                    mapEventType.equals(MapEvent.Type.UPDATE) ? VirtualNetworkEvent.Type.NETWORK_UPDATED :
-                    mapEventType.equals(MapEvent.Type.REMOVE) ? VirtualNetworkEvent.Type.NETWORK_REMOVED : null;
+                    mapEventType.equals(MapEvent.Type.INSERT)
+                            ? VirtualNetworkEvent.Type.NETWORK_ADDED :
+                    mapEventType.equals(MapEvent.Type.UPDATE)
+                            ? VirtualNetworkEvent.Type.NETWORK_UPDATED :
+                    mapEventType.equals(MapEvent.Type.REMOVE)
+                            ? VirtualNetworkEvent.Type.NETWORK_REMOVED : null;
                 return eventType == null ? null : new VirtualNetworkEvent(eventType, virtualNetwork.id());
             });
 
+    // Listener for virtual device events
+    private final MapEventListener<DeviceId, VirtualDevice> virtualDeviceMapListener =
+            new InternalMapListener<>((mapEventType, virtualDevice) -> {
+                VirtualNetworkEvent.Type eventType =
+                        mapEventType.equals(MapEvent.Type.INSERT)
+                                ? VirtualNetworkEvent.Type.VIRTUAL_DEVICE_ADDED :
+                        mapEventType.equals(MapEvent.Type.UPDATE)
+                                ? VirtualNetworkEvent.Type.VIRTUAL_DEVICE_UPDATED :
+                        mapEventType.equals(MapEvent.Type.REMOVE)
+                                ? VirtualNetworkEvent.Type.VIRTUAL_DEVICE_REMOVED : null;
+                return eventType == null ? null :
+                        new VirtualNetworkEvent(eventType, virtualDevice.networkId(), virtualDevice);
+            });
+
     // Track virtual network IDs by tenant Id
     private ConsistentMap<TenantId, Set<NetworkId>> tenantIdNetworkIdSetConsistentMap;
     private Map<TenantId, Set<NetworkId>> tenantIdNetworkIdSetMap;
@@ -128,17 +145,6 @@
     private ConsistentMap<DeviceId, VirtualDevice> deviceIdVirtualDeviceConsistentMap;
     private Map<DeviceId, VirtualDevice> deviceIdVirtualDeviceMap;
 
-    // Listener for virtual device events
-    private final MapEventListener<DeviceId, VirtualDevice> virtualDeviceMapListener =
-            new InternalMapListener<>((mapEventType, virtualDevice) -> {
-                VirtualNetworkEvent.Type eventType =
-                    mapEventType.equals(MapEvent.Type.INSERT) ? VirtualNetworkEvent.Type.VIRTUAL_DEVICE_ADDED :
-                    mapEventType.equals(MapEvent.Type.UPDATE) ? VirtualNetworkEvent.Type.VIRTUAL_DEVICE_UPDATED :
-                    mapEventType.equals(MapEvent.Type.REMOVE) ? VirtualNetworkEvent.Type.VIRTUAL_DEVICE_REMOVED : null;
-                return eventType == null ? null :
-                        new VirtualNetworkEvent(eventType, virtualDevice.networkId(), virtualDevice);
-            });
-
     // Track device IDs by network Id
     private ConsistentMap<NetworkId, Set<DeviceId>> networkIdDeviceIdSetConsistentMap;
     private Map<NetworkId, Set<DeviceId>> networkIdDeviceIdSetMap;