[ONOS-5731] Implement skeleton of VirtualNetworkPacketManager

Changes
1. Added VirtualNetworkPacketManager
2. Added VirtualNetworkPacketStore interface and impl class
3. Added VirtualPacketStore impl
4. Simple test cases are added

Todo
1. More test cases

Change-Id: I86f0484a9ee038dab8716703f0e5e41cbcf30cb1
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/VirtualNetworkIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/VirtualNetworkIntentCompilerTest.java
index 3acc2cf..595afd4 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/VirtualNetworkIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/VirtualNetworkIntentCompilerTest.java
@@ -107,6 +107,7 @@
         manager = new VirtualNetworkManager();
         manager.setStore(virtualNetworkManagerStore);
         manager.setIntentService(intentService);
+        setField(manager, "coreService", coreService);
         NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
         manager.activate();
 
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/AbstractVnetService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/AbstractVnetService.java
index 2eac0af..3700e28 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/AbstractVnetService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/AbstractVnetService.java
@@ -16,7 +16,6 @@
 
 package org.onosproject.incubator.net.virtual;
 
-import org.onlab.osgi.DefaultServiceDirectory;
 import org.onlab.osgi.ServiceDirectory;
 
 import static com.google.common.base.Preconditions.checkNotNull;
@@ -38,7 +37,7 @@
         checkNotNull(networkId, NETWORK_NULL);
         this.manager = manager;
         this.networkId = networkId;
-        this.serviceDirectory = new DefaultServiceDirectory();
+        this.serviceDirectory = manager.getServiceDirectory();
     }
 
     @Override
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkPacketStore.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkPacketStore.java
new file mode 100644
index 0000000..320424b
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkPacketStore.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.virtual;
+
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketEvent;
+import org.onosproject.net.packet.PacketRequest;
+import org.onosproject.net.packet.PacketStoreDelegate;
+
+import java.util.List;
+
+public interface VirtualNetworkPacketStore
+        extends VirtualStore<PacketEvent, PacketStoreDelegate> {
+    /**
+     * Decides which instance should emit the packet and forwards the packet to
+     * that instance. The relevant PacketManager is notified via the
+     * PacketStoreDelegate that it should emit the packet.
+     *
+     * @param networkId a virtual network identifier
+     * @param packet the packet to emit
+     */
+    void emit(NetworkId networkId, OutboundPacket packet);
+
+    /**
+     * Requests intercept of packets that match the given selector.
+     *
+     * @param networkId a virtual network identifier
+     * @param request a packet request
+     */
+    void requestPackets(NetworkId networkId, PacketRequest request);
+
+    /**
+     * Cancels intercept of packets that match the given selector.
+     *
+     * @param networkId a virtual network identifier
+     * @param request a packet request
+     */
+    void cancelPackets(NetworkId networkId, PacketRequest request);
+
+    /**
+     * Obtains all existing requests in the system.
+     *
+     * @param networkId a virtual network identifier
+     * @return list of packet requests in order of priority
+     */
+    List<PacketRequest> existingRequests(NetworkId networkId);
+}
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 2e852e8..21f721c 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
@@ -17,6 +17,7 @@
 
 import com.google.common.annotations.Beta;
 import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.core.ApplicationId;
 import org.onosproject.net.DeviceId;
 
 import java.util.Set;
@@ -112,4 +113,12 @@
      * @return a service directory
      */
     ServiceDirectory getServiceDirectory();
+
+    /**
+     * Returns the application identifier for a virtual network.
+     *
+     * @param networkId network identifier
+     * @return an representative application identifier for a virtual network
+     */
+    ApplicationId getVirtualNetworkApplicationId(NetworkId networkId);
 }
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualPacketProviderService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualPacketProviderService.java
index 28272d6..9facc1b 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualPacketProviderService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualPacketProviderService.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.incubator.net.virtual.provider;
 
-import org.onosproject.incubator.net.virtual.NetworkId;
 import org.onosproject.net.packet.PacketContext;
 
 /**
@@ -29,9 +28,8 @@
      * This processing will be done synchronously, i.e. run-to-completion.
      * This context is translated with virtual concepts.
      *
-     * @param networkId the virtual network ID which will handle the packet context
      * @param context inbound packet context
      */
-    void processPacket(NetworkId networkId, PacketContext context);
+    void processPacket(PacketContext context);
 
 }
diff --git a/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/event/AbstractVirtualListenerManagerTest.java b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/event/AbstractVirtualListenerManagerTest.java
index 33fce56..1195e69 100644
--- a/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/event/AbstractVirtualListenerManagerTest.java
+++ b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/event/AbstractVirtualListenerManagerTest.java
@@ -22,6 +22,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.core.ApplicationId;
 import org.onosproject.event.AbstractEvent;
 import org.onosproject.event.Event;
 import org.onosproject.event.EventDeliveryService;
@@ -295,6 +296,11 @@
         public ServiceDirectory getServiceDirectory() {
             return serviceDirectory;
         }
+
+        @Override
+        public ApplicationId getVirtualNetworkApplicationId(NetworkId networkId) {
+            return null;
+        }
     }
 
     private  class TestServiceDirectory implements ServiceDirectory {
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java
index 2665641..84589c8 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java
@@ -27,6 +27,8 @@
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
 import org.onosproject.incubator.net.tunnel.TunnelId;
 import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
 import org.onosproject.incubator.net.virtual.NetworkId;
@@ -61,6 +63,7 @@
 import org.onosproject.net.intent.IntentService;
 import org.onosproject.net.intent.IntentState;
 import org.onosproject.net.link.LinkService;
+import org.onosproject.net.packet.PacketService;
 import org.onosproject.net.provider.AbstractListenerProviderRegistry;
 import org.onosproject.net.provider.AbstractProviderService;
 import org.onosproject.net.topology.PathService;
@@ -91,18 +94,25 @@
     private static final String DEVICE_NULL = "Device ID cannot be null";
     private static final String LINK_POINT_NULL = "Link end-point cannot be null";
 
+    private static final String VIRTUAL_NETWORK_APP_ID_STRING =
+            "org.onosproject.virtual-network";
+
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected VirtualNetworkStore store;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected IntentService intentService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
     private final InternalVirtualIntentListener intentListener =
             new InternalVirtualIntentListener();
 
     private VirtualNetworkStoreDelegate delegate = this::post;
 
     private ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
+    private ApplicationId appId;
 
     // TODO: figure out how to coordinate "implementation" of a virtual network in a cluster
 
@@ -130,6 +140,7 @@
         store.setDelegate(delegate);
         eventDispatcher.addSink(VirtualNetworkEvent.class, listenerRegistry);
         intentService.addListener(intentListener);
+        appId = coreService.registerApplication(VIRTUAL_NETWORK_APP_ID_STRING);
         log.info("Started");
     }
 
@@ -355,6 +366,11 @@
         return (T) service;
     }
 
+    @Override
+    public ApplicationId getVirtualNetworkApplicationId(NetworkId networkId) {
+        return appId;
+    }
+
     /**
      * Returns the Vnet service matching the service key.
      *
@@ -403,6 +419,8 @@
             service = new VirtualNetworkPathManager(this, network.id());
         } else if (serviceKey.serviceClass.equals(FlowRuleService.class)) {
             service = new VirtualNetworkFlowRuleManager(this, network.id());
+        } else if (serviceKey.serviceClass.equals(PacketService.class)) {
+            service = new VirtualNetworkPacketManager(this, network.id());
         } else {
             return null;
         }
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManager.java
new file mode 100644
index 0000000..41b7dce
--- /dev/null
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManager.java
@@ -0,0 +1,372 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.virtual.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.virtual.AbstractVnetService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkPacketStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualPacketProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualPacketProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.packet.DefaultPacketRequest;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketEvent;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketProcessorEntry;
+import org.onosproject.net.packet.PacketRequest;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.packet.PacketStoreDelegate;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+public class VirtualNetworkPacketManager extends AbstractVnetService
+        implements PacketService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private final VirtualNetworkService manager;
+
+    protected VirtualNetworkPacketStore store;
+    private final List<ProcessorEntry> processors = Lists.newCopyOnWriteArrayList();
+
+    private NodeId localNodeId;
+
+    private DeviceService deviceService;
+    private FlowObjectiveService objectiveService;
+
+    private VirtualProviderRegistryService providerRegistryService = null;
+
+    private InternalPacketProviderService providerService = null;
+
+    public VirtualNetworkPacketManager(VirtualNetworkService virtualNetworkManager,
+                                       NetworkId networkId) {
+        super(virtualNetworkManager, networkId);
+        this.manager = virtualNetworkManager;
+
+        //Set node id as same as the node hosting virtual manager
+        ClusterService clusterService = serviceDirectory.get(ClusterService.class);
+        this.localNodeId = clusterService.getLocalNode().id();
+
+        this.store = serviceDirectory.get(VirtualNetworkPacketStore.class);
+        this.store.setDelegate(networkId(), new InternalStoreDelegate());
+
+        this.deviceService = manager.get(networkId(), DeviceService.class);
+        this.objectiveService = manager.get(networkId(), FlowObjectiveService.class);
+
+        providerRegistryService =
+                serviceDirectory.get(VirtualProviderRegistryService.class);
+        providerService = new InternalPacketProviderService();
+        providerRegistryService.registerProviderService(networkId(), providerService);
+    }
+
+    @Override
+    public void addProcessor(PacketProcessor processor, int priority) {
+        ProcessorEntry entry = new ProcessorEntry(processor, priority);
+
+        // Insert the new processor according to its priority.
+        int i = 0;
+        for (; i < processors.size(); i++) {
+            if (priority < processors.get(i).priority()) {
+                break;
+            }
+        }
+        processors.add(i, entry);
+    }
+
+    @Override
+    public void removeProcessor(PacketProcessor processor) {
+        // Remove the processor entry.
+        for (int i = 0; i < processors.size(); i++) {
+            if (processors.get(i).processor() == processor) {
+                processors.remove(i);
+                break;
+            }
+        }
+    }
+
+    @Override
+    public List<PacketProcessorEntry> getProcessors() {
+        return ImmutableList.copyOf(processors);
+    }
+
+    @Override
+    public void requestPackets(TrafficSelector selector, PacketPriority priority, ApplicationId appId) {
+        PacketRequest request = new DefaultPacketRequest(selector, priority, appId,
+                                                         localNodeId, Optional.empty());
+        store.requestPackets(networkId(), request);
+    }
+
+    @Override
+    public void requestPackets(TrafficSelector selector, PacketPriority priority,
+                               ApplicationId appId, Optional<DeviceId> deviceId) {
+        PacketRequest request =
+                new DefaultPacketRequest(selector, priority, appId,
+                                         localNodeId, deviceId);
+
+        store.requestPackets(networkId(), request);
+    }
+
+    @Override
+    public void cancelPackets(TrafficSelector selector, PacketPriority priority, ApplicationId appId) {
+        PacketRequest request = new DefaultPacketRequest(selector, priority, appId,
+                                                         localNodeId, Optional.empty());
+        store.cancelPackets(networkId(), request);
+    }
+
+    @Override
+    public void cancelPackets(TrafficSelector selector, PacketPriority priority,
+                              ApplicationId appId, Optional<DeviceId> deviceId) {
+        PacketRequest request = new DefaultPacketRequest(selector, priority,
+                                                         appId, localNodeId,
+                                                         deviceId);
+        store.cancelPackets(networkId(), request);
+    }
+
+    @Override
+    public List<PacketRequest> getRequests() {
+        return store.existingRequests(networkId());
+    }
+
+    @Override
+    public void emit(OutboundPacket packet) {
+        store.emit(networkId(), packet);
+    }
+
+    /**
+     * Personalized packet provider service issued to the supplied provider.
+     */
+    private class InternalPacketProviderService
+            extends AbstractVirtualProviderService<VirtualPacketProvider>
+            implements VirtualPacketProviderService {
+
+        protected InternalPacketProviderService() {
+            super();
+
+            Set<ProviderId> providerIds =
+                    providerRegistryService.getProvidersByService(this);
+            ProviderId providerId = providerIds.stream().findFirst().get();
+            VirtualPacketProvider provider = (VirtualPacketProvider)
+                    providerRegistryService.getProvider(providerId);
+            setProvider(provider);
+        }
+
+        @Override
+        public void processPacket(PacketContext context) {
+            // TODO filter packets sent to processors based on registrations
+            for (ProcessorEntry entry : processors) {
+                try {
+                    long start = System.nanoTime();
+                    entry.processor().process(context);
+                    entry.addNanos(System.nanoTime() - start);
+                } catch (Exception e) {
+                    log.warn("Packet processor {} threw an exception", entry.processor(), e);
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Entity for tracking stats for a packet processor.
+     */
+    private class ProcessorEntry implements PacketProcessorEntry {
+        private final PacketProcessor processor;
+        private final int priority;
+        private long invocations = 0;
+        private long nanos = 0;
+
+        public ProcessorEntry(PacketProcessor processor, int priority) {
+            this.processor = processor;
+            this.priority = priority;
+        }
+
+        @Override
+        public PacketProcessor processor() {
+            return processor;
+        }
+
+        @Override
+        public int priority() {
+            return priority;
+        }
+
+        @Override
+        public long invocations() {
+            return invocations;
+        }
+
+        @Override
+        public long totalNanos() {
+            return nanos;
+        }
+
+        @Override
+        public long averageNanos() {
+            return invocations > 0 ? nanos / invocations : 0;
+        }
+
+        void addNanos(long nanos) {
+            this.nanos += nanos;
+            this.invocations++;
+        }
+    }
+
+    private void localEmit(NetworkId networkId, OutboundPacket packet) {
+        Device device = deviceService.getDevice(packet.sendThrough());
+        if (device == null) {
+            return;
+        }
+        VirtualPacketProvider packetProvider =
+                (VirtualPacketProvider) providerService.provider();
+
+        if (packetProvider != null) {
+            packetProvider.emit(networkId, packet);
+        }
+    }
+
+    /**
+     * Internal callback from the packet store.
+     */
+    protected class InternalStoreDelegate implements PacketStoreDelegate {
+        @Override
+        public void notify(PacketEvent event) {
+            localEmit(networkId(), event.subject());
+        }
+
+        @Override
+        public void requestPackets(PacketRequest request) {
+            DeviceId deviceid = request.deviceId().orElse(null);
+
+            if (deviceid != null) {
+                pushRule(deviceService.getDevice(deviceid), request);
+            } else {
+                pushToAllDevices(request);
+            }
+        }
+
+        @Override
+        public void cancelPackets(PacketRequest request) {
+            DeviceId deviceid = request.deviceId().orElse(null);
+
+            if (deviceid != null) {
+                removeRule(deviceService.getDevice(deviceid), request);
+            } else {
+                removeFromAllDevices(request);
+            }
+        }
+    }
+
+    /**
+     * Pushes packet intercept flow rules to the device.
+     *
+     * @param device  the device to push the rules to
+     * @param request the packet request
+     */
+    private void pushRule(Device device, PacketRequest request) {
+        if (!device.type().equals(Device.Type.SWITCH)) {
+            return;
+        }
+
+        ForwardingObjective forwarding = createBuilder(request)
+                .add(new ObjectiveContext() {
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.warn("Failed to install packet request {} to {}: {}",
+                                 request, device.id(), error);
+                    }
+                });
+
+        objectiveService.forward(device.id(), forwarding);
+    }
+
+    /**
+     * Removes packet intercept flow rules from the device.
+     *
+     * @param device  the device to remove the rules deom
+     * @param request the packet request
+     */
+    private void removeRule(Device device, PacketRequest request) {
+        if (!device.type().equals(Device.Type.SWITCH)) {
+            return;
+        }
+        ForwardingObjective forwarding = createBuilder(request)
+                .remove(new ObjectiveContext() {
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.warn("Failed to withdraw packet request {} from {}: {}",
+                                 request, device.id(), error);
+                    }
+                });
+        objectiveService.forward(device.id(), forwarding);
+    }
+
+    /**
+     * Pushes a packet request flow rule to all devices.
+     *
+     * @param request the packet request
+     */
+    private void pushToAllDevices(PacketRequest request) {
+        log.debug("Pushing packet request {} to all devices", request);
+        for (Device device : deviceService.getDevices()) {
+            pushRule(device, request);
+        }
+    }
+
+    /**
+     * Removes packet request flow rule from all devices.
+     *
+     * @param request the packet request
+     */
+    private void removeFromAllDevices(PacketRequest request) {
+        deviceService.getAvailableDevices().forEach(d -> removeRule(d, request));
+    }
+
+    private DefaultForwardingObjective.Builder createBuilder(PacketRequest request) {
+        return DefaultForwardingObjective.builder()
+                .withPriority(request.priority().priorityValue())
+                .withSelector(request.selector())
+                .fromApp(manager.getVirtualNetworkApplicationId(networkId()))
+                .withFlag(ForwardingObjective.Flag.VERSATILE)
+                .withTreatment(DefaultTrafficTreatment.builder().punt().build())
+                .makePermanent();
+    }
+}
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkDeviceManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkDeviceManagerTest.java
index e319e30..44099e3 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkDeviceManagerTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkDeviceManagerTest.java
@@ -71,6 +71,7 @@
         manager = new VirtualNetworkManager();
         manager.store = virtualNetworkManagerStore;
         manager.intentService = intentService;
+        manager.coreService = coreService;
         NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
 
         testDirectory = new TestServiceDirectory();
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java
index 0afc6ea..fa93335 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowRuleManagerTest.java
@@ -33,9 +33,6 @@
 import org.onosproject.core.CoreService;
 import org.onosproject.event.EventDeliveryService;
 import org.onosproject.incubator.net.virtual.NetworkId;
-import org.onosproject.incubator.net.virtual.TenantId;
-import org.onosproject.incubator.net.virtual.VirtualDevice;
-import org.onosproject.incubator.net.virtual.VirtualLink;
 import org.onosproject.incubator.net.virtual.VirtualNetwork;
 import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
 import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
@@ -48,12 +45,8 @@
 import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
 import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
 import org.onosproject.incubator.store.virtual.impl.SimpleVirtualFlowRuleStore;
-import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.Link;
 import org.onosproject.net.NetTestTools;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.TestDeviceParams;
 import org.onosproject.net.flow.DefaultFlowEntry;
 import org.onosproject.net.flow.DefaultFlowRule;
 import org.onosproject.net.flow.FlowEntry;
@@ -83,7 +76,7 @@
 import static org.junit.Assert.*;
 import static org.onosproject.net.flow.FlowRuleEvent.Type.*;
 
-public class VirtualNetworkFlowRuleManagerTest extends TestDeviceParams {
+public class VirtualNetworkFlowRuleManagerTest extends VirtualNetworkTestUtil {
     private static final int TIMEOUT = 10;
 
     private VirtualNetworkManager manager;
@@ -107,9 +100,6 @@
     protected TestFlowRuleListener listener1 = new TestFlowRuleListener();
     protected TestFlowRuleListener listener2 = new TestFlowRuleListener();
 
-    private final TenantId tid1 = TenantId.tenantId("tid1");
-    private final TenantId tid2 = TenantId.tenantId("tid2");
-
     private VirtualNetwork vnet1;
     private VirtualNetwork vnet2;
 
@@ -150,8 +140,8 @@
 
         manager.activate();
 
-        vnet1 = setupVirtualNetworkTopology(tid1);
-        vnet2 = setupVirtualNetworkTopology(tid2);
+        vnet1 = setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = setupVirtualNetworkTopology(manager, TID2);
 
         vnetFlowRuleService1 = new VirtualNetworkFlowRuleManager(manager, vnet1.id());
         vnetFlowRuleService2 = new VirtualNetworkFlowRuleManager(manager, vnet2.id());
@@ -175,60 +165,8 @@
         virtualNetworkManagerStore.deactivate();
     }
 
-    /**
-     * Method to create the virtual network for further testing.
-     *
-     * @return virtual network
-     */
-    private VirtualNetwork setupVirtualNetworkTopology(TenantId tenantId) {
-        manager.registerTenantId(tenantId);
-        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(tenantId);
-
-        VirtualDevice virtualDevice1 =
-                manager.createVirtualDevice(virtualNetwork.id(), DID1);
-        VirtualDevice virtualDevice2 =
-                manager.createVirtualDevice(virtualNetwork.id(), DID2);
-        VirtualDevice virtualDevice3 =
-                manager.createVirtualDevice(virtualNetwork.id(), DID3);
-        VirtualDevice virtualDevice4 =
-                manager.createVirtualDevice(virtualNetwork.id(), DID4);
-
-        ConnectPoint cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
-        manager.createVirtualPort(virtualNetwork.id(), cp1.deviceId(), cp1.port(), cp1);
-
-        ConnectPoint cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
-        manager.createVirtualPort(virtualNetwork.id(), cp2.deviceId(), cp2.port(), cp2);
-
-        ConnectPoint cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
-        manager.createVirtualPort(virtualNetwork.id(), cp3.deviceId(), cp3.port(), cp3);
-
-        ConnectPoint cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
-        manager.createVirtualPort(virtualNetwork.id(), cp4.deviceId(), cp4.port(), cp4);
-
-        ConnectPoint cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
-        manager.createVirtualPort(virtualNetwork.id(), cp5.deviceId(), cp5.port(), cp5);
-
-        ConnectPoint cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
-        manager.createVirtualPort(virtualNetwork.id(), cp6.deviceId(), cp6.port(), cp6);
-
-        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
-        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
-        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
-        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
-        VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
-        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
-        VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
-        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
-        VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp2, cp6);
-        virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
-        VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp6, cp2);
-        virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
-
-        return virtualNetwork;
-    }
-
     private FlowRule flowRule(int tsval, int trval) {
-        return flowRule(DID1, tsval, trval);
+        return flowRule(VDID1, tsval, trval);
     }
 
     private FlowRule flowRule(DeviceId did, int tsval, int trval) {
@@ -248,22 +186,22 @@
         FlowRule rule = flowRule(hval, hval);
         vnetFlowRuleService1.applyFlowRules(rule);
 
-        assertNotNull("rule should be found", vnetFlowRuleService1.getFlowEntries(DID1));
+        assertNotNull("rule should be found", vnetFlowRuleService1.getFlowEntries(VDID1));
         return rule;
     }
 
     private int flowCount(FlowRuleService service) {
         List<FlowEntry> entries = Lists.newArrayList();
-        service.getFlowEntries(DID1).forEach(entries::add);
+        service.getFlowEntries(VDID1).forEach(entries::add);
         return entries.size();
     }
 
     @Test
     public void getFlowEntries() {
         assertTrue("store should be empty",
-                   Sets.newHashSet(vnetFlowRuleService1.getFlowEntries(DID1)).isEmpty());
+                   Sets.newHashSet(vnetFlowRuleService1.getFlowEntries(VDID1)).isEmpty());
         assertTrue("store should be empty",
-                   Sets.newHashSet(vnetFlowRuleService2.getFlowEntries(DID1)).isEmpty());
+                   Sets.newHashSet(vnetFlowRuleService2.getFlowEntries(VDID1)).isEmpty());
 
         FlowRule f1 = addFlowRule(1);
         FlowRule f2 = addFlowRule(2);
@@ -274,7 +212,7 @@
         assertEquals("2 rules should exist", 2, flowCount(vnetFlowRuleService1));
         assertEquals("0 rules should exist", 0, flowCount(vnetFlowRuleService2));
 
-        providerService1.pushFlowMetrics(DID1, ImmutableList.of(fe1, fe2));
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1, fe2));
         validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
                        RULE_ADDED, RULE_ADDED);
 
@@ -283,7 +221,7 @@
         System.err.println("events :" + listener1.events);
         assertEquals("0 rules should exist", 0, flowCount(vnetFlowRuleService2));
 
-        providerService1.pushFlowMetrics(DID1, ImmutableList.of(fe1));
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1));
         validateEvents(listener1, RULE_UPDATED, RULE_UPDATED);
     }
 
@@ -313,10 +251,10 @@
         FlowEntry fe1 = new DefaultFlowEntry(f1);
         FlowEntry fe2 = new DefaultFlowEntry(f2);
         FlowEntry fe3 = new DefaultFlowEntry(f3);
-        providerService1.pushFlowMetrics(DID1, ImmutableList.of(fe1, fe2, fe3));
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1, fe2, fe3));
         validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
                        RULE_ADDED, RULE_ADDED, RULE_ADDED);
-        vnetFlowRuleService1.purgeFlowRules(DID1);
+        vnetFlowRuleService1.purgeFlowRules(VDID1);
         assertEquals("0 rule should exist", 0, flowCount(vnetFlowRuleService1));
     }
 
@@ -330,7 +268,7 @@
         FlowEntry fe1 = new DefaultFlowEntry(f1);
         FlowEntry fe2 = new DefaultFlowEntry(f2);
         FlowEntry fe3 = new DefaultFlowEntry(f3);
-        providerService1.pushFlowMetrics(DID1, ImmutableList.of(fe1, fe2, fe3));
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1, fe2, fe3));
         validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
                        RULE_ADDED, RULE_ADDED, RULE_ADDED);
 
@@ -355,7 +293,7 @@
         StoredFlowEntry fe1 = new DefaultFlowEntry(f1);
         FlowEntry fe2 = new DefaultFlowEntry(f2);
 
-        providerService1.pushFlowMetrics(DID1, ImmutableList.of(fe1, fe2));
+        providerService1.pushFlowMetrics(VDID1, ImmutableList.of(fe1, fe2));
         vnetFlowRuleService1.removeFlowRules(f1);
 
         //FIXME modification of "stored" flow entry outside of store
@@ -373,7 +311,7 @@
         FlowEntry fe3 = new DefaultFlowEntry(f3);
         vnetFlowRuleService1.applyFlowRules(f3);
 
-        providerService1.pushFlowMetrics(DID1, Collections.singletonList(fe3));
+        providerService1.pushFlowMetrics(VDID1, Collections.singletonList(fe3));
         validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADDED, RULE_UPDATED);
 
         providerService1.flowRemoved(fe3);
@@ -392,7 +330,7 @@
         FlowEntry fe3 = new DefaultFlowEntry(f3);
 
 
-        providerService1.pushFlowMetrics(DID1, Lists.newArrayList(fe1, fe2, fe3));
+        providerService1.pushFlowMetrics(VDID1, Lists.newArrayList(fe1, fe2, fe3));
 
         validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
                        RULE_ADDED, RULE_ADDED);
@@ -414,7 +352,7 @@
 
         vnetFlowRuleService1.removeFlowRules(f3);
 
-        providerService1.pushFlowMetrics(DID1, Lists.newArrayList(fe1, fe2));
+        providerService1.pushFlowMetrics(VDID1, Lists.newArrayList(fe1, fe2));
 
         validateEvents(listener1, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
                        RULE_REMOVE_REQUESTED, RULE_ADDED, RULE_ADDED, RULE_REMOVED);
@@ -439,7 +377,7 @@
 
     private boolean validateState(Map<FlowRule, FlowEntry.FlowEntryState> expected) {
         Map<FlowRule, FlowEntry.FlowEntryState> expectedToCheck = new HashMap<>(expected);
-        Iterable<FlowEntry> rules = vnetFlowRuleService1.getFlowEntries(DID1);
+        Iterable<FlowEntry> rules = vnetFlowRuleService1.getFlowEntries(VDID1);
         for (FlowEntry f : rules) {
             assertTrue("Unexpected FlowRule " + f, expectedToCheck.containsKey(f));
             assertEquals("FlowEntry" + f, expectedToCheck.get(f), f.state());
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManagerTest.java
index ed0f3c2..01611f3 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManagerTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkHostManagerTest.java
@@ -66,6 +66,7 @@
         manager = new VirtualNetworkManager();
         manager.store = virtualNetworkManagerStore;
         manager.intentService = intentService;
+        manager.coreService = coreService;
         NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
 
         testDirectory = new TestServiceDirectory();
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManagerTest.java
index 70f1c1b..a2062d9 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManagerTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkLinkManagerTest.java
@@ -72,6 +72,7 @@
         manager = new VirtualNetworkManager();
         manager.store = virtualNetworkManagerStore;
         manager.intentService = intentService;
+        manager.coreService = coreService;
         NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
 
         testDirectory = new TestServiceDirectory();
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 6bf9ed2..158fcef 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
@@ -104,6 +104,7 @@
         manager.store = virtualNetworkManagerStore;
         manager.addListener(listener);
         manager.intentService = intentService;
+        manager.coreService = coreService;
         NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
 
         testDirectory = new TestServiceDirectory();
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerTest.java
new file mode 100644
index 0000000..b9771e4
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPacketManagerTest.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.virtual.impl;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkPacketStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualPacketProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.store.virtual.impl.SimpleVirtualPacketStore;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.intent.FakeIntentManager;
+import org.onosproject.net.intent.TestableIntentService;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.TestStorageService;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.*;
+
+public class VirtualNetworkPacketManagerTest extends VirtualNetworkTestUtil {
+
+    private static final int PROCESSOR_PRIORITY = 1;
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService = new TestCoreService();
+    private TestableIntentService intentService = new FakeIntentManager();
+    private TestServiceDirectory testDirectory;
+    private EventDeliveryService eventDeliveryService;
+    private VirtualProviderManager providerRegistryService;
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    private VirtualPacketProvider provider = new TestPacketProvider();
+    private VirtualNetworkPacketStore packetStore = new SimpleVirtualPacketStore();
+
+    private VirtualNetworkPacketManager packetManager1;
+    private VirtualNetworkPacketManager packetManager2;
+
+    @Before
+    public void setUp() throws TestUtils.TestUtilsException {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.coreService = coreService;
+        manager.intentService = intentService;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        providerRegistryService = new VirtualProviderManager();
+        providerRegistryService.registerProvider(provider);
+
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(VirtualProviderRegistryService.class, providerRegistryService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(ClusterService.class, new ClusterServiceAdapter())
+                .add(VirtualNetworkPacketStore.class, packetStore);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        eventDeliveryService = new TestEventDispatcher();
+        NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+
+        manager.activate();
+
+        vnet1 = VirtualNetworkTestUtil.setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = VirtualNetworkTestUtil.setupVirtualNetworkTopology(manager, TID2);
+
+        packetManager1 = new VirtualNetworkPacketManager(manager, vnet1.id());
+        packetManager2 = new VirtualNetworkPacketManager(manager, vnet2.id());
+    }
+
+    /**
+     * Tests the correct usage of addProcessor() for a outbound packet.
+     */
+    @Test
+    public void addProcessorTest() {
+        PacketProcessor testProcessor = new TestProcessor();
+        packetManager1.addProcessor(testProcessor, PROCESSOR_PRIORITY);
+
+        assertEquals("1 processor expected", 1,
+                    packetManager1.getProcessors().size());
+        assertEquals("0 processor expected", 0,
+                     packetManager2.getProcessors().size());
+
+        assertEquals("not equal packet processor", testProcessor,
+                     packetManager1.getProcessors().get(0).processor());
+        assertEquals("not equal packet processor priority", PROCESSOR_PRIORITY,
+                     packetManager1.getProcessors().get(0).priority());
+    }
+
+    /**
+     * Tests the correct usage of addProcessor() for a outbound packet.
+     */
+    @Test
+    public void removeProcessorTest() {
+        PacketProcessor testProcessor = new TestProcessor();
+        packetManager1.addProcessor(testProcessor, PROCESSOR_PRIORITY);
+
+        assertEquals("1 processor expected", 1,
+                     packetManager1.getProcessors().size());
+        assertEquals("0 processor expected", 0,
+                     packetManager2.getProcessors().size());
+
+        packetManager1.removeProcessor(testProcessor);
+
+        assertEquals("0 processor expected", 0,
+                     packetManager1.getProcessors().size());
+        assertEquals("0 processor expected", 0,
+                     packetManager2.getProcessors().size());
+    }
+
+    /**
+     * Tests the correct usage of emit() for a outbound packet.
+     */
+    @Test
+    public void emitTest() {
+        OutboundPacket packet =
+                new DefaultOutboundPacket(VDID1, DefaultTrafficTreatment.emptyTreatment(), ByteBuffer.allocate(5));
+        packetManager1.emit(packet);
+        assertEquals("Packet not emitted correctly", packet, emittedPacket);
+    }
+
+    private static OutboundPacket emittedPacket = null;
+
+    /**
+     * Core service test class.
+     */
+    private class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+    }
+
+    private class TestPacketProvider extends AbstractVirtualProvider
+            implements VirtualPacketProvider {
+
+        /**
+         * Creates a provider with the supplied identifier.
+         */
+        protected TestPacketProvider() {
+            super(new ProviderId("test-packet",
+                                 "org.onosproject.virtual.test-packet"));
+        }
+
+        @Override
+        public void emit(NetworkId networkId, OutboundPacket packet) {
+            emittedPacket = packet;
+        }
+    }
+
+    private class TestProcessor implements PacketProcessor {
+
+        @Override
+        public void process(PacketContext context) {
+
+        }
+    }
+}
\ No newline at end of file
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManagerTest.java
index 768bc4d..1bff96f 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManagerTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkPathManagerTest.java
@@ -71,6 +71,7 @@
         manager = new VirtualNetworkManager();
         manager.store = virtualNetworkManagerStore;
         manager.intentService = intentService;
+        manager.coreService = coreService;
         NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
 
         testDirectory = new TestServiceDirectory();
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
new file mode 100644
index 0000000..487cb6e
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTestUtil.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.net.virtual.impl;
+
+import org.onosproject.incubator.net.virtual.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+
+import static org.onosproject.net.DeviceId.deviceId;
+
+public class VirtualNetworkTestUtil extends TestDeviceParams {
+
+    protected static final TenantId TID1 = TenantId.tenantId("tid1");
+    protected static final TenantId TID2 = TenantId.tenantId("tid2");
+
+    protected static final DeviceId VDID1 = deviceId("of:foo_v");
+    protected static final DeviceId VDID2 = deviceId("of:bar_v");
+    protected static final DeviceId VDID3 = deviceId("of:who_v");
+    protected static final DeviceId VDID4 = deviceId("of:what_v");
+
+    /**
+     * Method to create the virtual network for further testing.
+     *
+     * @return virtual network
+     */
+    public static VirtualNetwork setupVirtualNetworkTopology(VirtualNetworkManager manager,
+                                                             TenantId tenantId) {
+        manager.registerTenantId(tenantId);
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(tenantId);
+
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork.id(), VDID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork.id(), VDID2);
+        VirtualDevice virtualDevice3 =
+                manager.createVirtualDevice(virtualNetwork.id(), VDID3);
+        VirtualDevice virtualDevice4 =
+                manager.createVirtualDevice(virtualNetwork.id(), VDID4);
+
+        ConnectPoint vcp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
+        ConnectPoint cp1 = new ConnectPoint(DID1, PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), vcp1.deviceId(), vcp1.port(), cp1);
+
+        ConnectPoint vcp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
+        ConnectPoint cp2 = new ConnectPoint(DID1, PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), vcp2.deviceId(), vcp2.port(), cp2);
+
+        ConnectPoint vcp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
+        ConnectPoint cp3 = new ConnectPoint(DID2, PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), vcp3.deviceId(), vcp3.port(), cp3);
+
+        ConnectPoint vcp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
+        ConnectPoint cp4 = new ConnectPoint(DID2, PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), vcp4.deviceId(), vcp4.port(), cp4);
+
+        ConnectPoint vcp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
+        ConnectPoint cp5 = new ConnectPoint(DID3, PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), vcp5.deviceId(), vcp5.port(), cp5);
+
+        ConnectPoint vcp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
+        ConnectPoint cp6 = new ConnectPoint(DID3, PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), vcp6.deviceId(), vcp6.port(), cp6);
+
+        DistributedVirtualNetworkStore virtualNetworkManagerStore =
+                (DistributedVirtualNetworkStore) manager.store;
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), vcp1, vcp3);
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), vcp3, vcp1);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), vcp4, vcp5);
+        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), vcp5, vcp4);
+        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), vcp2, vcp6);
+        virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), vcp6, vcp2);
+        virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
+
+        return virtualNetwork;
+    }
+}
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManagerTest.java
index 11bfdc8..ccbb71c 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManagerTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkTopologyManagerTest.java
@@ -23,8 +23,10 @@
 import org.onlab.osgi.TestServiceDirectory;
 import org.onlab.rest.BaseResource;
 import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
 import org.onosproject.core.IdGenerator;
 import org.onosproject.incubator.net.virtual.NetworkId;
 import org.onosproject.incubator.net.virtual.TenantId;
@@ -82,6 +84,7 @@
         manager = new VirtualNetworkManager();
         manager.store = virtualNetworkManagerStore;
         manager.intentService = intentService;
+        manager.coreService = coreService;
         NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
 
         testDirectory = new TestServiceDirectory();
@@ -613,6 +616,8 @@
      */
     private class TestCoreService extends CoreServiceAdapter {
 
+        ApplicationId appId;
+
         @Override
         public IdGenerator getIdGenerator(String topic) {
             return new IdGenerator() {
@@ -624,5 +629,17 @@
                 }
             };
         }
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            appId = new DefaultApplicationId(1, name);
+            return appId;
+        }
+
+            @Override
+        public ApplicationId getAppId(String name) {
+            return appId;
+        }
     }
+
 }
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java
index 1a1c235..d8ae05d 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java
@@ -26,10 +26,9 @@
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
 import org.onosproject.core.DefaultApplicationId;
 import org.onosproject.core.IdGenerator;
-import org.onosproject.core.Version;
 import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
 import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
 import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
@@ -49,7 +48,6 @@
 import org.onosproject.net.DefaultPort;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.DisjointPath;
 import org.onosproject.net.HostId;
 import org.onosproject.net.HostLocation;
 import org.onosproject.net.Link;
@@ -63,26 +61,20 @@
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.FlowEntry;
 import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleListener;
-import org.onosproject.net.flow.FlowRuleOperations;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flow.TableStatisticsEntry;
+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.ClusterId;
+import org.onosproject.net.topology.LinkWeigher;
 import org.onosproject.net.topology.LinkWeight;
 import org.onosproject.net.topology.Topology;
-import org.onosproject.net.topology.TopologyCluster;
-import org.onosproject.net.topology.TopologyGraph;
-import org.onosproject.net.topology.TopologyListener;
 import org.onosproject.net.topology.TopologyServiceAdapter;
 
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Collectors;
 
 import static org.junit.Assert.assertEquals;
@@ -308,27 +300,7 @@
         }
     }
 
-    private static class TestCoreService implements CoreService {
-
-        @Override
-        public Version version() {
-            return null;
-        }
-
-        @Override
-        public Set<ApplicationId> getAppIds() {
-            return null;
-        }
-
-        @Override
-        public ApplicationId getAppId(Short id) {
-            return null;
-        }
-
-        @Override
-        public ApplicationId getAppId(String name) {
-            return null;
-        }
+    private static class TestCoreService extends CoreServiceAdapter {
 
         @Override
         public ApplicationId registerApplication(String name) {
@@ -336,14 +308,15 @@
         }
 
         @Override
-        public ApplicationId registerApplication(String name,
-                                                 Runnable preDeactivate) {
-            return null;
-        }
-
-        @Override
         public IdGenerator getIdGenerator(String topic) {
-            return null;
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
         }
     }
 
@@ -393,6 +366,11 @@
         }
 
         @Override
+        public ApplicationId getVirtualNetworkApplicationId(NetworkId networkId) {
+            return null;
+        }
+
+        @Override
         public void registerTenantId(TenantId tenantId) {
 
         }
@@ -479,53 +457,6 @@
     private static class TestTopologyService extends TopologyServiceAdapter {
 
         @Override
-        public void addListener(TopologyListener listener) {
-
-        }
-
-        @Override
-        public void removeListener(TopologyListener listener) {
-
-        }
-
-        @Override
-        public Topology currentTopology() {
-            return null;
-        }
-
-        @Override
-        public boolean isLatest(Topology topology) {
-            return false;
-        }
-
-        @Override
-        public TopologyGraph getGraph(Topology topology) {
-            return null;
-        }
-
-        @Override
-        public Set<TopologyCluster> getClusters(Topology topology) {
-            return null;
-        }
-
-        @Override
-        public TopologyCluster getCluster(Topology topology, ClusterId clusterId) {
-            return null;
-        }
-
-        @Override
-        public Set<DeviceId> getClusterDevices(Topology topology,
-                                               TopologyCluster cluster) {
-            return null;
-        }
-
-        @Override
-        public Set<Link> getClusterLinks(Topology topology,
-                                         TopologyCluster cluster) {
-            return null;
-        }
-
-        @Override
         public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst) {
             DefaultPath path = new DefaultPath(PID, ImmutableList.of(LINK1),
                                                100, ANNOTATIONS);
@@ -541,58 +472,19 @@
         }
 
         @Override
-        public Set<DisjointPath> getDisjointPaths(Topology topology,
-                                                  DeviceId src, DeviceId dst) {
-            return null;
+        public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst,
+                                  LinkWeigher weigher) {
+            DefaultPath path = new DefaultPath(PID, ImmutableList.of(LINK1),
+                                               100, ANNOTATIONS);
+            return ImmutableSet.of(path);
         }
 
-        @Override
-        public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
-                                                  DeviceId dst, LinkWeight weight) {
-            return null;
-        }
-
-        @Override
-        public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
-                                                  DeviceId dst,
-                                                  Map<Link, Object> riskProfile) {
-            return null;
-        }
-
-        @Override
-        public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
-                                                  DeviceId dst, LinkWeight weight,
-                                                  Map<Link, Object> riskProfile) {
-            return null;
-        }
-
-        @Override
-        public boolean isInfrastructure(Topology topology,
-                                        ConnectPoint connectPoint) {
-            return false;
-        }
-
-        @Override
-        public boolean isBroadcastPoint(Topology topology,
-                                        ConnectPoint connectPoint) {
-            return false;
-        }
     }
 
-    private static class TestFlowRuleService implements FlowRuleService {
+    private static class TestFlowRuleService extends FlowRuleServiceAdapter {
         static Set<FlowRule> ruleCollection = new HashSet<>();
 
         @Override
-        public void addListener(FlowRuleListener listener) {
-
-        }
-
-        @Override
-        public void removeListener(FlowRuleListener listener) {
-
-        }
-
-        @Override
         public int getFlowRuleCount() {
             return ruleCollection.size();
         }
@@ -613,11 +505,6 @@
         }
 
         @Override
-        public void purgeFlowRules(DeviceId deviceId) {
-
-        }
-
-        @Override
         public void removeFlowRules(FlowRule... flowRules) {
             Set<FlowRule> candidates = new HashSet<>();
             for (FlowRule rule : flowRules) {
@@ -627,37 +514,5 @@
             }
             ruleCollection.removeAll(candidates);
         }
-
-        @Override
-        public void removeFlowRulesById(ApplicationId appId) {
-
-        }
-
-        @Override
-        public Iterable<FlowRule> getFlowRulesById(ApplicationId id) {
-            return null;
-        }
-
-        @Override
-        public Iterable<FlowEntry> getFlowEntriesById(ApplicationId id) {
-            return null;
-        }
-
-        @Override
-        public Iterable<FlowRule> getFlowRulesByGroupId(ApplicationId appId,
-                                                        short groupId) {
-            return null;
-        }
-
-        @Override
-        public void apply(FlowRuleOperations ops) {
-
-        }
-
-        @Override
-        public Iterable<TableStatisticsEntry>
-        getFlowTableStatistics(DeviceId deviceId) {
-            return null;
-        }
     }
 }
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualNetworkTopologyProviderTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualNetworkTopologyProviderTest.java
index 1391506..5e2b33b 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualNetworkTopologyProviderTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualNetworkTopologyProviderTest.java
@@ -111,6 +111,7 @@
         virtualNetworkManagerStore.activate();
 
         manager = new VirtualNetworkManager();
+        TestUtils.setField(manager, "coreService", coreService);
         TestUtils.setField(manager, "store", virtualNetworkManagerStore);
         TestUtils.setField(manager, "intentService", intentService);
         NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
diff --git a/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/SimpleVirtualPacketStore.java b/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/SimpleVirtualPacketStore.java
new file mode 100644
index 0000000..5dde804
--- /dev/null
+++ b/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/SimpleVirtualPacketStore.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.incubator.store.virtual.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkPacketStore;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketEvent;
+import org.onosproject.net.packet.PacketRequest;
+import org.onosproject.net.packet.PacketStoreDelegate;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class SimpleVirtualPacketStore
+        extends AbstractVirtualStore<PacketEvent, PacketStoreDelegate>
+        implements VirtualNetworkPacketStore {
+
+    private Map<NetworkId, Map<TrafficSelector, Set<PacketRequest>>> requests
+            = Maps.newConcurrentMap();
+
+    @Override
+    public void emit(NetworkId networkId, OutboundPacket packet) {
+        notifyDelegate(networkId, new PacketEvent(PacketEvent.Type.EMIT, packet));
+    }
+
+    @Override
+    public void requestPackets(NetworkId networkId, PacketRequest request) {
+        requests.computeIfAbsent(networkId, k -> Maps.newConcurrentMap());
+
+        requests.get(networkId).compute(request.selector(), (s, existingRequests) -> {
+            if (existingRequests == null) {
+                return ImmutableSet.of(request);
+            } else if (!existingRequests.contains(request)) {
+                if (hasDelegate(networkId)) {
+                    delegateMap.get(networkId).requestPackets(request);
+                }
+                return ImmutableSet.<PacketRequest>builder()
+                        .addAll(existingRequests)
+                        .add(request)
+                        .build();
+            } else {
+                return existingRequests;
+            }
+        });
+    }
+
+    @Override
+    public void cancelPackets(NetworkId networkId, PacketRequest request) {
+        requests.get(networkId).computeIfPresent(request.selector(), (s, existingRequests) -> {
+            if (existingRequests.contains(request)) {
+                HashSet<PacketRequest> newRequests = Sets.newHashSet(existingRequests);
+                newRequests.remove(request);
+                if (newRequests.size() > 0) {
+                    return ImmutableSet.copyOf(newRequests);
+                } else {
+                    if (hasDelegate(networkId)) {
+                        delegateMap.get(networkId).cancelPackets(request);
+                    }
+                    return null;
+                }
+            } else {
+                return existingRequests;
+            }
+        });
+    }
+
+    @Override
+    public List<PacketRequest> existingRequests(NetworkId networkId) {
+        List<PacketRequest> list = Lists.newArrayList();
+        requests.get(networkId).values().forEach(list::addAll);
+        list.sort((o1, o2) -> o1.priority().priorityValue() - o2.priority().priorityValue());
+        return list;
+    }
+}