VOL-2649 Remove cordconfig dependency in mcast app by directly using Sadis

Change-Id: I672b422d592ea5962309b17258d5c363dc5fcfe2
diff --git a/pom.xml b/pom.xml
index fd7bcef..4d6d098 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,9 +37,8 @@
         <onos.app.category>Traffic Steering</onos.app.category>
         <onos.app.title>CORD Multicast App</onos.app.title>
         <onos.app.url>http://opencord.org</onos.app.url>
-        <onos.app.requires>org.opencord.config</onos.app.requires>
-        <cord.config.version>2.0.0-SNAPSHOT</cord.config.version>
         <olt.api.version>4.0.0-SNAPSHOT</olt.api.version>
+        <sadis.api.version>5.0.0</sadis.api.version>
     </properties>
 
     <dependencies>
@@ -64,8 +63,8 @@
         </dependency>
         <dependency>
             <groupId>org.opencord</groupId>
-            <artifactId>cord-config</artifactId>
-            <version>${cord.config.version}</version>
+            <artifactId>sadis-api</artifactId>
+            <version>${sadis.api.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/src/main/java/org/opencord/cordmcast/CordMcast.java b/src/main/java/org/opencord/cordmcast/CordMcast.java
index bd10980..108ceda 100644
--- a/src/main/java/org/opencord/cordmcast/CordMcast.java
+++ b/src/main/java/org/opencord/cordmcast/CordMcast.java
@@ -18,6 +18,9 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.onosproject.net.Device;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
@@ -67,8 +70,6 @@
 import org.onosproject.store.service.Serializer;
 import org.onosproject.store.service.StorageService;
 import org.onosproject.store.service.Versioned;
-import org.opencord.cordconfig.CordConfigService;
-import org.opencord.cordconfig.access.AccessDeviceData;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 
@@ -124,9 +125,6 @@
     protected ComponentConfigService componentConfigService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected CordConfigService cordConfigService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected NetworkConfigRegistry networkConfig;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
@@ -144,6 +142,9 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     private LeadershipService leadershipService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected SadisService sadisService;
+
     protected McastListener listener = new InternalMulticastListener();
     private InternalNetworkConfigListener configListener =
             new InternalNetworkConfigListener();
@@ -381,7 +382,7 @@
             return;
         }
 
-        Optional<AccessDeviceData> oltInfo = cordConfigService.getAccessDevice(sink.deviceId());
+        Optional<SubscriberAndDeviceInformation> oltInfo = getSubscriberAndDeviceInformation(sink.deviceId());
 
         if (!oltInfo.isPresent()) {
             log.warn("Unknown OLT device : {}", sink.deviceId());
@@ -432,7 +433,7 @@
             return;
         }
 
-        Optional<AccessDeviceData> oltInfo = cordConfigService.getAccessDevice(sink.deviceId());
+        Optional<SubscriberAndDeviceInformation> oltInfo = getSubscriberAndDeviceInformation(sink.deviceId());
 
         if (!oltInfo.isPresent()) {
             log.warn("Unknown OLT device : {}", sink.deviceId());
@@ -487,6 +488,40 @@
         }
     }
 
+    /**
+     * Fetches device information associated with the device serial number from SADIS.
+     *
+     * @param serialNumber serial number of a device
+     * @return device information; an empty Optional otherwise.
+     */
+    private Optional<SubscriberAndDeviceInformation> getSubscriberAndDeviceInformation(String serialNumber) {
+        long start = System.currentTimeMillis();
+        try {
+            return Optional.ofNullable(sadisService.getSubscriberInfoService().get(serialNumber));
+        } finally {
+            if (log.isDebugEnabled()) {
+                // SADIS may call remote systems to fetch device data and this calls can take a long time.
+                // This measurement is just for monitoring these kinds of situations.
+                log.debug("Device fetched from SADIS. Elapsed {} msec", System.currentTimeMillis() - start);
+            }
+
+        }
+    }
+
+    /**
+     * Fetches device information associated with the device serial number from SADIS.
+     *
+     * @param deviceId device id
+     * @return device information; an empty Optional otherwise.
+     */
+    private Optional<SubscriberAndDeviceInformation> getSubscriberAndDeviceInformation(DeviceId deviceId) {
+        Device device = deviceService.getDevice(deviceId);
+        if (device == null || device.serialNumber() == null) {
+            return Optional.empty();
+        }
+        return getSubscriberAndDeviceInformation(device.serialNumber());
+    }
+
     private class InternalNetworkConfigListener implements NetworkConfigListener {
         @Override
         public void event(NetworkConfigEvent event) {
diff --git a/src/test/java/org/opencord/cordmcast/McastTest.java b/src/test/java/org/opencord/cordmcast/McastTest.java
index ea4d33b..c8be3b2 100644
--- a/src/test/java/org/opencord/cordmcast/McastTest.java
+++ b/src/test/java/org/opencord/cordmcast/McastTest.java
@@ -39,7 +39,6 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.HostId;
 import org.onosproject.net.config.NetworkConfigRegistryAdapter;
-import org.onosproject.net.device.DeviceServiceAdapter;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.criteria.IPCriterion;
@@ -67,9 +66,9 @@
       cordMcast.coreService = new MockCoreService();
       cordMcast.flowObjectiveService = new MockFlowObjectiveService();
       cordMcast.mastershipService = new TestMastershipService();
-      cordMcast.deviceService = new DeviceServiceAdapter();
+      cordMcast.deviceService = new MockDeviceService();
       cordMcast.networkConfig = new NetworkConfigRegistryAdapter();
-      cordMcast.cordConfigService = new MockCordConfigService();
+      cordMcast.sadisService = new MockSadisService();
 
       cordMcast.storageService =
              EasyMock.createMock(StorageServiceAdapter.class);
diff --git a/src/test/java/org/opencord/cordmcast/McastTestBase.java b/src/test/java/org/opencord/cordmcast/McastTestBase.java
index 273c862..ef04165 100644
--- a/src/test/java/org/opencord/cordmcast/McastTestBase.java
+++ b/src/test/java/org/opencord/cordmcast/McastTestBase.java
@@ -15,27 +15,32 @@
  */
 package org.opencord.cordmcast;
 
-import java.io.IOException;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
 
+import org.onlab.packet.Ip4Address;
 import org.onlab.packet.IpAddress;
-import org.onlab.packet.VlanId;
 import org.onosproject.TestApplicationId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreServiceAdapter;
 import org.onosproject.mastership.MastershipServiceAdapter;
 import org.onosproject.mcast.api.McastRoute;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Annotations;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.HostId;
 import org.onosproject.net.PortNumber;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.device.DeviceServiceAdapter;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.criteria.Criterion;
@@ -45,14 +50,12 @@
 import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
 import org.onosproject.net.flowobjective.ForwardingObjective;
 import org.onosproject.net.flowobjective.NextObjective;
-import org.opencord.cordconfig.CordConfigListener;
-import org.opencord.cordconfig.CordConfigService;
-import org.opencord.cordconfig.access.AccessAgentData;
-import org.opencord.cordconfig.access.AccessDeviceData;
 
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.ImmutableMap;
+import org.opencord.sadis.BandwidthProfileInformation;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
 
 public class McastTestBase {
 
@@ -72,6 +75,10 @@
      protected static final ConnectPoint CONNECT_POINT_B = new ConnectPoint(DEVICE_ID_OF_A, PORT_B);
      protected static final ConnectPoint CONNECT_POINT_C = new ConnectPoint(DEVICE_ID_OF_A, PORT_C);
 
+     // serial number of the device A
+     protected static final String SERIAL_NUMBER_OF_DEVICE_A = "serialNumberOfDevA";
+     // Management ip address of the device A
+     protected static final Ip4Address MANAGEMENT_IP_OF_A = Ip4Address.valueOf("10.177.125.4");
      //Host id configuration
      protected static final HostId HOST_ID_NONE = HostId.NONE;
      // Source connect point
@@ -123,65 +130,70 @@
           }
      }
 
-     class MockCordConfigService implements CordConfigService {
+    protected class MockSadisService implements SadisService {
 
-          @Override
-          public void addListener(CordConfigListener listener) {
+        @Override
+        public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
+            return new MockSubService();
+        }
 
-          }
+        @Override
+        public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
+            return null;
+        }
+    }
 
-          @Override
-          public void removeListener(CordConfigListener listener) {
+    private class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
+        MockSubscriberAndDeviceInformation deviceA =
+                new MockSubscriberAndDeviceInformation(SERIAL_NUMBER_OF_DEVICE_A, MANAGEMENT_IP_OF_A);
 
-          }
+        @Override
+        public SubscriberAndDeviceInformation get(String id) {
+            return SERIAL_NUMBER_OF_DEVICE_A.equals(id) ? deviceA : null;
+        }
 
-          @Override
-          public Set<AccessDeviceData> getAccessDevices() {
+        @Override
+        public void invalidateAll() {
+        }
 
-               return null;
-          }
+        @Override
+        public void invalidateId(String id) {
+        }
 
-          @Override
-          public Optional<AccessDeviceData> getAccessDevice(DeviceId deviceId) {
-             if (deviceId == DEVICE_ID_OF_A) {
-               PortNumber uplink = PortNumber.portNumber(3);
-               VlanId vlan = VlanId.vlanId((short) 0);
-               ObjectMapper mapper = new ObjectMapper();
-               JsonNode defaultVlanNode = null;
-               try {
-                    defaultVlanNode =
-                    (JsonNode) mapper.readTree("{\"driver\":\"pmc-olt\" , \"type \" : \"OLT\"}");
-               } catch (IOException e) {
-                    e.printStackTrace();
-               }
+        @Override
+        public SubscriberAndDeviceInformation getfromCache(String id) {
+            return null;
+        }
+    }
 
-               Optional<VlanId> defaultVlan;
-               if (defaultVlanNode.isMissingNode()) {
-                    defaultVlan = Optional.empty();
-               } else {
-                    defaultVlan = Optional.of(VlanId.vlanId(defaultVlanNode.shortValue()));
-               }
-               Optional<AccessDeviceData> accessDeviceData = null;
-               AccessDeviceData accessDevice = new AccessDeviceData(deviceId, uplink, vlan, defaultVlan);
-               accessDeviceData = Optional.of(accessDevice);
-               return accessDeviceData;
-             } else {
-                 knownOltFlag = true;
-                 return Optional.empty();
-             }
-          }
+    private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
 
-          @Override
-          public Set<AccessAgentData> getAccessAgents() {
-               return null;
-          }
+        MockSubscriberAndDeviceInformation(String id, Ip4Address ipAddress) {
+            this.setId(id);
+            this.setIPAddress(ipAddress);
+            this.setUplinkPort((int) PORT_A.toLong());
+        }
+    }
 
-          @Override
-          public Optional<AccessAgentData> getAccessAgent(DeviceId deviceId) {
-               return null;
-          }
+    class MockDeviceService extends DeviceServiceAdapter {
 
-     }
+        @Override
+        public Device getDevice(DeviceId deviceId) {
+            if (DEVICE_ID_OF_A.equals(deviceId)) {
+                DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
+                        .set(AnnotationKeys.MANAGEMENT_ADDRESS, MANAGEMENT_IP_OF_A.toString());
+                SparseAnnotations annotations = annotationsBuilder.build();
+                Annotations[] da = {annotations};
+
+                Device deviceA = new DefaultDevice(null, DEVICE_ID_OF_A, Device.Type.OTHER, "", "",
+                        "", SERIAL_NUMBER_OF_DEVICE_A, null, da);
+                return deviceA;
+            } else {
+                knownOltFlag = true;
+            }
+            return null;
+        }
+    }
 
      public OutputInstruction outputPort(TrafficTreatment trafficTreatment) {
          List<Instruction> listOfInstructions = trafficTreatment.allInstructions();