[ONOS-6248] VPLS refactoring

Change-Id: I8ffb2199ca108ad8dfe271681068636fc4af2a40
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsManagerTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsManagerTest.java
new file mode 100644
index 0000000..67128db
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsManagerTest.java
@@ -0,0 +1,339 @@
+/*
+ * 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.vpls;
+
+import com.google.common.collect.ImmutableSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.VplsOperation;
+import org.onosproject.vpls.api.VplsOperationService;
+import org.onosproject.vpls.store.VplsStoreEvent;
+
+import java.util.Collection;
+
+import static org.junit.Assert.*;
+import static org.onosproject.net.EncapsulationType.*;
+import static org.onosproject.vpls.api.VplsData.VplsState.*;
+
+/**
+ * Test for {@link VplsManager}
+ */
+public class VplsManagerTest extends VplsTest {
+    private VplsManager vplsManager;
+    private TestVplsStore vplsStore = new TestVplsStore();
+    private TestHostService hostService = new TestHostService();
+    private TestInterfaceService interfaceService = new TestInterfaceService();
+    private TestVplsOperationService vplsOperationService = new TestVplsOperationService();
+
+    @Before
+    public void setup() {
+        vplsManager = new VplsManager();
+        vplsManager.hostService = hostService;
+        vplsManager.vplsStore = vplsStore;
+        vplsManager.operationService = vplsOperationService;
+        vplsManager.interfaceService = interfaceService;
+        vplsStore.clear();
+        vplsOperationService.clear();
+        vplsManager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        vplsManager.deactivate();
+    }
+
+    /**
+     * Creates VPLS by given name and encapsulation type.
+     */
+    @Test
+    public void testCreateVpls() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        assertEquals(VPLS1, vplsData.name());
+        assertEquals(NONE, vplsData.encapsulationType());
+
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertEquals(vplsData.state(), ADDING);
+    }
+
+    /**
+     * Gets VPLS by VPLS name.
+     */
+    @Test
+    public void testGetVpls() {
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.state(ADDED);
+        vplsStore.addVpls(vplsData);
+
+        VplsData result = vplsManager.getVpls(VPLS1);
+        assertEquals(vplsData, result);
+
+        result = vplsManager.getVpls(VPLS2);
+        assertNull(result);
+    }
+
+    /**
+     * Removes a VPLS.
+     */
+    @Test
+    public void testRemoveVpls() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.removeVpls(vplsData);
+        assertEquals(vplsData.state(), REMOVING);
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNull(vplsData);
+        Collection<VplsData> allVpls = vplsStore.getAllVpls();
+        assertEquals(0, allVpls.size());
+    }
+
+    /**
+     * Removes all VPLS.
+     */
+    @Test
+    public void testRemoveAllVpls() {
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.state(ADDED);
+        vplsStore.addVpls(vplsData);
+
+        vplsData = VplsData.of(VPLS2, VLAN);
+        vplsData.state(ADDED);
+        vplsStore.addVpls(vplsData);
+
+        vplsManager.removeAllVpls();
+        assertEquals(0, vplsStore.getAllVpls().size());
+    }
+
+    /**
+     * Adds network interfaces one by one to a VPLS.
+     */
+    @Test
+    public void testAddInterface() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.addInterface(vplsData, V100H1);
+        vplsManager.addInterface(vplsData, V100H2);
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+        assertEquals(vplsData.state(), UPDATING);
+        assertEquals(2, vplsData.interfaces().size());
+        assertTrue(vplsData.interfaces().contains(V100H1));
+        assertTrue(vplsData.interfaces().contains(V100H2));
+    }
+
+    /**
+     * Adds network interfaces to a VPLS.
+     */
+    @Test
+    public void testAddInterfaces() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.addInterfaces(vplsData, ImmutableSet.of(V100H1, V100H2));
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+        assertEquals(vplsData.state(), UPDATING);
+        assertEquals(2, vplsData.interfaces().size());
+        assertTrue(vplsData.interfaces().contains(V100H1));
+        assertTrue(vplsData.interfaces().contains(V100H2));
+    }
+
+    /**
+     * Removes network interfaces one by one from a VPLS.
+     */
+    @Test
+    public void testRemoveInterface() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.addInterface(vplsData, V100H1);
+        vplsManager.addInterface(vplsData, V100H2);
+        vplsManager.removeInterface(vplsData, V100H1);
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+        assertEquals(vplsData.state(), UPDATING);
+        assertEquals(1, vplsData.interfaces().size());
+        assertTrue(vplsData.interfaces().contains(V100H2));
+    }
+
+    /**
+     * Removes network interfaces from a VPLS.
+     */
+    @Test
+    public void testRemoveInterfaces() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.addInterface(vplsData, V100H1);
+        vplsManager.addInterface(vplsData, V100H2);
+        vplsManager.removeInterfaces(vplsData, ImmutableSet.of(V100H1, V100H2));
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+        assertEquals(vplsData.state(), UPDATING);
+        assertEquals(0, vplsData.interfaces().size());
+    }
+
+    /**
+     * Sets encapsulation type for a VPLS.
+     */
+    @Test
+    public void testSetEncapsulationType() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.setEncapsulationType(vplsData, EncapsulationType.VLAN);
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+        assertEquals(vplsData.state(), UPDATING);
+        assertEquals(vplsData.encapsulationType(), EncapsulationType.VLAN);
+    }
+
+    /**
+     * Adds hosts to a VPLS.
+     */
+    @Test
+    public void testAddHost() {
+        VplsData vplsData  = VplsData.of(VPLS1, NONE);
+        vplsData.addInterface(V100H1);
+        vplsData.state(ADDED);
+        vplsStore.addVpls(vplsData);
+
+        HostEvent hostEvent = new HostEvent(HostEvent.Type.HOST_ADDED, V100HOST1);
+        hostService.postHostEvent(hostEvent);
+
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+
+        assertEquals(vplsData.state(), UPDATING);
+    }
+
+    /**
+     * Removes hosts from a VPLS.
+     */
+    @Test
+    public void testRemoveHost() {
+        VplsData vplsData  = VplsData.of(VPLS1, NONE);
+        vplsData.addInterface(V100H1);
+        vplsData.state(ADDED);
+        vplsStore.addVpls(vplsData);
+
+        HostEvent hostEvent = new HostEvent(HostEvent.Type.HOST_REMOVED, V100HOST1);
+        hostService.postHostEvent(hostEvent);
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+
+        assertEquals(vplsData.state(), UPDATING);
+    }
+
+    /**
+     * Pass different VPLS store event to store delegate.
+     * Include these cases:
+     * <ul>
+     *     <li>VPLS added</li>
+     *     <li>VPLS updated</li>
+     *     <li>VPLS state updated</li>
+     *     <li>VPLS removed</li>
+     * </ul>
+     */
+    @Test
+    public void testStoreDelegate() {
+        // Add
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        VplsStoreEvent event = new VplsStoreEvent(VplsStoreEvent.Type.ADD, vplsData);
+        vplsStore.delegate().notify(event);
+
+        VplsOperation vplsOperation = vplsOperationService.operation();
+        assertEquals(vplsOperation.op(), VplsOperation.Operation.ADD);
+        assertEquals(vplsOperation.vpls(), vplsData);
+        vplsOperationService.clear();
+
+        // Update info
+        vplsData.encapsulationType(EncapsulationType.VLAN);
+        vplsData.state(UPDATING);
+        event = new VplsStoreEvent(VplsStoreEvent.Type.UPDATE, vplsData);
+        vplsStore.delegate().notify(event);
+        vplsOperation = vplsOperationService.operation();
+        assertEquals(vplsOperation.op(), VplsOperation.Operation.UPDATE);
+        assertEquals(vplsOperation.vpls(), vplsData);
+        vplsOperationService.clear();
+
+        // Update state (no operation)
+        vplsData.state(VplsData.VplsState.ADDED);
+        event = new VplsStoreEvent(VplsStoreEvent.Type.UPDATE, vplsData);
+        vplsStore.delegate().notify(event);
+        vplsOperation = vplsOperationService.operation();
+        assertNull(vplsOperation);
+        vplsOperationService.clear();
+
+        // Remove
+        event = new VplsStoreEvent(VplsStoreEvent.Type.REMOVE, vplsData);
+        vplsStore.delegate().notify(event);
+        vplsOperation = vplsOperationService.operation();
+        assertEquals(vplsOperation.op(), VplsOperation.Operation.REMOVE);
+        assertEquals(vplsOperation.vpls(), vplsData);
+        vplsOperationService.clear();
+    }
+
+    /**
+     * Trigger host event listener by HOST_ADDED event.
+     */
+    @Test
+    public void hostAddEventTest() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.addInterface(vplsData, V100H1);
+        HostEvent hostEvent = new HostEvent(HostEvent.Type.HOST_ADDED, V100HOST1);
+        hostService.postHostEvent(hostEvent);
+
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertEquals(UPDATING, vplsData.state());
+    }
+
+    /**
+     * Trigger host event listener by HOST_REMOVED event.
+     */
+    @Test
+    public void hostRemoveEventTest() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.addInterface(vplsData, V100H1);
+        HostEvent hostEvent = new HostEvent(HostEvent.Type.HOST_REMOVED, V100HOST1);
+        hostService.postHostEvent(hostEvent);
+
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertEquals(UPDATING, vplsData.state());
+    }
+
+    /**
+     * Test VPLS operation service.
+     * Stores last operation submitted by VPLS manager.
+     */
+    class TestVplsOperationService implements VplsOperationService {
+        VplsOperation operation;
+
+        @Override
+        public void submit(VplsOperation vplsOperation) {
+            this.operation = vplsOperation;
+        }
+
+        /**
+         * Clears the VPLS operation.
+         */
+        public void clear() {
+            operation = null;
+        }
+
+        /**
+         * Gets the latest VPLS operation.
+         * @return the latest VPLS operation.
+         */
+        public VplsOperation operation() {
+            return operation;
+        }
+    }
+
+}