[ONOS-4045]Adding mastership service to NetconfProvider

Change-Id: Id39cbef54a079ab6e080a9d3f60770c4bea90b3f
diff --git a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java
index 99ef8ce..432329b 100644
--- a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java
+++ b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java
@@ -19,9 +19,16 @@
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
 import org.onlab.packet.IpAddress;
+import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.key.DeviceKeyId;
+import org.onosproject.net.key.DeviceKeyService;
+import org.onosproject.net.key.UsernamePassword;
 import org.onosproject.netconf.NetconfController;
 import org.onosproject.netconf.NetconfDevice;
 import org.onosproject.netconf.NetconfDeviceFactory;
@@ -34,6 +41,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Arrays;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -45,6 +53,11 @@
 @Component(immediate = true)
 @Service
 public class NetconfControllerImpl implements NetconfController {
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceKeyService deviceKeyService;
 
     public static final Logger log = LoggerFactory
             .getLogger(NetconfControllerImpl.class);
@@ -95,55 +108,93 @@
     }
 
     @Override
-    public NetconfDevice connectDevice(NetconfDeviceInfo deviceInfo) throws NetconfException {
-        if (netconfDeviceMap.containsKey(deviceInfo.getDeviceId())) {
-            log.info("Device {} is already present", deviceInfo);
-            return netconfDeviceMap.get(deviceInfo.getDeviceId());
+    public NetconfDevice connectDevice(DeviceId deviceId) throws NetconfException {
+        if (netconfDeviceMap.containsKey(deviceId)) {
+            log.debug("Device {} is already present", deviceId);
+            return netconfDeviceMap.get(deviceId);
         } else {
-            log.info("Creating NETCONF device {}", deviceInfo);
-            NetconfDevice device = createDevice(deviceInfo);
-            device.getSession().addDeviceOutputListener(downListener);
-            return device;
+            log.debug("Creating NETCONF device {}", deviceId);
+            Device device = deviceService.getDevice(deviceId);
+            String ip;
+            int port;
+            if (device != null) {
+                ip = device.annotations().value("ipaddress");
+                port = Integer.parseInt(device.annotations().value("port"));
+            } else {
+                String[] info = deviceId.toString().split(":");
+                if (info.length == 3) {
+                    ip = info[1];
+                    port = Integer.parseInt(info[2]);
+                } else {
+                    ip = Arrays.asList(info).stream().filter(el -> !el.equals(info[0])
+                    && !el.equals(info[info.length - 1]))
+                            .reduce((t, u) -> t + ":" + u)
+                            .get();
+                    log.debug("ip v6 {}", ip);
+                    port = Integer.parseInt(info[info.length - 1]);
+                }
+            }
+            try {
+                UsernamePassword deviceKey = deviceKeyService.getDeviceKey(
+                        DeviceKeyId.deviceKeyId(deviceId.toString())).asUsernamePassword();
+
+                NetconfDeviceInfo deviceInfo = new NetconfDeviceInfo(deviceKey.username(),
+                                                                     deviceKey.password(),
+                                                                     IpAddress.valueOf(ip),
+                                                                     port);
+                NetconfDevice netconfDevicedevice = createDevice(deviceInfo);
+
+                netconfDevicedevice.getSession().addDeviceOutputListener(downListener);
+                return netconfDevicedevice;
+            } catch (NullPointerException e) {
+                throw new NetconfException("No Device Key for device " + deviceId, e);
+            }
         }
     }
 
     @Override
-    public void disconnectDevice(NetconfDeviceInfo deviceInfo) {
-        if (!netconfDeviceMap.containsKey(deviceInfo.getDeviceId())) {
-            log.warn("Device {} is not present", deviceInfo);
+    public void disconnectDevice(DeviceId deviceId, boolean remove) {
+        if (!netconfDeviceMap.containsKey(deviceId)) {
+            log.warn("Device {} is not present", deviceId);
         } else {
-            stopDevice(deviceInfo);
+            stopDevice(deviceId, remove);
         }
     }
 
-    @Override
-    public void removeDevice(NetconfDeviceInfo deviceInfo) {
-        if (!netconfDeviceMap.containsKey(deviceInfo.getDeviceId())) {
-            log.warn("Device {} is not present", deviceInfo);
-        } else {
-            netconfDeviceMap.remove(deviceInfo.getDeviceId());
+    private void stopDevice(DeviceId deviceId, boolean remove) {
+        netconfDeviceMap.get(deviceId).disconnect();
+        netconfDeviceMap.remove(deviceId);
+        if (remove) {
             for (NetconfDeviceListener l : netconfDeviceListeners) {
-                l.deviceRemoved(deviceInfo);
+                l.deviceRemoved(deviceId);
+            }
+        }
+    }
+
+    @Override
+    public void removeDevice(DeviceId deviceId) {
+        if (!netconfDeviceMap.containsKey(deviceId)) {
+            log.warn("Device {} is not present", deviceId);
+            for (NetconfDeviceListener l : netconfDeviceListeners) {
+                l.deviceRemoved(deviceId);
+            }
+        } else {
+            netconfDeviceMap.remove(deviceId);
+            for (NetconfDeviceListener l : netconfDeviceListeners) {
+                l.deviceRemoved(deviceId);
             }
         }
     }
 
     private NetconfDevice createDevice(NetconfDeviceInfo deviceInfo) throws NetconfException {
         NetconfDevice netconfDevice = deviceFactory.createNetconfDevice(deviceInfo);
-        for (NetconfDeviceListener l : netconfDeviceListeners) {
-            l.deviceAdded(deviceInfo);
-        }
         netconfDeviceMap.put(deviceInfo.getDeviceId(), netconfDevice);
+        for (NetconfDeviceListener l : netconfDeviceListeners) {
+            l.deviceAdded(deviceInfo.getDeviceId());
+        }
         return netconfDevice;
     }
 
-    private void stopDevice(NetconfDeviceInfo deviceInfo) {
-        netconfDeviceMap.get(deviceInfo.getDeviceId()).disconnect();
-        netconfDeviceMap.remove(deviceInfo.getDeviceId());
-        for (NetconfDeviceListener l : netconfDeviceListeners) {
-            l.deviceRemoved(deviceInfo);
-        }
-    }
 
     @Override
     public Map<DeviceId, NetconfDevice> getDevicesMap() {
@@ -155,6 +206,8 @@
         return netconfDeviceMap.keySet();
     }
 
+
+
     //Device factory for the specific NetconfDeviceImpl
     private class DefaultNetconfDeviceFactory implements NetconfDeviceFactory {
 
@@ -171,7 +224,7 @@
         @Override
         public void event(NetconfDeviceOutputEvent event) {
             if (event.type().equals(NetconfDeviceOutputEvent.Type.DEVICE_UNREGISTERED)) {
-                removeDevice(event.getDeviceInfo());
+                removeDevice(event.getDeviceInfo().getDeviceId());
             }
         }