NetconfSession refactoring

- Move netconf rpc envelope processing common across secure transport implementation
  to AbstractNetconfSession
  work by: Palash Kala <palash.kala@samsung.com>

Change-Id: I5f0d6adecf6224ae44f224291f645725b3c87739
diff --git a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfSessionMinaImpl.java b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfSessionMinaImpl.java
index 846ec26..56818a3 100644
--- a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfSessionMinaImpl.java
+++ b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfSessionMinaImpl.java
@@ -33,7 +33,7 @@
 import org.bouncycastle.openssl.PEMKeyPair;
 import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
 import org.onlab.util.SharedExecutors;
-import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.AbstractNetconfSession;
 import org.onosproject.netconf.NetconfDeviceInfo;
 import org.onosproject.netconf.NetconfDeviceOutputEvent;
 import org.onosproject.netconf.NetconfDeviceOutputEvent.Type;
@@ -75,7 +75,7 @@
 /**
  * Implementation of a NETCONF session to talk to a device.
  */
-public class NetconfSessionMinaImpl implements NetconfSession {
+public class NetconfSessionMinaImpl extends AbstractNetconfSession {
 
     private static final Logger log = getLogger(NetconfSessionMinaImpl.class);
 
@@ -89,29 +89,11 @@
     private static final String END_OF_RPC_OPEN_TAG = "\">";
     private static final String EQUAL = "=";
     private static final String NUMBER_BETWEEN_QUOTES_MATCHER = "\"+([0-9]+)+\"";
-    private static final String RPC_OPEN = "<rpc ";
-    private static final String RPC_CLOSE = "</rpc>";
-    private static final String GET_OPEN = "<get>";
-    private static final String GET_CLOSE = "</get>";
-    private static final String WITH_DEFAULT_OPEN = "<with-defaults ";
-    private static final String WITH_DEFAULT_CLOSE = "</with-defaults>";
-    private static final String DEFAULT_OPERATION_OPEN = "<default-operation>";
-    private static final String DEFAULT_OPERATION_CLOSE = "</default-operation>";
-    private static final String SUBTREE_FILTER_OPEN = "<filter type=\"subtree\">";
     private static final String SUBTREE_FILTER_CLOSE = "</filter>";
-    private static final String EDIT_CONFIG_OPEN = "<edit-config>";
-    private static final String EDIT_CONFIG_CLOSE = "</edit-config>";
-    private static final String TARGET_OPEN = "<target>";
-    private static final String TARGET_CLOSE = "</target>";
     // FIXME hard coded namespace nc
-    private static final String CONFIG_OPEN = "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
-    private static final String CONFIG_CLOSE = "</config>";
     private static final String XML_HEADER =
             "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
-    private static final String NETCONF_BASE_NAMESPACE =
-            "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"";
-    private static final String NETCONF_WITH_DEFAULTS_NAMESPACE =
-            "xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\"";
+
     // FIXME hard coded namespace base10
     private static final String SUBSCRIPTION_SUBTREE_FILTER_OPEN =
             "<filter xmlns:base10=\"urn:ietf:params:xml:ns:netconf:base:1.0\" base10:type=\"subtree\">";
@@ -212,6 +194,8 @@
         startSession();
     }
 
+    //TODO: Remove the default methods already implemented in NetconfSession
+
     // FIXME blocking
     @Deprecated
     private void startSession() throws IOException {
@@ -316,14 +300,6 @@
         subscriptionConnected = true;
     }
 
-    @Override
-    public void startSubscription() throws NetconfException {
-        if (!subscriptionConnected) {
-            startSubscriptionStream(null);
-        }
-        streamHandler.setEnableNotifications(true);
-    }
-
     @Beta
     @Override
     public void startSubscription(String filterSchema) throws NetconfException {
@@ -642,266 +618,6 @@
     }
 
     @Override
-    public String doWrappedRpc(String request) throws NetconfException {
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append(RPC_OPEN);
-        rpc.append(MESSAGE_ID_STRING);
-        rpc.append(EQUAL);
-        rpc.append("\"");
-        rpc.append(messageIdInteger.get());
-        rpc.append("\"  ");
-        rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
-        rpc.append(request);
-        rpc.append(RPC_CLOSE).append(NEW_LINE);
-        rpc.append(ENDPATTERN);
-        String reply = sendRequest(rpc.toString());
-        checkReply(reply);
-        return reply;
-    }
-
-    @Override
-    public String get(String request) throws NetconfException {
-        return requestSync(request);
-    }
-
-    @Override
-    public String get(String filterSchema, String withDefaultsMode) throws NetconfException {
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append(RPC_OPEN);
-        rpc.append(MESSAGE_ID_STRING);
-        rpc.append(EQUAL);
-        rpc.append("\"");
-        rpc.append(messageIdInteger.get());
-        rpc.append("\"  ");
-        rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
-        rpc.append(GET_OPEN).append(NEW_LINE);
-        if (filterSchema != null) {
-            rpc.append(SUBTREE_FILTER_OPEN).append(NEW_LINE);
-            rpc.append(filterSchema).append(NEW_LINE);
-            rpc.append(SUBTREE_FILTER_CLOSE).append(NEW_LINE);
-        }
-        if (withDefaultsMode != null) {
-            rpc.append(WITH_DEFAULT_OPEN).append(NETCONF_WITH_DEFAULTS_NAMESPACE).append(">");
-            rpc.append(withDefaultsMode).append(WITH_DEFAULT_CLOSE).append(NEW_LINE);
-        }
-        rpc.append(GET_CLOSE).append(NEW_LINE);
-        rpc.append(RPC_CLOSE).append(NEW_LINE);
-        rpc.append(ENDPATTERN);
-        String reply = sendRequest(rpc.toString());
-        checkReply(reply);
-        return reply;
-    }
-
-    @Override
-    public String getConfig(DatastoreId netconfTargetConfig) throws NetconfException {
-        return getConfig(netconfTargetConfig, null);
-    }
-
-    @Override
-    public String getConfig(DatastoreId netconfTargetConfig,
-                            String configurationSchema) throws NetconfException {
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append("<rpc ");
-        rpc.append(MESSAGE_ID_STRING);
-        rpc.append(EQUAL);
-        rpc.append("\"");
-        rpc.append(messageIdInteger.get());
-        rpc.append("\"  ");
-        rpc.append("xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
-        rpc.append("<get-config>\n");
-        rpc.append("<source>\n");
-        rpc.append("<").append(netconfTargetConfig).append("/>");
-        rpc.append("</source>");
-        if (configurationSchema != null) {
-            rpc.append("<filter type=\"subtree\">\n");
-            rpc.append(configurationSchema).append("\n");
-            rpc.append("</filter>\n");
-        }
-        rpc.append("</get-config>\n");
-        rpc.append("</rpc>\n");
-        rpc.append(ENDPATTERN);
-        String reply = sendRequest(rpc.toString());
-        return checkReply(reply) ? reply : "ERROR " + reply;
-    }
-
-    @Override
-    public boolean editConfig(String newConfiguration) throws NetconfException {
-        if (!newConfiguration.endsWith(ENDPATTERN)) {
-            newConfiguration = newConfiguration + ENDPATTERN;
-        }
-        return checkReply(sendRequest(newConfiguration));
-    }
-
-    @Override
-    public boolean editConfig(DatastoreId netconfTargetConfig,
-                              String mode,
-                              String newConfiguration)
-            throws NetconfException {
-
-        newConfiguration = newConfiguration.trim();
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append(RPC_OPEN);
-        rpc.append(MESSAGE_ID_STRING);
-        rpc.append(EQUAL);
-        rpc.append("\"");
-        rpc.append(messageIdInteger.get());
-        rpc.append("\"  ");
-        rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
-        rpc.append(EDIT_CONFIG_OPEN).append("\n");
-        rpc.append(TARGET_OPEN);
-        rpc.append("<").append(netconfTargetConfig).append("/>");
-        rpc.append(TARGET_CLOSE).append("\n");
-        if (mode != null) {
-            rpc.append(DEFAULT_OPERATION_OPEN);
-            rpc.append(mode);
-            rpc.append(DEFAULT_OPERATION_CLOSE).append("\n");
-        }
-        rpc.append(CONFIG_OPEN).append("\n");
-        rpc.append(newConfiguration);
-        rpc.append(CONFIG_CLOSE).append("\n");
-        rpc.append(EDIT_CONFIG_CLOSE).append("\n");
-        rpc.append(RPC_CLOSE);
-        rpc.append(ENDPATTERN);
-        log.debug("{}", rpc);
-        String reply = sendRequest(rpc.toString());
-        return checkReply(reply);
-    }
-
-    @Override
-    public boolean copyConfig(DatastoreId destination,
-                              DatastoreId source)
-            throws NetconfException {
-        return bareCopyConfig(destination.asXml(), source.asXml());
-    }
-
-    @Override
-    public boolean copyConfig(DatastoreId netconfTargetConfig,
-                              String newConfiguration)
-            throws NetconfException {
-        return bareCopyConfig(netconfTargetConfig.asXml(),
-                normalizeCopyConfigParam(newConfiguration));
-    }
-
-    @Override
-    public boolean copyConfig(String netconfTargetConfig,
-                              String newConfiguration) throws NetconfException {
-        return bareCopyConfig(normalizeCopyConfigParam(netconfTargetConfig),
-                normalizeCopyConfigParam(newConfiguration));
-    }
-
-    /**
-     * Normalize String parameter passed to copy-config API.
-     * <p>
-     * Provided for backward compatibility purpose
-     *
-     * @param input passed to copyConfig API
-     * @return XML likely to be suitable for copy-config source or target
-     */
-    private static CharSequence normalizeCopyConfigParam(String input) {
-        input = input.trim();
-        if (input.startsWith("<url")) {
-            return input;
-        } else if (!input.startsWith("<")) {
-            // assume it is a datastore name
-            return DatastoreId.datastore(input).asXml();
-        } else if (!input.startsWith("<config>")) {
-            return "<config>" + input + "</config>";
-        }
-        return input;
-    }
-
-    private boolean bareCopyConfig(CharSequence target,
-                                   CharSequence source)
-            throws NetconfException {
-
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append(RPC_OPEN);
-        rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
-        rpc.append("<copy-config>");
-        rpc.append("<target>");
-        rpc.append(target);
-        rpc.append("</target>");
-        rpc.append("<source>");
-        rpc.append(source);
-        rpc.append("</source>");
-        rpc.append("</copy-config>");
-        rpc.append("</rpc>");
-        rpc.append(ENDPATTERN);
-        return checkReply(sendRequest(rpc.toString()));
-    }
-
-    @Override
-    public boolean deleteConfig(DatastoreId netconfTargetConfig) throws NetconfException {
-        if (netconfTargetConfig.equals(DatastoreId.RUNNING)) {
-            log.warn("Target configuration for delete operation can't be \"running\"",
-                    netconfTargetConfig);
-            return false;
-        }
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append("<rpc>");
-        rpc.append("<delete-config>");
-        rpc.append("<target>");
-        rpc.append("<").append(netconfTargetConfig).append("/>");
-        rpc.append("</target>");
-        rpc.append("</delete-config>");
-        rpc.append("</rpc>");
-        rpc.append(ENDPATTERN);
-        return checkReply(sendRequest(rpc.toString()));
-    }
-
-    @Override
-    public boolean lock(DatastoreId configType) throws NetconfException {
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
-        rpc.append("<lock>");
-        rpc.append("<target>");
-        rpc.append("<");
-        rpc.append(configType.id());
-        rpc.append("/>");
-        rpc.append("</target>");
-        rpc.append("</lock>");
-        rpc.append("</rpc>");
-        rpc.append(ENDPATTERN);
-        String lockReply = sendRequest(rpc.toString());
-        return checkReply(lockReply);
-    }
-
-    @Override
-    public boolean unlock(DatastoreId configType) throws NetconfException {
-        StringBuilder rpc = new StringBuilder(XML_HEADER);
-        rpc.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
-        rpc.append("<unlock>");
-        rpc.append("<target>");
-        rpc.append("<");
-        rpc.append(configType.id());
-        rpc.append("/>");
-        rpc.append("</target>");
-        rpc.append("</unlock>");
-        rpc.append("</rpc>");
-        rpc.append(ENDPATTERN);
-        String unlockReply = sendRequest(rpc.toString());
-        return checkReply(unlockReply);
-    }
-
-    @Override
-    public boolean close() throws NetconfException {
-        return close(false);
-    }
-
-    private boolean close(boolean force) throws NetconfException {
-        StringBuilder rpc = new StringBuilder();
-        rpc.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">");
-        if (force) {
-            rpc.append("<kill-session/>");
-        } else {
-            rpc.append("<close-session/>");
-        }
-        rpc.append("</rpc>");
-        rpc.append(ENDPATTERN);
-        return checkReply(sendRequest(rpc.toString())) || close(true);
-    }
-
-    @Override
     public String getSessionId() {
         return sessionID;
     }
@@ -929,7 +645,9 @@
         streamHandler.removeDeviceEventListener(listener);
     }
 
-    private boolean checkReply(String reply) {
+    @Override
+    protected boolean checkReply(String reply) {
+        // Overridden to record error logs
         if (reply != null) {
             if (!reply.contains("<rpc-error>")) {
                 log.debug("Device {} sent reply {}", deviceInfo, reply);