[ONOS-7566] Implementation of NetconfProxySession

Change-Id: I01cbe0b10ac36cb6db53127555b551f405acdeb1
diff --git a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/DefaultNetconfDevice.java b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/DefaultNetconfDevice.java
index c952027..dfbe760 100644
--- a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/DefaultNetconfDevice.java
+++ b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/DefaultNetconfDevice.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.netconf.ctl.impl;
 
+import org.onosproject.netconf.NetconfController;
 import org.onosproject.netconf.NetconfDevice;
 import org.onosproject.netconf.NetconfDeviceInfo;
 import org.onosproject.netconf.NetconfException;
@@ -34,24 +35,37 @@
 
     private NetconfDeviceInfo netconfDeviceInfo;
     private boolean deviceState = true;
-    private final NetconfSessionFactory sessionFactory;
     private NetconfSession netconfSession;
+    private boolean isMasterSession = false;
+    private NetconfSession netconfProxySession;
 
     // will block until hello RPC handshake completes
     /**
      * Creates a new default NETCONF device with the information provided.
      * The device gets created only if no exception is thrown while connecting to
      * it and establishing the NETCONF session.
+     * The secure transport session will only be created if isMaster is true.
      * @param deviceInfo information about the device to be created.
+     * @param isMaster if true create secure transport session, otherwise create proxy session.
+     * @param netconfController netconf controller object
      * @throws NetconfException if there are problems in creating or establishing
      * the underlying NETCONF connection and session.
      */
-    public DefaultNetconfDevice(NetconfDeviceInfo deviceInfo)
+    public DefaultNetconfDevice(NetconfDeviceInfo deviceInfo,
+                                boolean isMaster,
+                                NetconfController netconfController)
             throws NetconfException {
         netconfDeviceInfo = deviceInfo;
-        sessionFactory = (ncDevInfo) -> new NetconfSessionMinaImpl(ncDevInfo);
         try {
-            netconfSession = sessionFactory.createNetconfSession(deviceInfo);
+            if (isMaster) {
+                netconfSession = new NetconfSessionMinaImpl(deviceInfo);
+                isMasterSession = true;
+                netconfProxySession = netconfSession;
+            } else {
+                netconfProxySession = new NetconfSessionProxyImpl
+                        .ProxyNetconfSessionFactory()
+                        .createNetconfSession(deviceInfo, netconfController);
+            }
         } catch (NetconfException e) {
             deviceState = false;
             throw new NetconfException("Cannot create connection and session for device " +
@@ -64,18 +78,30 @@
      * Creates a new default NETCONF device with the information provided.
      * The device gets created only if no exception is thrown while connecting to
      * it and establishing the NETCONF session.
-     *
+     * The secure transport session will only be created if isMaster is true.
      * @param deviceInfo information about the device to be created.
      * @param factory the factory used to create the session
+     * @param isMaster if true create secure transport session, otherwise create proxy session.
+     * @param netconfController netconf controller object
      * @throws NetconfException if there are problems in creating or establishing
      * the underlying NETCONF connection and session.
      */
-    public DefaultNetconfDevice(NetconfDeviceInfo deviceInfo, NetconfSessionFactory factory)
+    public DefaultNetconfDevice(NetconfDeviceInfo deviceInfo,
+                                NetconfSessionFactory factory,
+                                boolean isMaster,
+                                NetconfController netconfController)
             throws NetconfException {
         netconfDeviceInfo = deviceInfo;
-        sessionFactory = factory;
         try {
-            netconfSession = sessionFactory.createNetconfSession(deviceInfo);
+            if (isMaster) {
+                netconfSession = factory.createNetconfSession(deviceInfo, netconfController);
+                isMasterSession = true;
+                netconfProxySession = netconfSession;
+            } else {
+                netconfProxySession = new NetconfSessionProxyImpl
+                        .ProxyNetconfSessionFactory()
+                        .createNetconfSession(deviceInfo, netconfController);
+            }
         } catch (NetconfException e) {
             deviceState = false;
             throw new NetconfException("Cannot create connection and session for device " +
@@ -90,23 +116,29 @@
 
     @Override
     public NetconfSession getSession() {
-        return netconfSession;
+        return netconfProxySession;
     }
 
     @Override
     public void disconnect() {
         deviceState = false;
         try {
-            netconfSession.close();
+            if (isMasterSession) {
+                netconfSession.close();
+            }
+            netconfProxySession.close();
         } catch (NetconfException e) {
             log.warn("Cannot communicate with the device {} session already closed", netconfDeviceInfo);
         }
     }
 
     @Override
+    public boolean isMasterSession() {
+        return isMasterSession;
+    }
+
+    @Override
     public NetconfDeviceInfo getDeviceInfo() {
         return netconfDeviceInfo;
     }
-
-
 }