[ONOS-5936] (vCore) Virtual FlowObjective Manager and Store

Changes
1. FlowObjective manager for virtual network is added
2. VirtualFlowObjective store is added
3. SimpleVirtualFlowObjectiveStore is implementation
4. Unit tests are added

Change-Id: I18ff1d440d1f85ca96fff36a33a8b67566031e2c
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerTest.java
new file mode 100644
index 0000000..2ca243b
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManagerTest.java
@@ -0,0 +1,198 @@
+/*
+ * 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.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestTools;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.TestApplicationId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+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.VirtualNetworkFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.event.VirtualEvent;
+import org.onosproject.incubator.net.virtual.event.VirtualListenerRegistryManager;
+import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
+import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.store.virtual.impl.SimpleVirtualFlowObjectiveStore;
+import org.onosproject.incubator.store.virtual.impl.SimpleVirtualFlowRuleStore;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleBatchOperation;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.intent.FakeIntentManager;
+import org.onosproject.net.intent.TestableIntentService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.TestStorageService;
+
+import static org.junit.Assert.*;
+
+/**
+ * Junit tests for VirtualNetworkFlowObjectiveManager.
+ */
+public class VirtualNetworkFlowObjectiveManagerTest
+        extends VirtualNetworkTestUtil {
+
+    private static final int RETRY_MS = 250;
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private TestableIntentService intentService = new FakeIntentManager();
+    private ServiceDirectory testDirectory;
+    private SimpleVirtualFlowObjectiveStore flowObjectiveStore;
+
+    private VirtualProviderManager providerRegistryService;
+    private EventDeliveryService eventDeliveryService;
+    VirtualListenerRegistryManager listenerRegistryManager =
+            VirtualListenerRegistryManager.getInstance();
+
+    private ApplicationId appId;
+
+    private VirtualNetwork vnet1;
+    private VirtualNetwork vnet2;
+
+    private FlowObjectiveService service1;
+    private FlowObjectiveService service2;
+
+    //FIXME: referring flowrule service, store, and provider shouldn't be here
+    private VirtualFlowRuleProvider flowRuleProvider = new TestProvider();
+    private SimpleVirtualFlowRuleStore flowRuleStore;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        CoreService coreService = new TestCoreService();
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        StorageService storageService = new TestStorageService();
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", storageService);
+        virtualNetworkManagerStore.activate();
+
+        flowObjectiveStore = new SimpleVirtualFlowObjectiveStore();
+        TestUtils.setField(flowObjectiveStore, "storageService", storageService);
+        flowObjectiveStore.activate();
+        flowRuleStore = new SimpleVirtualFlowRuleStore();
+        flowRuleStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        manager.intentService = intentService;
+        TestUtils.setField(manager, "coreService", coreService);
+
+        providerRegistryService = new VirtualProviderManager();
+        providerRegistryService.registerProvider(flowRuleProvider);
+
+        eventDeliveryService = new TestEventDispatcher();
+        NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
+        eventDeliveryService.addSink(VirtualEvent.class, listenerRegistryManager);
+
+        appId = new TestApplicationId("FlowRuleManagerTest");
+
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(CoreService.class, coreService)
+                .add(EventDeliveryService.class, eventDeliveryService)
+                .add(VirtualProviderRegistryService.class, providerRegistryService)
+                .add(VirtualNetworkFlowRuleStore.class, flowRuleStore)
+                .add(VirtualNetworkFlowObjectiveStore.class, flowObjectiveStore);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        vnet1 = setupVirtualNetworkTopology(manager, TID1);
+        vnet2 = setupVirtualNetworkTopology(manager, TID2);
+
+        service1 = new VirtualNetworkFlowObjectiveManager(manager, vnet1.id());
+        service2 = new VirtualNetworkFlowObjectiveManager(manager, vnet2.id());
+    }
+
+    @After
+    public void tearDownTest() {
+        manager.deactivate();
+        virtualNetworkManagerStore.deactivate();
+    }
+
+    /**
+     * Tests adding a forwarding objective.
+     */
+    @Test
+    public void forwardingObjective() {
+        TrafficSelector selector = DefaultTrafficSelector.emptySelector();
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        ForwardingObjective forward =
+                DefaultForwardingObjective.builder()
+                        .fromApp(NetTestTools.APP_ID)
+                        .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                        .withSelector(selector)
+                        .withTreatment(treatment)
+                        .makePermanent()
+                        .add();
+
+        service1.forward(VDID1, forward);
+
+        TestTools.assertAfter(RETRY_MS, () ->
+                assertEquals("1 flowrule entry expected",
+                             1, flowRuleStore.getFlowRuleCount(vnet1.id())));
+        TestTools.assertAfter(RETRY_MS, () ->
+                assertEquals("0 flowrule entry expected",
+                             0, flowRuleStore.getFlowRuleCount(vnet2.id())));
+    }
+
+    //TODO: More test cases for filter, foward, and next
+
+    private class TestProvider extends AbstractVirtualProvider
+            implements VirtualFlowRuleProvider {
+
+        protected TestProvider() {
+            super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
+        }
+
+        @Override
+        public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
+
+        }
+    }
+}
\ No newline at end of file
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 3cf0457..2d125d1 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
@@ -40,6 +40,7 @@
 import org.onosproject.incubator.net.virtual.VirtualLink;
 import org.onosproject.incubator.net.virtual.VirtualNetwork;
 import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowObjectiveStore;
 import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
 import org.onosproject.incubator.net.virtual.VirtualNetworkGroupStore;
 import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
@@ -54,6 +55,7 @@
 import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderService;
 import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
 import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.store.virtual.impl.SimpleVirtualFlowObjectiveStore;
 import org.onosproject.incubator.store.virtual.impl.SimpleVirtualFlowRuleStore;
 import org.onosproject.incubator.store.virtual.impl.SimpleVirtualGroupStore;
 import org.onosproject.incubator.store.virtual.impl.SimpleVirtualPacketStore;
@@ -833,7 +835,8 @@
                 .add(ClusterService.class, new ClusterServiceAdapter())
                 .add(VirtualNetworkFlowRuleStore.class, new SimpleVirtualFlowRuleStore())
                 .add(VirtualNetworkPacketStore.class, new SimpleVirtualPacketStore())
-                .add(VirtualNetworkGroupStore.class, new SimpleVirtualGroupStore());
+                .add(VirtualNetworkGroupStore.class, new SimpleVirtualGroupStore())
+                .add(VirtualNetworkFlowObjectiveStore.class, new SimpleVirtualFlowObjectiveStore());
 
         validateServiceGetReturnsSavedInstance(virtualNetwork.id(), FlowRuleService.class);
         validateServiceGetReturnsSavedInstance(virtualNetwork.id(), PacketService.class);
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
index 1a49e22..1cedd4a 100644
--- 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
@@ -33,13 +33,18 @@
 import org.onosproject.incubator.net.virtual.NetworkId;
 import org.onosproject.incubator.net.virtual.VirtualDevice;
 import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowObjectiveStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
 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.VirtualFlowRuleProvider;
 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.SimpleVirtualFlowObjectiveStore;
+import org.onosproject.incubator.store.virtual.impl.SimpleVirtualFlowRuleStore;
 import org.onosproject.incubator.store.virtual.impl.SimpleVirtualPacketStore;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.NetTestTools;
@@ -49,6 +54,8 @@
 import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
 import org.onosproject.net.flowobjective.ForwardingObjective;
 import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleBatchOperation;
 import org.onosproject.net.intent.FakeIntentManager;
 import org.onosproject.net.intent.TestableIntentService;
 import org.onosproject.net.packet.DefaultOutboundPacket;
@@ -57,6 +64,7 @@
 import org.onosproject.net.packet.PacketPriority;
 import org.onosproject.net.packet.PacketProcessor;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.StorageService;
 import org.onosproject.store.service.TestStorageService;
 
 import java.nio.ByteBuffer;
@@ -95,12 +103,17 @@
 
     private ApplicationId appId = new TestApplicationId("VirtualPacketManagerTest");
 
+    private VirtualFlowRuleProvider flowRuleProvider = new TestFlowRuleProvider();
+    private SimpleVirtualFlowRuleStore flowRuleStore;
+    private SimpleVirtualFlowObjectiveStore flowObjectiveStore;
+
     @Before
     public void setUp() throws TestUtils.TestUtilsException {
         virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
 
         TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
-        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        StorageService storageService = new TestStorageService();
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", storageService);
         virtualNetworkManagerStore.activate();
 
         manager = new VirtualNetworkManager();
@@ -109,8 +122,15 @@
         manager.intentService = intentService;
         NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
 
+        flowObjectiveStore = new SimpleVirtualFlowObjectiveStore();
+        TestUtils.setField(flowObjectiveStore, "storageService", storageService);
+        flowObjectiveStore.activate();
+        flowRuleStore = new SimpleVirtualFlowRuleStore();
+        flowRuleStore.activate();
+
         providerRegistryService = new VirtualProviderManager();
         providerRegistryService.registerProvider(provider);
+        providerRegistryService.registerProvider(flowRuleProvider);
 
         testDirectory = new TestServiceDirectory()
                 .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
@@ -118,6 +138,8 @@
                 .add(VirtualProviderRegistryService.class, providerRegistryService)
                 .add(EventDeliveryService.class, eventDeliveryService)
                 .add(ClusterService.class, new ClusterServiceAdapter())
+                .add(VirtualNetworkFlowRuleStore.class, flowRuleStore)
+                .add(VirtualNetworkFlowObjectiveStore.class, flowObjectiveStore)
                 .add(VirtualNetworkPacketStore.class, packetStore);
         TestUtils.setField(manager, "serviceDirectory", testDirectory);
 
@@ -373,4 +395,27 @@
             return false;
         }
     }
+
+    private class TestFlowRuleProvider extends AbstractVirtualProvider
+            implements VirtualFlowRuleProvider {
+
+        protected TestFlowRuleProvider() {
+            super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
+        }
+
+        @Override
+        public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
+
+        }
+
+        @Override
+        public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
+
+        }
+    }
 }