[ONOS-5751] Initial implementation of LISP mapping provider

Change-Id: Ibddfc9f92e4d385c9995e7baa3613a2562499fbf
diff --git a/providers/lisp/mapping/BUCK b/providers/lisp/mapping/BUCK
index a711177..7e4bb9d 100644
--- a/providers/lisp/mapping/BUCK
+++ b/providers/lisp/mapping/BUCK
@@ -2,8 +2,16 @@
     '//lib:CORE_DEPS',
     '//protocols/lisp/api:onos-protocols-lisp-api',
     '//protocols/lisp/msg:onos-protocols-lisp-msg',
+    '//apps/mappingmanagement/api:onos-apps-mappingmanagement-api',
+]
+
+TEST_DEPS = [
+    '//lib:TEST_ADAPTERS',
+    '//protocols/lisp/api:onos-protocols-lisp-api-tests',
+    '//apps/mappingmanagement/api:onos-apps-mappingmanagement-api-tests',
 ]
 
 osgi_jar_with_tests (
     deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
 )
diff --git a/providers/lisp/mapping/pom.xml b/providers/lisp/mapping/pom.xml
index 2cea3c2..61f8cee 100644
--- a/providers/lisp/mapping/pom.xml
+++ b/providers/lisp/mapping/pom.xml
@@ -39,6 +39,8 @@
             <groupId>org.onosproject</groupId>
             <artifactId>onos-lisp-api</artifactId>
             <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
@@ -50,5 +52,17 @@
             <artifactId>onos-lisp-msg</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-mapping-api</artifactId>
+            <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/impl/LispMappingProvider.java b/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/impl/LispMappingProvider.java
index 7c6d016..09bf3e6 100644
--- a/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/impl/LispMappingProvider.java
+++ b/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/impl/LispMappingProvider.java
@@ -24,9 +24,17 @@
 import org.onosproject.lisp.ctl.LispMessageListener;
 import org.onosproject.lisp.ctl.LispRouterId;
 import org.onosproject.lisp.ctl.LispRouterListener;
+import org.onosproject.lisp.msg.protocols.LispMapNotify;
+import org.onosproject.lisp.msg.protocols.LispMapReply;
 import org.onosproject.lisp.msg.protocols.LispMessage;
+import org.onosproject.mapping.MappingEntry;
+import org.onosproject.mapping.MappingProvider;
+import org.onosproject.mapping.MappingProviderRegistry;
+import org.onosproject.mapping.MappingProviderService;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.provider.AbstractProvider;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.provider.lisp.mapping.util.MappingEntryBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -34,13 +42,18 @@
  * Provider which uses a LISP controller to manage EID-RLOC mapping.
  */
 @Component(immediate = true)
-public class LispMappingProvider extends AbstractProvider {
+public class LispMappingProvider extends AbstractProvider implements MappingProvider {
 
     private static final Logger log = LoggerFactory.getLogger(LispMappingProvider.class);
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected LispController controller;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MappingProviderRegistry providerRegistry;
+
+    protected MappingProviderService providerService;
+
     private static final String SCHEME_NAME = "lisp";
     private static final String MAPPING_PROVIDER_PACKAGE =
                                 "org.onosproject.lisp.provider.mapping";
@@ -57,6 +70,8 @@
     @Activate
     public void activate() {
 
+        providerService = providerRegistry.register(this);
+
         // listens all LISP router related events
         controller.addRouterListener(listener);
 
@@ -69,12 +84,16 @@
     @Deactivate
     public void deactivate() {
 
+        providerRegistry.unregister(this);
+
         // stops listening all LISP router related events
         controller.removeRouterListener(listener);
 
         // stops listening all LISP control messages
         controller.removeMessageListener(listener);
 
+        providerService = null;
+
         log.info("Stopped");
     }
 
@@ -106,7 +125,31 @@
 
         @Override
         public void handleOutgoingMessage(LispRouterId routerId, LispMessage msg) {
+            if (providerService == null) {
+                // We are shutting down, nothing to be done
+                return;
+            }
 
+            DeviceId deviceId = DeviceId.deviceId(routerId.toString());
+            switch (msg.getType()) {
+
+                case LISP_MAP_REPLY:
+                    LispMapReply reply = (LispMapReply) msg;
+
+                    MappingEntry replyMe = new MappingEntryBuilder(deviceId, reply).build();
+                    providerService.mappingAdded(replyMe, false);
+                    break;
+
+                case LISP_MAP_NOTIFY:
+                    LispMapNotify notify = (LispMapNotify) msg;
+
+                    MappingEntry notifyMe = new MappingEntryBuilder(deviceId, notify).build();
+                    providerService.mappingAdded(notifyMe, true);
+                    break;
+
+                default:
+                    log.warn("Unhandled message type: {}", msg.getType());
+            }
         }
     }
 }
diff --git a/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilder.java b/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilder.java
new file mode 100644
index 0000000..12a58e4
--- /dev/null
+++ b/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilder.java
@@ -0,0 +1,63 @@
+/*
+ * 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.provider.lisp.mapping.util;
+
+import org.onosproject.lisp.msg.protocols.LispMapNotify;
+import org.onosproject.lisp.msg.protocols.LispMapReply;
+import org.onosproject.mapping.MappingEntry;
+import org.onosproject.net.DeviceId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Mapping entry builder class.
+ */
+public class MappingEntryBuilder {
+    private static final Logger log = LoggerFactory.getLogger(MappingEntryBuilder.class);
+
+    private final DeviceId deviceId;
+    private final LispMapReply mapReply;
+    private final LispMapNotify mapNotify;
+
+    /**
+     * Default constructor for MappingEntryBuilder.
+     *
+     * @param deviceId device identifier
+     * @param mapReply map reply message
+     */
+    public MappingEntryBuilder(DeviceId deviceId, LispMapReply mapReply) {
+        this.deviceId = deviceId;
+        this.mapReply = mapReply;
+        this.mapNotify = null;
+    }
+
+    /**
+     * Default constructor for MappingEntryBuilder.
+     *
+     * @param deviceId  device identifier
+     * @param mapNotify map notify message
+     */
+    public MappingEntryBuilder(DeviceId deviceId, LispMapNotify mapNotify) {
+        this.deviceId = deviceId;
+        this.mapNotify = mapNotify;
+        this.mapReply = null;
+    }
+
+    public MappingEntry build() {
+        // TODO: provide a way to build mapping entry from input parameters
+        return null;
+    }
+}
diff --git a/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/package-info.java b/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/package-info.java
new file mode 100644
index 0000000..8538009
--- /dev/null
+++ b/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * LISP provider utility package.
+ */
+package org.onosproject.provider.lisp.mapping.util;
\ No newline at end of file
diff --git a/providers/lisp/mapping/src/test/java/org/onosproject/provider/lisp/mapping/impl/LispMappingProviderTest.java b/providers/lisp/mapping/src/test/java/org/onosproject/provider/lisp/mapping/impl/LispMappingProviderTest.java
new file mode 100644
index 0000000..7278efb
--- /dev/null
+++ b/providers/lisp/mapping/src/test/java/org/onosproject/provider/lisp/mapping/impl/LispMappingProviderTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.provider.lisp.mapping.impl;
+
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.lisp.ctl.LispController;
+import org.onosproject.lisp.ctl.LispControllerAdapter;
+import org.onosproject.lisp.ctl.LispRouter;
+import org.onosproject.lisp.ctl.LispRouterListener;
+import org.onosproject.mapping.MappingProvider;
+import org.onosproject.mapping.MappingProviderRegistry;
+import org.onosproject.mapping.MappingProviderRegistryAdapter;
+import org.onosproject.mapping.MappingProviderService;
+import org.onosproject.mapping.MappingProviderServiceAdapter;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.Set;
+
+import static junit.framework.TestCase.assertFalse;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * LISP mapping provider unit test.
+ */
+public class LispMappingProviderTest {
+
+
+    private final LispMappingProvider provider = new LispMappingProvider();
+    private final LispController controller = new MockLispController();
+
+    // provider mocks
+    private final MappingProviderRegistry providerRegistry =
+                                            new MockMappingProviderRegistry();
+    private final MappingProviderService providerService =
+                                            new MockMappingProviderService();
+
+    private final Set<LispRouterListener> routerListeners = Sets.newCopyOnWriteArraySet();
+
+
+    @Before
+    public void setUp() {
+        provider.providerRegistry = providerRegistry;
+        provider.controller = controller;
+        provider.activate();
+    }
+
+    @Test
+    public void activate() throws Exception {
+        assertEquals("Provider should be registered", 1,
+                        providerRegistry.getProviders().size());
+        assertTrue("LISP device provider should be registered",
+                        providerRegistry.getProviders().contains(provider.id()));
+        assertEquals("Incorrect provider service",
+                        providerService, provider.providerService);
+        assertEquals("LISP router listener should be registered", 1,
+                routerListeners.size());
+    }
+
+    @Test
+    public void deactivate() throws Exception {
+        provider.deactivate();
+
+        assertFalse("Provider should not be registered",
+                            providerRegistry.getProviders().contains(provider));
+        assertNull("Provider service should be null",
+                            provider.providerService);
+        assertEquals("Controller listener should be removed", 0,
+                            routerListeners.size());
+    }
+
+    /**
+     * Mock class for LispController.
+     */
+    private class MockLispController extends LispControllerAdapter {
+
+        Iterable<LispRouter> routers = Sets.newHashSet();
+
+        @Override
+        public Iterable<LispRouter> getRouters() {
+            return routers;
+        }
+
+        @Override
+        public void addRouterListener(LispRouterListener listener) {
+            if (!routerListeners.contains(listener)) {
+                routerListeners.add(listener);
+            }
+        }
+
+        @Override
+        public void removeRouterListener(LispRouterListener listener) {
+            routerListeners.remove(listener);
+        }
+
+    }
+
+    /**
+     * Mock class for MappingProviderRegistry.
+     */
+    private class MockMappingProviderRegistry extends MappingProviderRegistryAdapter {
+        Set<ProviderId> providers = Sets.newHashSet();
+
+        @Override
+        public MappingProviderService register(MappingProvider provider) {
+            providers.add(provider.id());
+            return providerService;
+        }
+
+        @Override
+        public void unregister(MappingProvider provider) {
+            providers.remove(provider.id());
+        }
+
+        @Override
+        public Set<ProviderId> getProviders() {
+            return providers;
+        }
+    }
+
+    /**
+     * Mock class for MappingService.
+     */
+    private class MockMappingProviderService extends MappingProviderServiceAdapter {
+
+    }
+}
diff --git a/providers/lisp/pom.xml b/providers/lisp/pom.xml
index b83bedc..4898309 100644
--- a/providers/lisp/pom.xml
+++ b/providers/lisp/pom.xml
@@ -44,6 +44,11 @@
             <classifier>tests</classifier>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-mapping-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 
 </project>