diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOcNos.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOcNos.java
index fb9c090..d7c9fcb 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOcNos.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOcNos.java
@@ -44,18 +44,35 @@
         return rpc;
     }
 
+    /**
+     * Construct a rpc target power message.
+     *
+     * @param filter to build rpc
+     * @return RPC payload
+     */
+    @Override
+    public StringBuilder getModulationSchemeRequestRpc(String filter) {
+        StringBuilder rpc = new StringBuilder();
+        rpc.append("<get>")
+                .append("<filter>")
+                .append(filter)
+                .append("</filter>")
+                .append("</get>");
+        return rpc;
+    }
+
     @Override
     public void setModulationSchemeProcessor(PortNumber port, Object component, long bitRate) {
         String modulation = null;
         String editConfig = null;
         if (bitRate <= TerminalDeviceModulationConfig.BitRate.GBPS_100.value) {
             modulation = "dp_qpsk";
-            editConfig = state.modulationEditConfig(state.cassini, port, component, bitRate, modulation);
+            editConfig = state.modulationEditConfig(state.terminalDevice, port, component, bitRate, modulation);
             //setting the modulation by calling rpc
             state.setModulationRpc(port, component, editConfig);
         } else { // check if bitrate is greater than 100 Gig
             modulation = "dp_16qam";
-            editConfig = state.modulationEditConfig(state.cassini, port, component, bitRate, modulation);
+            editConfig = state.modulationEditConfig(state.terminalDevice, port, component, bitRate, modulation);
             //setting the modulation by calling rpc
             state.setModulationRpc(port, component, editConfig);
         }
@@ -109,7 +126,7 @@
                 log.info("The component content is {}.", component.toString());
         }
 
-        state.cassini = this;
+        state.terminalDevice = this;
         log.info("Setting the state with clsName :{} ", clsName);
     }
 
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOpenConfig.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOpenConfig.java
index bb82685..f126392 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOpenConfig.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOpenConfig.java
@@ -33,26 +33,6 @@
     /**
      * Construct a rpc target power message.
      *
-     * @param filter to build rpc
-     * @return RPC payload
-     */
-    @Override
-    public StringBuilder getModulationSchemeRequestRpc(String filter) {
-        StringBuilder rpc = new StringBuilder();
-        rpc.append("<get-config>")
-                .append("<source>")
-                .append("<" + DatastoreId.RUNNING + "/>")
-                .append("</source>")
-                .append("<filter type='subtree'>")
-                .append(filter)
-                .append("</filter>")
-                .append("</get-config>");
-        return rpc;
-    }
-
-    /**
-     * Construct a rpc target power message.
-     *
      * @return RPC payload
      */
     @Override
@@ -116,12 +96,12 @@
         String editConfig = null;
         if (bitRate <= BitRate.GBPS_100.value) {
             modulation = "dp_qpsk";
-            editConfig = state.modulationEditConfig(state.cassini, port, component, bitRate, modulation);
+            editConfig = state.modulationEditConfig(state.terminalDevice, port, component, bitRate, modulation);
             //setting the modulation by calling rpc
             state.setModulationRpc(port, component, editConfig);
         } else { // check if bitrate is greater than 100 Gig
             modulation = "dp_16qam";
-            editConfig = state.modulationEditConfig(state.cassini, port, component, bitRate, modulation);
+            editConfig = state.modulationEditConfig(state.terminalDevice, port, component, bitRate, modulation);
             //setting the modulation by calling rpc
             state.setModulationRpc(port, component, editConfig);
         }
@@ -162,6 +142,6 @@
                 log.info("The component content is {}.", component.toString());
         }
 
-        state.cassini = this;
+        state.terminalDevice = this;
     }
 }
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/GrooveModulationOpenConfig.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/GrooveModulationOpenConfig.java
index 0b7cde8..f5b4eda 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/GrooveModulationOpenConfig.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/GrooveModulationOpenConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-present Open Networking Foundation
+ * Copyright 2020-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,433 +19,132 @@
 
 import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
-import org.onlab.osgi.DefaultServiceDirectory;
-import org.onosproject.drivers.utilities.XmlConfigParser;
-import org.onosproject.net.DeviceId;
 import org.onosproject.net.ModulationScheme;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.behaviour.ModulationConfig;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.driver.AbstractHandlerBehaviour;
 import org.onosproject.netconf.DatastoreId;
-import org.onosproject.netconf.NetconfController;
-import org.onosproject.netconf.NetconfDevice;
-import org.onosproject.netconf.NetconfException;
-import org.onosproject.netconf.NetconfSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
 /*
  * Driver Implementation of the ModulationConfig for OcNos standard open config based terminal devices.
  */
-public class GrooveModulationOpenConfig<T> extends AbstractHandlerBehaviour implements ModulationConfig<T> {
+public class GrooveModulationOpenConfig<T> extends TerminalDeviceModulationConfig<T> {
 
-
-    private static final String RPC_TAG_NETCONF_BASE =
-            "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
-
-    private static final String RPC_CLOSE_TAG = "</rpc>";
-
-    private static final Logger log = LoggerFactory.getLogger(GrooveModulationOpenConfig.class);
-
-    private ComponentType state = ComponentType.DIRECTION;
-
-
-    enum BitRate {
-        GBPS_200(200),      // 200 Gbps
-        GBPS_100(100),        // 100 Gbps
-        GBPS_40(40),          // 40 Gbps
-        GBPS_10(10);          // 10 Gbps
-
-        private final long value;
-
-        public long getValue() {
-            return value;
-        }
-
-        BitRate(long value) {
-            this.value = value;
-        }
-    }
+    public static Logger log = LoggerFactory.getLogger(GrooveModulationOpenConfig.class);
 
     /**
-     * Returns the NetconfSession with the device for which the method was called.
+     * Construct a rpc target power message.
      *
-     * @param deviceId device indetifier
-     * @return The netconf session or null
+     * @return RPC payload
      */
+    @Override
+    public DatastoreId getDataStoreId() {
+        return DatastoreId.RUNNING;
+    }
+    /**
+     * Construct a rpc target power message.
+     *
+     * @param name for optical channel name
+     * @return RPC payload
+     */
+    @Override
+    public StringBuilder createModulationFilterRequestRpc(String name) {
+        StringBuilder rpc = new StringBuilder();
+        rpc.append("<name>").append(name).append("</name>");
+        return rpc;
+    }
 
+    @Override
+    public ModulationScheme modulationSchemeType(String operationalMode) {
+        /*Used for Internal Testing */
+        //String modulationScheme="DP16QAM";
+        ModulationScheme modulation;
+        if (operationalMode.equalsIgnoreCase("62") ||
+                operationalMode.equalsIgnoreCase("68")) {
+            modulation = ModulationScheme.DP_16QAM;
+        } else {
+            modulation = ModulationScheme.DP_QPSK;
+        }
+        return modulation;
+    }
 
-    private NetconfSession getNetconfSession(DeviceId deviceId) {
-        log.info("Inside getNetconfSession () method for device : {}", deviceId);
-        NetconfController controller = handler().get(NetconfController.class);
-        NetconfDevice ncdev = controller.getDevicesMap().get(deviceId);
-        if (ncdev == null) {
-            log.trace("No netconf device, returning null session");
+    @Override
+    public String modulationEditConfigRequestRpc(TerminalDeviceModulationConfig modulationConfig, PortNumber portNumber,
+                                                 Object component, long bitRate, String modulation) {
+        if (component != null) {
+            // This is an edit-config operation.
+            String portMode = modulation.equals("DP_QPSK") ? "QPSK_100G" : "16QAM_200G";
+            String portName = state.ocName(modulationConfig, portNumber);
+            Pattern portPattern = Pattern.compile(".*-[1]-[1-9][0-4]?-L[1-2]$"); // e.g. TRANSCEIVER-1-1-L1
+            Matcher lineMatch = portPattern.matcher(portName);
+            lineMatch.find();
+            final String[] split = lineMatch.group(0).split("-");
+
+            return "<ne xmlns=\"http://coriant.com/yang/os/ne\">" +
+                    "        <shelf>" +
+                    "          <shelf-id>" + split[1] + "</shelf-id>" +
+                    "          <slot>" +
+                    "            <slot-id>" + split[2] + "</slot-id>" +
+                    "            <card>" +
+                    "              <port>" +
+                    "                <port-id>" + split[3].replace("L", "") + "</port-id>" +
+                    "                <port-mode>" + portMode + "</port-mode>" +
+                    "              </port>" +
+                    "            </card>" +
+                    "          </slot>" +
+                    "        </shelf>" +
+                    "      </ne>";
+        } else {
+            log.error("Cannot process the component {}.", component.getClass());
             return null;
         }
-        return ncdev.getSession();
     }
 
-    /*
-     *
-     * Get the deviceId for which the methods apply.
-     *
-     * @return The deviceId as contained in the handler data
-     */
-
-
-    private DeviceId did() {
-        return handler().data().deviceId();
-    }
-
-    /**
-     * Execute RPC request.
-     *
-     * @param session Netconf session
-     * @param message Netconf message in XML format
-     * @return XMLConfiguration object
-     */
-
-    private XMLConfiguration executeRpc(NetconfSession session, String message) {
-        try {
-            CompletableFuture<String> fut = session.rpc(message);
-            String rpcReply = fut.get();
-            XMLConfiguration xconf = (XMLConfiguration) XmlConfigParser.loadXmlString(rpcReply);
-            xconf.setExpressionEngine(new XPathExpressionEngine());
-            return xconf;
-        } catch (NetconfException ne) {
-            log.error("Exception on Netconf protocol: {}.", ne);
-        } catch (InterruptedException ie) {
-            log.error("Interrupted Exception: {}.", ie);
-        } catch (ExecutionException ee) {
-            log.error("Concurrent Exception while executing Netconf operation: {}.", ee);
-        }
-        return null;
-    }
-
-    /**
-     * Get the target Modulation Scheme on the component.
-     *
-     * @param port      the port
-     * @param component the port component
-     * @return ModulationScheme as per bitRate value
-     **/
     @Override
-    public Optional<ModulationScheme> getModulationScheme(PortNumber port, T component) {
-        checkState(component);
-        return state.getModulationScheme(port, component);
+    public void setModulationSchemeProcessor(PortNumber port, Object component, long bitRate) {
+        ModulationScheme modulation = null;
+        if (bitRate <= BitRate.GBPS_100.value) {
+            modulation = ModulationScheme.DP_QPSK;
+        } else {
+            modulation = ModulationScheme.DP_16QAM;
+
+        }
+        // TODO: Groove doesn't support to change the modulation format via OpenConfig directly
+        //  without recommissioning the Optical Channel
+        // Workaround: use Groove native model via port-mode change
+        // String editConfig = modulationEditConfig(groove, port, component, bitRate, modulation.name());
+        String editConfig = state.modulationEditConfig(state.terminalDevice, port, component,
+                                                       bitRate, modulation.name());
+
+        //setting the modulation by calling rpc
+        state.setModulationRpc(port, component, editConfig);
     }
 
     /**
-     * Set the target Modulation Scheme on the component.
+     * Get the Modulation Scheme on the component.
      *
-     * @param port      the port
-     * @param component the port component
-     * @param bitRate   bit rate in bps
+     * @param conf HierarchicalConfiguration for path ../optical-channel/config
+     * @return Optional<ModulationScheme>
      **/
-    @Override
-    public void setModulationScheme(PortNumber port, T component, long bitRate) {
-        checkState(component);
-        state.setModulationScheme(port, component, bitRate);
-    }
+    public Optional<ModulationScheme> getModulation(XMLConfiguration conf) {
+        HierarchicalConfiguration config =
+                conf.configurationAt("data/components/component/optical-channel/config");
 
-
-    /*
-     *
-     * Set the ComponentType to invoke proper methods for different template T.
-     * @param component the component.
-     */
-    void checkState(Object component) {
-        String clsName = component.getClass().getName();
-        switch (clsName) {
-            case "org.onosproject.net.Direction":
-                state = ComponentType.DIRECTION;
-                break;
-            case "org.onosproject.net.OchSignal":
-                state = ComponentType.OCHSIGNAL;
-                break;
-            default:
-                log.error("Cannot parse the component type {}.", clsName);
-                log.info("The component content is {}.", component.toString());
+        String operationalMode = String.valueOf(config.getString("operational-mode"));
+        /*Used for Internal Testing */
+        //String modulationScheme="DP16QAM";
+        ModulationScheme modulation;
+        if (operationalMode.equalsIgnoreCase("62") ||
+                operationalMode.equalsIgnoreCase("68")) {
+            modulation = ModulationScheme.DP_16QAM;
+        } else {
+            modulation = ModulationScheme.DP_QPSK;
         }
-
-        state.groove = this;
-        log.info("Setting the state with clsName :{} ", clsName);
-    }
-
-    /*
-     *
-     * Component type.
-     */
-    enum ComponentType {
-
-        /*
-         *
-         * Direction.
-         */
-        DIRECTION() {
-            @Override
-            Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
-                return super.getModulationScheme(port, component);
-            }
-
-            @Override
-            void setModulationScheme(PortNumber port, Object component, long bitRate) {
-                log.info("Inside the enum setModulationScheme()");
-                super.setModulationScheme(port, component, bitRate);
-            }
-        },
-
-        /**
-         * OchSignal.
-         */
-        OCHSIGNAL() {
-            @Override
-            Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
-                return super.getModulationScheme(port, component);
-            }
-
-            @Override
-            void setModulationScheme(PortNumber port, Object component, long bitRate) {
-                super.setModulationScheme(port, component, bitRate);
-            }
-        };
-
-
-        GrooveModulationOpenConfig groove;
-
-        /*
-         * mirror method in the internal class.
-         * @param port port
-         * @param component component
-         * @return target modulation
-         */
-        Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
-            NetconfSession session = groove.getNetconfSession(groove.did());
-            checkNotNull(session);
-            String filter = createModulationFilter(groove, port);
-            StringBuilder rpcReq = new StringBuilder();
-            rpcReq.append(RPC_TAG_NETCONF_BASE)
-                    .append("<get-config>")
-                    .append("<source>")
-                    .append("<" + DatastoreId.RUNNING + "/>")
-                    .append("</source>")
-                    .append("<filter type='subtree'>")
-                    .append(filter)
-                    .append("</filter>")
-                    .append("</get-config>")
-                    .append(RPC_CLOSE_TAG);
-            XMLConfiguration xconf = groove.executeRpc(session, rpcReq.toString());
-            if (xconf == null) {
-                log.error("Error in executingRpc");
-                return Optional.empty();
-            }
-            try {
-                HierarchicalConfiguration config =
-                        xconf.configurationAt("data/components/component/optical-channel/config");
-
-                String operationalMode = String.valueOf(config.getString("operational-mode"));
-                /*Used for Internal Testing */
-                //String modulationScheme="DP16QAM";
-                ModulationScheme modulation;
-                if (operationalMode.equalsIgnoreCase("62") ||
-                        operationalMode.equalsIgnoreCase("68")) {
-                    modulation = ModulationScheme.DP_16QAM;
-                } else {
-                    modulation = ModulationScheme.DP_QPSK;
-                }
-                return Optional.of(modulation);
-            } catch (IllegalArgumentException e) {
-                log.error("Error in parsing config", e);
-                return Optional.empty();
-            }
-        }
-
-        /*
-         * mirror method in the internal class.
-         * @param port port
-         * @param component component
-         * @param power target value
-         */
-        void setModulationScheme(PortNumber port, Object component, long bitRate) {
-
-            ModulationScheme modulation = null;
-            if (bitRate <= BitRate.GBPS_100.value) {
-                modulation = ModulationScheme.DP_QPSK;
-            } else {
-                modulation = ModulationScheme.DP_16QAM;
-
-            }
-            // TODO: Groove doesn't support to change the modulation format via OpenConfig directly
-            //  without recommissioning the Optical Channel
-            // Workaround: use Groove native model via port-mode change
-            // String editConfig = modulationEditConfig(groove, port, component, bitRate, modulation.name());
-            String editConfig = groovePortModeEditConfig(groove, port, component, bitRate, modulation.name());
-
-            //setting the modulation by calling rpc
-            setModulationRpc(port, component, editConfig);
-
-        }
-
-        private static String createModulationFilter(GrooveModulationOpenConfig modulationConfig,
-                                                     PortNumber portNumber) {
-            String name = ocName(modulationConfig, portNumber);
-            StringBuilder sb = new StringBuilder("<components xmlns=\"http://openconfig.net/yang/platform\">");
-            sb.append("<component>").append("<name>").append(name).append("</name>");
-            sb.append("</component>").append("</components>");
-            return sb.toString();
-        }
-
-        /**
-         * Extract component name from portNumber's annotations.
-         *
-         * @param pc         modulation config instance
-         * @param portNumber the port number
-         * @return the component name
-         */
-
-
-        private static String ocName(GrooveModulationOpenConfig pc, PortNumber portNumber) {
-            DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
-            DeviceId deviceId = pc.handler().data().deviceId();
-            return deviceService.getPort(deviceId, portNumber).annotations().value("oc-name");
-        }
-
-        /*
-         *
-         * Parse filtering string from port and component.
-         * @param portNumber Port Number
-         * @param component port component (optical-channel)
-         * @param bitRate bitRate in bps
-         * @return filtering string in xml format
-         */
-        private String modulationEditConfig(GrooveModulationOpenConfig modulationConfig, PortNumber portNumber,
-                                            Object component, long bitRate, String modulation) {
-            /*
-             <components xmlns="http://openconfig.net/yang/platform">
-               <component>
-                 <name>oc1/0</name>
-                 <config>
-                    <name>oc1/0</name>
-                 </config>
-                 <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
-                   <config>
-                      <operational-mode>62</operational-mode>
-                   </config>
-                 </optical-channel>
-               </component>
-             </components>
-             */
-            String operationalMode = convertToGrooveOperationalMode(modulation);
-            if (component != null) {
-                // This is an edit-config operation.
-                String portName = ocName(modulationConfig, portNumber); //oc1/0
-                StringBuilder sb = new StringBuilder("<components xmlns=\"http://openconfig.net/yang/platform\">");
-                sb.append("<component>");
-                sb.append("<name>").append(portName).append("</name>");
-                sb.append("<config>");
-                sb.append("<name>").append(portName).append("</name>");
-                sb.append("</config>");
-                sb.append("<optical-channel xmlns=\"http://openconfig.net/yang/terminal-device\">")
-                        .append("<config>")
-                        .append("<operational-mode>")
-                        .append(operationalMode)
-                        .append("</operational-mode>")
-                        .append("</config>")
-                        .append("</optical-channel>");
-                sb.append("</component>");
-                sb.append("</components>");
-                return sb.toString();
-            } else {
-                log.error("Cannot process the component {}.", component.getClass());
-                return null;
-            }
-        }
-
-        /*
-         *
-         * Parse filtering string from port and component.
-         * @param portNumber Port Number
-         * @param component port component (optical-channel)
-         * @param bitRate bitRate in bps
-         * @return filtering string in xml format
-         */
-        private String groovePortModeEditConfig(GrooveModulationOpenConfig modulationConfig, PortNumber portNumber,
-                                                Object component, long bitRate, String modulation) {
-            if (component != null) {
-                // This is an edit-config operation.
-                String portMode = modulation.equals("DP_QPSK") ? "QPSK_100G" : "16QAM_200G";
-                String portName = ocName(modulationConfig, portNumber);
-                Pattern portPattern = Pattern.compile(".*-[1]-[1-9][0-4]?-L[1-2]$"); // e.g. TRANSCEIVER-1-1-L1
-                Matcher lineMatch = portPattern.matcher(portName);
-                lineMatch.find();
-                final String[] split = lineMatch.group(0).split("-");
-
-                return "<ne xmlns=\"http://coriant.com/yang/os/ne\">" +
-                        "        <shelf>" +
-                        "          <shelf-id>" + split[1] + "</shelf-id>" +
-                        "          <slot>" +
-                        "            <slot-id>" + split[2] + "</slot-id>" +
-                        "            <card>" +
-                        "              <port>" +
-                        "                <port-id>" + split[3].replace("L", "") + "</port-id>" +
-                        "                <port-mode>" + portMode + "</port-mode>" +
-                        "              </port>" +
-                        "            </card>" +
-                        "          </slot>" +
-                        "        </shelf>" +
-                        "      </ne>";
-            } else {
-                log.error("Cannot process the component {}.", component.getClass());
-                return null;
-            }
-        }
-
-
-        private String convertToGrooveOperationalMode(String modulation) {
-            if (modulation.equals(ModulationScheme.DP_QPSK.name())) {
-                return "22"; // Symbol rate 100G; modulation DP-QPSK; FEC mode SDFEC25
-            } else {
-                return "62"; // Symbol rate 200G; modulation DP-16QAM; FEC mode SDFEC25
-            }
-        }
-
-        private boolean setModulationRpc(PortNumber port, Object component, String editConfig) {
-            // NOTE: this doesn't work in current Groove version.
-            NetconfSession session = groove.getNetconfSession(groove.did());
-            checkNotNull(session);
-            boolean response = true;
-            StringBuilder rpcReq = new StringBuilder();
-            rpcReq.append(RPC_TAG_NETCONF_BASE)
-                    .append("<edit-config>")
-                    .append("<target><" + DatastoreId.RUNNING + "/></target>")
-                    .append("<config>")
-                    .append(editConfig)
-                    .append("</config>")
-                    .append("</edit-config>")
-                    .append(RPC_CLOSE_TAG);
-            log.info("RPC call for Setting Modulation : {}", rpcReq.toString());
-            XMLConfiguration xconf = groove.executeRpc(session, rpcReq.toString());
-            if (xconf == null) {
-                log.error("The <edit-config> operation to set target-modulation of Port({}:{}) is failed.",
-                        port.toString(), component.toString());
-            } else if (!xconf.getRoot().getChild(0).getName().equals("ok")) {
-                // The successful reply should be "<rpc-reply ...><ok /></rpc-reply>"
-                response = false;
-                log.error("The <edit-config> operation to set target-modulation of Port({}:{}) is failed.",
-                        port.toString(), component.toString());
-            }
-            return response;
-        }
+        return Optional.of(modulation);
     }
 }
+
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/GrooveOpenConfigDevicePowerConfig.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/GrooveOpenConfigDevicePowerConfig.java
index d38345b..ea7a506 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/GrooveOpenConfigDevicePowerConfig.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/GrooveOpenConfigDevicePowerConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-present Open Networking Foundation
+ * Copyright 2020-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,422 +19,82 @@
 package org.onosproject.drivers.odtn;
 
 import com.google.common.collect.Range;
-import org.apache.commons.configuration.HierarchicalConfiguration;
-import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
 import org.onlab.osgi.DefaultServiceDirectory;
-import org.onosproject.drivers.utilities.XmlConfigParser;
+import org.onosproject.drivers.odtn.openconfig.TerminalDevicePowerConfig;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.behaviour.PowerConfig;
 import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.netconf.NetconfController;
-import org.onosproject.netconf.NetconfDevice;
-import org.onosproject.netconf.NetconfException;
-import org.onosproject.netconf.NetconfSession;
-import org.slf4j.Logger;
+import org.onosproject.netconf.DatastoreId;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Driver Implementation of the PowerConfig for OpenConfig terminal devices.
  */
 public class GrooveOpenConfigDevicePowerConfig<T>
-        extends AbstractHandlerBehaviour implements PowerConfig<T> {
-    private static final String RPC_TAG_NETCONF_BASE =
-            "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
-
-    private static final String RPC_CLOSE_TAG = "</rpc>";
-
-    private static final long NO_POWER = -50;
-
-    private static final Logger log = getLogger(GrooveOpenConfigDevicePowerConfig.class);
-
-    private ComponentType state = ComponentType.DIRECTION;
+        extends TerminalDevicePowerConfig<T> implements PowerConfig<T> {
 
     /**
-     * Returns the NetconfSession with the device for which the method was called.
+     * Construct a rpc target power message.
      *
-     * @param deviceId device indetifier
-     * @return The netconf session or null
+     * @param filter to build rpc
+     * @return RPC payload
      */
-    private NetconfSession getNetconfSession(DeviceId deviceId) {
-        NetconfController controller = handler().get(NetconfController.class);
-        NetconfDevice ncdev = controller.getDevicesMap().get(deviceId);
-        if (ncdev == null) {
-            log.trace("No netconf device, returning null session");
-            return null;
-        }
-        return ncdev.getSession();
+    @Override
+    public StringBuilder getTargetPowerRequestRpc(String filter) {
+        StringBuilder rpc = new StringBuilder();
+        rpc.append("<get>")
+                .append("<filter type='subtree'>")
+                .append(filter)
+                .append("</filter>")
+                .append("</get>");
+        return rpc;
     }
 
     /**
-     * Get the deviceId for which the methods apply.
+     * Construct a rpc target power message.
      *
-     * @return The deviceId as contained in the handler data
+     * @return RPC payload
      */
-    private DeviceId did() {
-        return handler().data().deviceId();
+    @Override
+    public DatastoreId getDataStoreId() {
+        return DatastoreId.RUNNING;
     }
 
     /**
-     * Execute RPC request.
+     * Construct a rpc target power message.
      *
-     * @param session Netconf session
-     * @param message Netconf message in XML format
-     * @return XMLConfiguration object
-     */
-    private XMLConfiguration executeRpc(NetconfSession session, String message) {
-        try {
-            CompletableFuture<String> fut = session.rpc(message);
-            String rpcReply = fut.get();
-            XMLConfiguration xconf = (XMLConfiguration) XmlConfigParser.loadXmlString(rpcReply);
-            xconf.setExpressionEngine(new XPathExpressionEngine());
-            return xconf;
-        } catch (NetconfException ne) {
-            log.error("Exception on Netconf protocol: {}.", ne);
-        } catch (InterruptedException ie) {
-            log.error("Interrupted Exception: {}.", ie);
-        } catch (ExecutionException ee) {
-            log.error("Concurrent Exception while executing Netconf operation: {}.", ee);
-        }
-        return null;
-    }
-
-    /**
-     * Get the target-output-power value on specific optical-channel.
-     *
-     * @param port      the port
-     * @param component the port component. It should be 'oc-name' in the Annotations of Port.
-     *                  'oc-name' could be mapped to '/component/name' in openconfig yang.
-     * @return target power value
+     * @param name for optical channel name
+     * @param power to build rpc for target output power configuration
+     * @return RPC payload
      */
     @Override
-    public Optional<Double> getTargetPower(PortNumber port, T component) {
-        checkState(component);
-        return state.getTargetPower(port, component);
-    }
-
-    @Override
-    public void setTargetPower(PortNumber port, T component, double power) {
-        checkState(component);
-        state.setTargetPower(port, component, power);
-    }
-
-    @Override
-    public Optional<Double> currentPower(PortNumber port, T component) {
-        checkState(component);
-        return state.currentPower(port, component);
-    }
-
-    @Override
-    public Optional<Double> currentInputPower(PortNumber port, T component) {
-        checkState(component);
-        return state.currentInputPower(port, component);
-    }
-
-    @Override
-    public Optional<Range<Double>> getTargetPowerRange(PortNumber port, T component) {
-        checkState(component);
-        return state.getTargetPowerRange(port, component);
-    }
-
-    @Override
-    public Optional<Range<Double>> getInputPowerRange(PortNumber port, T component) {
-        checkState(component);
-        return state.getInputPowerRange(port, component);
-    }
-
-    @Override
-    public List<PortNumber> getPorts(T component) {
-        checkState(component);
-        return state.getPorts(component);
-    }
-
-
-    /**
-     * Set the ComponentType to invoke proper methods for different template T.
-     *
-     * @param component the component.
-     */
-    void checkState(Object component) {
-        String clsName = component.getClass().getName();
-        switch (clsName) {
-            case "org.onosproject.net.Direction":
-                state = ComponentType.DIRECTION;
-                break;
-            case "org.onosproject.net.OchSignal":
-                state = ComponentType.OCHSIGNAL;
-                break;
-            default:
-                log.error("Cannot parse the component type {}.", clsName);
-                log.info("The component content is {}.", component.toString());
-        }
-        state.groove = this;
-    }
-
-    /**
-     * Component type.
-     */
-    enum ComponentType {
-
-        /**
-         * Direction.
-         */
-        DIRECTION() {
-            @Override
-            public Optional<Double> getTargetPower(PortNumber port, Object component) {
-                return super.getTargetPower(port, component);
-            }
-
-            @Override
-            public void setTargetPower(PortNumber port, Object component, double power) {
-                super.setTargetPower(port, component, power);
-            }
-        },
-
-        /**
-         * OchSignal.
-         */
-        OCHSIGNAL() {
-            @Override
-            public Optional<Double> getTargetPower(PortNumber port, Object component) {
-                return super.getTargetPower(port, component);
-            }
-
-            @Override
-            public void setTargetPower(PortNumber port, Object component, double power) {
-                super.setTargetPower(port, component, power);
-            }
-        };
-
-
-        GrooveOpenConfigDevicePowerConfig groove;
-
-        /**
-         * mirror method in the internal class.
-         *
-         * @param port      port
-         * @param component component
-         * @return target power
-         */
-        Optional<Double> getTargetPower(PortNumber port, Object component) {
-            if (!isOpticalChannelInPort(port)) {
-                return Optional.empty();
-            }
-            NetconfSession session = groove.getNetconfSession(groove.did());
-            checkNotNull(session);
-            String filter = parsePort(groove, port, null, null);
-            StringBuilder rpcReq = new StringBuilder();
-            rpcReq.append(RPC_TAG_NETCONF_BASE)
-                    .append("<get>")
-                    .append("<filter type='subtree'>")
-                    .append(filter)
-                    .append("</filter>")
-                    .append("</get>")
-                    .append(RPC_CLOSE_TAG);
-            XMLConfiguration xconf = groove.executeRpc(session, rpcReq.toString());
-            try {
-                HierarchicalConfiguration config =
-                        xconf.configurationAt("data/components/component/optical-channel/config");
-                double power = Float.valueOf(config.getString("target-output-power")).doubleValue();
-                return Optional.of(power);
-            } catch (IllegalArgumentException e) {
-                return Optional.empty();
-            }
-        }
-
-        /**
-         * mirror method in the internal class.
-         *
-         * @param port      port
-         * @param component component
-         * @param power     target value
-         */
-        void setTargetPower(PortNumber port, Object component, double power) {
-            NetconfSession session = groove.getNetconfSession(groove.did());
-            checkNotNull(session);
-            String editConfig = parsePort(groove, port, null, power);
-            StringBuilder rpcReq = new StringBuilder();
-            rpcReq.append(RPC_TAG_NETCONF_BASE)
-                    .append("<edit-config>")
-                    .append("<target><running/></target>")
+    public StringBuilder parsePortRequestRpc(Double power, String name) {
+        StringBuilder rpc = new StringBuilder();
+        rpc.append("<component>").append("<name>").append(name).append("</name>");
+        if (power != null) {
+            // This is an edit-config operation.
+            rpc.append("<optical-channel xmlns=\"http://openconfig.net/yang/terminal-device\">")
                     .append("<config>")
-                    .append(editConfig)
+                    .append("<target-output-power>")
+                    .append(power)
+                    .append("</target-output-power>")
                     .append("</config>")
-                    .append("</edit-config>")
-                    .append(RPC_CLOSE_TAG);
-            XMLConfiguration xconf = groove.executeRpc(session, rpcReq.toString());
-            // The successful reply should be "<rpc-reply ...><ok /></rpc-reply>"
-            if (!xconf.getRoot().getChild(0).getName().equals("ok")) {
-                log.error("The <edit-config> operation to set target-output-power of Port({}:{}) is failed.",
-                          port.toString(), component.toString());
-            }
+                    .append("</optical-channel>");
         }
+        return rpc;
+    }
 
-        /**
-         * mirror method in the internal class.
-         *
-         * @param port      port
-         * @param component the component.
-         * @return current output power.
-         */
-        Optional<Double> currentPower(PortNumber port, Object component) {
-            if (!isOpticalChannelInPort(port)) {
-                return Optional.empty();
-            }
-
-            XMLConfiguration xconf = getOpticalChannelState(
-                    groove, port, "<output-power><instant/></output-power>");
-            try {
-                HierarchicalConfiguration config =
-                        xconf.configurationAt("data/components/component/optical-channel/state/output-power");
-                double currentPower = Float.valueOf(config.getString("instant")).doubleValue();
-                return Optional.of(currentPower);
-            } catch (IllegalArgumentException e) {
-                return Optional.empty();
-            }
+    @Override
+    public Optional<Range<Double>> getTargetPowerRange(PortNumber port, Object component) {
+        // Only line ports have power
+        DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
+        DeviceId deviceId = did();
+        if (deviceService.getPort(deviceId, port).type() == Port.Type.OCH) {
+            return Optional.of(Range.open(-20., 6.));
         }
-
-        /**
-         * mirror method in the internal class.
-         *
-         * @param port      port
-         * @param component the component
-         * @return current input power
-         */
-        Optional<Double> currentInputPower(PortNumber port, Object component) {
-            if (!isOpticalChannelInPort(port)) {
-                return Optional.empty();
-            }
-
-            XMLConfiguration xconf = getOpticalChannelState(
-                    groove, port, "<input-power><instant/></input-power>");
-            try {
-                HierarchicalConfiguration config =
-                        xconf.configurationAt("data/components/component/optical-channel/state/input-power");
-                double currentPower = Float.valueOf(config.getString("instant")).doubleValue();
-                return Optional.of(currentPower);
-            } catch (IllegalArgumentException e) {
-                return Optional.empty();
-            }
-        }
-
-        Optional<Range<Double>> getTargetPowerRange(PortNumber port, Object component) {
-            // Only line ports have power
-            if (isOpticalChannelInPort(port)) {
-                return Optional.of(Range.open(-20., 6.));
-            }
-            return Optional.empty();
-        }
-
-        boolean isOpticalChannelInPort(PortNumber port) {
-            DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
-            DeviceId deviceId = groove.handler().data().deviceId();
-            return (deviceService.getPort(deviceId, port).type() == Port.Type.OCH);
-        }
-
-        Optional<Range<Double>> getInputPowerRange(PortNumber port, Object component) {
-            if (!isOpticalChannelInPort(port)) {
-                return Optional.empty();
-            }
-            XMLConfiguration xconf = getOpticalChannelState(groove, port, "<input-power-range/>");
-            try {
-                HierarchicalConfiguration config =
-                        xconf.configurationAt("data/components/component/optical-channel/state/input-power-range");
-                double inputMin = Float.valueOf(config.getString("min")).doubleValue();
-                double inputMax = Float.valueOf(config.getString("max")).doubleValue();
-                return Optional.of(Range.open(inputMin, inputMax));
-            } catch (IllegalArgumentException e) {
-                return Optional.empty();
-            }
-        }
-
-        List<PortNumber> getPorts(Object component) {
-            // FIXME
-            log.warn("Not Implemented Yet!");
-            return new ArrayList<PortNumber>();
-        }
-
-        /**
-         * Get filtered content under <optical-channel><state>.
-         *
-         * @param pc         power config instance
-         * @param port       the port number
-         * @param underState the filter condition
-         * @return RPC reply
-         */
-        private static XMLConfiguration getOpticalChannelState(GrooveOpenConfigDevicePowerConfig pc,
-                                                               PortNumber port, String underState) {
-            NetconfSession session = pc.getNetconfSession(pc.did());
-            checkNotNull(session);
-            String name = ocName(pc, port);
-            StringBuilder rpcReq = new StringBuilder(RPC_TAG_NETCONF_BASE);
-            rpcReq.append("<get><filter><components xmlns=\"http://openconfig.net/yang/platform\"><component>")
-                    .append("<name>").append(name).append("</name>")
-                    .append("<optical-channel xmlns=\"http://openconfig.net/yang/terminal-device\">")
-                    .append("<state>")
-                    .append(underState)
-                    .append("</state></optical-channel></component></components></filter></get>")
-                    .append(RPC_CLOSE_TAG);
-            XMLConfiguration xconf = pc.executeRpc(session, rpcReq.toString());
-            return xconf;
-        }
-
-
-        /**
-         * Extract component name from portNumber's annotations.
-         *
-         * @param pc         power config instance
-         * @param portNumber the port number
-         * @return the component name
-         */
-        private static String ocName(GrooveOpenConfigDevicePowerConfig pc, PortNumber portNumber) {
-            DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
-            DeviceId deviceId = pc.handler().data().deviceId();
-            return deviceService.getPort(deviceId, portNumber).annotations().value("oc-name");
-        }
-
-
-        /**
-         * Parse filtering string from port and component.
-         *
-         * @param portNumber Port Number
-         * @param component  port component (optical-channel)
-         * @param power      power value set.
-         * @return filtering string in xml format
-         */
-        private static String parsePort(GrooveOpenConfigDevicePowerConfig pc, PortNumber portNumber,
-                                        Object component, Double power) {
-            if (component == null) {
-                String name = ocName(pc, portNumber);
-                StringBuilder sb = new StringBuilder("<components xmlns=\"http://openconfig.net/yang/platform\">");
-                sb.append("<component>").append("<name>").append(name).append("</name>");
-                if (power != null) {
-                    // This is an edit-config operation.
-                    sb.append("<optical-channel xmlns=\"http://openconfig.net/yang/terminal-device\">")
-                            .append("<config>")
-                            .append("<target-output-power>")
-                            .append(power)
-                            .append("</target-output-power>")
-                            .append("</config>")
-                            .append("</optical-channel>");
-                }
-                sb.append("</component>").append("</components>");
-                return sb.toString();
-            } else {
-                log.error("Cannot process the component {}.", component.getClass());
-                return null;
-            }
-        }
+        return Optional.empty();
     }
 }
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/GrooveOpenConfigFlowRuleProgrammable.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/GrooveOpenConfigFlowRuleProgrammable.java
index ea0d4c8..2134f08 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/GrooveOpenConfigFlowRuleProgrammable.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/GrooveOpenConfigFlowRuleProgrammable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-present Open Networking Foundation
+ * Copyright 2020-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,262 +18,66 @@
 
 package org.onosproject.drivers.odtn;
 
-import com.google.common.collect.ImmutableList;
-import org.onosproject.drivers.odtn.impl.DeviceConnectionCache;
+import org.onlab.util.Frequency;
 import org.onosproject.drivers.odtn.impl.FlowRuleParser;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Port;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.net.flow.DefaultFlowEntry;
-import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.drivers.odtn.openconfig.AbstractTerminalDeviceFlowRuleProgrammable;
 import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleProgrammable;
 import org.onosproject.netconf.DatastoreId;
-import org.onosproject.netconf.NetconfController;
 import org.onosproject.netconf.NetconfException;
 import org.onosproject.netconf.NetconfSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.xml.namespace.NamespaceContext;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery.OC_NAME;
-
 /**
  * Implementation of FlowRuleProgrammable interface for
  * OpenConfig terminal devices.
  */
 public class GrooveOpenConfigFlowRuleProgrammable
-        extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
+        extends AbstractTerminalDeviceFlowRuleProgrammable {
+
 
     private static final Logger log =
             LoggerFactory.getLogger(GrooveOpenConfigFlowRuleProgrammable.class);
 
-    private static final String RPC_TAG_NETCONF_BASE =
-            "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
+    public void setOpticalChannelFrequency(NetconfSession session,
+                                            String optChannel, Frequency freq) throws NetconfException {
 
-    private static final String RPC_CLOSE_TAG = "</rpc>";
+        final String transceiver = optChannel.replace("OCH", "TRANSCEIVER");
+        final StringBuilder sb = new StringBuilder();
+        sb.append(
+                "<components xmlns='http://openconfig.net/yang/platform'>"
+                        + "<component>"
+                        + "<name>" + optChannel + "</name>"
+                        + "<oc-opt-term:optical-channel "
+                        +
+                        "    xmlns:oc-opt-term='http://openconfig.net/yang/terminal-device'>"
+                        + "  <oc-opt-term:config>"
+                        + "   <oc-opt-term:frequency>" + (long) freq.asMHz() + "</oc-opt-term:frequency>"
+                        + "  </oc-opt-term:config>"
+                        + " </oc-opt-term:optical-channel>"
+                        + "</component>"
+                        + "<component>"
+                        + "  <name>" + transceiver + "</name>"
+                        + "   <transceiver xmlns='http://openconfig.net/yang/platform/transceiver'>"
+                        + "     <config>"
+                        + "       <enabled>true</enabled>"
+                        + "     </config>"
+                        + "   </transceiver>"
+                        + " </component>"
+                        + "</components>");
 
+        final boolean ok =
+                session.editConfig(DatastoreId.RUNNING, null, sb.toString());
 
-    /**
-     * Apply the flow entries specified in the collection rules.
-     *
-     * @param rules A collection of Flow Rules to be applied
-     * @return The collection of added Flow Entries
-     */
-    @Override
-    public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
-        NetconfSession session = getNetconfSession();
-        if (session == null) {
-            openConfigError("null session");
-            return ImmutableList.of();
+        if (!ok) {
+            throw new NetconfException("error writing channel frequency");
         }
-        List<FlowRule> added = new ArrayList<>();
-        for (FlowRule r : rules) {
-            try {
-                String connectionId = applyFlowRule(session, r);
-                getConnectionCache().add(did(), connectionId, r);
-                added.add(r);
-            } catch (Exception e) {
-                openConfigError("Error {}", e);
-                continue;
-            }
-        }
-        openConfigLog("applyFlowRules added {}", added.size());
-        return added;
     }
 
-    /**
-     * Get the flow entries that are present on the device.
-     *
-     * @return A collection of Flow Entries
-     */
-    @Override
-    public Collection<FlowEntry> getFlowEntries() {
-        DeviceConnectionCache cache = getConnectionCache();
-        if (cache.get(did()) == null) {
-            return ImmutableList.of();
-        }
-
-        List<FlowEntry> entries = new ArrayList<>();
-        for (FlowRule r : cache.get(did())) {
-            entries.add(
-                    new DefaultFlowEntry(r, FlowEntry.FlowEntryState.ADDED, 0, 0, 0));
-        }
-        return entries;
-    }
-
-    /**
-     * Remove the specified flow rules.
-     *
-     * @param rules A collection of Flow Rules to be removed
-     * @return The collection of removed Flow Entries
-     */
-    @Override
-    public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
-        NetconfSession session = getNetconfSession();
-        if (session == null) {
-            openConfigError("null session");
-            return ImmutableList.of();
-        }
-        List<FlowRule> removed = new ArrayList<>();
-        for (FlowRule r : rules) {
-            try {
-                String connectionId = removeFlowRule(session, r);
-                getConnectionCache().remove(did(), connectionId);
-                removed.add(r);
-            } catch (Exception e) {
-                openConfigError("Error {}", e);
-                continue;
-            }
-        }
-        openConfigLog("removedFlowRules removed {}", removed.size());
-        return removed;
-    }
-
-    private DeviceConnectionCache getConnectionCache() {
-        return DeviceConnectionCache.init();
-    }
-
-    // Context so XPath expressions are aware of XML namespaces
-    private static final NamespaceContext NS_CONTEXT = new NamespaceContext() {
-        @Override
-        public String getNamespaceURI(String prefix) {
-            if (prefix.equals("oc-platform-types")) {
-                return "http://openconfig.net/yang/platform-types";
-            }
-            if (prefix.equals("oc-opt-term")) {
-                return "http://openconfig.net/yang/terminal-device";
-            }
-            return null;
-        }
-
-        @Override
-        public Iterator getPrefixes(String val) {
-            return null;
-        }
-
-        @Override
-        public String getPrefix(String uri) {
-            return null;
-        }
-    };
-
-
-    /**
-     * Helper method to get the device id.
-     */
-    private DeviceId did() {
-        return data().deviceId();
-    }
-
-    /**
-     * Helper method to log from this class adding DeviceId.
-     */
-    private void openConfigLog(String format, Object... arguments) {
-        log.info("OPENCONFIG {}: " + format, did(), arguments);
-    }
-
-    /**
-     * Helper method to log an error from this class adding DeviceId.
-     */
-    private void openConfigError(String format, Object... arguments) {
-        log.error("OPENCONFIG {}: " + format, did(), arguments);
-    }
-
-
-    /**
-     * Helper method to get the Netconf Session.
-     */
-    private NetconfSession getNetconfSession() {
-        NetconfController controller =
-                checkNotNull(handler().get(NetconfController.class));
-        return controller.getNetconfDevice(did()).getSession();
-    }
-
-
-    /**
-     * Construct a String with a Netconf filtered get RPC Message.
-     *
-     * @param filter A valid XML tree with the filter to apply in the get
-     * @return a String containing the RPC XML Document
-     */
-    private String filteredGetBuilder(String filter) {
-        StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
-        rpc.append("<get>");
-        rpc.append("<filter type='subtree'>");
-        rpc.append(filter);
-        rpc.append("</filter>");
-        rpc.append("</get>");
-        rpc.append(RPC_CLOSE_TAG);
-        return rpc.toString();
-    }
-
-    /**
-     * Construct a get request to retrieve Components and their
-     * properties (for the ONOS port, index).
-     *
-     * @return The filt content to send to the device.
-     */
-    private String getComponents() {
-        StringBuilder filt = new StringBuilder();
-        filt.append("<components xmlns='http://openconfig.net/yang/platform'>");
-        filt.append(" <component>");
-        filt.append("  <name/>");
-        filt.append("  <properties/>");
-        filt.append(" </component>");
-        filt.append("</components>");
-        return filteredGetBuilder(filt.toString());
-    }
-
-
-    /**
-     * Construct a get request to retrieve Optical Channels and
-     * the line port they are using.
-     * <p>
-     * Thset ort.
-     *
-     * @return The filt content to send to the device.
-     */
-    private String getOpticalChannels() {
-        StringBuilder filt = new StringBuilder();
-        filt.append("<components xmlns='http://openconfig.net/yang/platform'>");
-        filt.append(" <component>");
-        filt.append("  <name/>");
-        filt.append("  <state/>");
-        filt.append("  <oc-opt-term:optical-channel xmlns:oc-opt-term"
-                            + " = 'http://openconfig.net/yang/terminal-device'>");
-        filt.append("    <oc-opt-term:config>");
-        filt.append("     <oc-opt-term:line-port/>");
-        filt.append("    </oc-opt-term:config >");
-        filt.append("  </oc-opt-term:optical-channel>");
-        filt.append(" </component>");
-        filt.append("</components>");
-        return filteredGetBuilder(filt.toString());
-    }
-
-
-    /**
-     * Get the OpenConfig component name for the OpticalChannel component.
-     *
-     * @param portNumber ONOS port number of the Line port ().
-     * @return the channel component name or null
-     */
-    private String getOpticalChannel(PortNumber portNumber) {
-        Port clientPort = handler().get(DeviceService.class).getPort(did(), portNumber);
-        return clientPort.annotations().value(OC_NAME);
-    }
-
-
+    //Overloaded setOpticalChannelFrequency() with two param as required for removeFlowRule()
     private void setOpticalChannelFrequency(NetconfSession session, StringBuilder sb) throws NetconfException {
 
         final boolean ok =
@@ -284,63 +88,7 @@
         }
     }
 
-
-    /**
-     * Apply the flowrule.
-     * <p>
-     * Note: only bidirectional are supported as of now,
-     * given OpenConfig note (below). In consequence, only the
-     * TX rules are actually mapped to netconf ops.
-     * <p>
-     * https://github.com/openconfig/public/blob/master/release/models
-     * /optical-transport/openconfig-terminal-device.yang
-     * <p>
-     * Directionality:
-     * To maintain simplicity in the model, the configuration is
-     * described from client-to-line direction.  The assumption is that
-     * equivalent reverse configuration is implicit, resulting in
-     * the same line-to-client configuration.
-     *
-     * @param session The Netconf session.
-     * @param r       Flow Rules to be applied.
-     * @return the optical channel + the frequency or just channel as identifier fo the config installed on the device
-     * @throws NetconfException if exchange goes wrong
-     */
-    protected String applyFlowRule(NetconfSession session, FlowRule r) throws NetconfException {
-        FlowRuleParser frp = new FlowRuleParser(r);
-        if (!frp.isReceiver()) {
-            String optChannel = getOpticalChannel(frp.getPortNumber());
-            final long frequency = (long) frp.getCentralFrequency().asMHz();
-            final String transceiver = optChannel.replace("OCH", "TRANSCEIVER");
-            final StringBuilder sb = new StringBuilder();
-            sb.append(
-                    "<components xmlns='http://openconfig.net/yang/platform'>"
-                            + "<component>"
-                            + "<name>" + optChannel + "</name>"
-                            + "<oc-opt-term:optical-channel "
-                            +
-                            "    xmlns:oc-opt-term='http://openconfig.net/yang/terminal-device'>"
-                            + "  <oc-opt-term:config>"
-                            + "   <oc-opt-term:frequency>" + frequency + "</oc-opt-term:frequency>"
-                            + "  </oc-opt-term:config>"
-                            + " </oc-opt-term:optical-channel>"
-                            + "</component>"
-                            + "<component>"
-                            + "  <name>" + transceiver + "</name>"
-                            + "   <transceiver xmlns='http://openconfig.net/yang/platform/transceiver'>"
-                            + "     <config>"
-                            + "       <enabled>true</enabled>"
-                            + "     </config>"
-                            + "   </transceiver>"
-                            + " </component>"
-                            + "</components>");
-
-            setOpticalChannelFrequency(session, sb);
-            return optChannel + ":" + frp.getCentralFrequency().asGHz();
-        }
-        return String.valueOf(frp.getCentralFrequency().asGHz());
-    }
-
+    @Override
     protected String removeFlowRule(NetconfSession session, FlowRule r)
             throws NetconfException {
         FlowRuleParser frp = new FlowRuleParser(r);
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/TerminalDeviceModulationConfig.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/TerminalDeviceModulationConfig.java
index 5b8992f..3a2a95e 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/TerminalDeviceModulationConfig.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/TerminalDeviceModulationConfig.java
@@ -103,14 +103,16 @@
      */
     public StringBuilder getModulationSchemeRequestRpc(String filter) {
         StringBuilder rpc = new StringBuilder();
-        rpc.append("<get>")
-                .append("<filter>")
+        rpc.append("<get-config>")
+                .append("<source>")
+                .append("<" + DatastoreId.RUNNING + "/>")
+                .append("</source>")
+                .append("<filter type='subtree'>")
                 .append(filter)
                 .append("</filter>")
-                .append("</get>");
+                .append("</get-config>");
         return rpc;
     }
-
     /**
      * Construct a rpc target power message.
      *
@@ -187,33 +189,33 @@
         //check if bitrate is less than equal to 100 Gig
         if (bitRate <= BitRate.GBPS_100.value) {
             modulation = ModulationScheme.DP_QPSK;
-            editConfig = state.modulationEditConfig(state.cassini, port, component, bitRate, modulation.name());
+            editConfig = state.modulationEditConfig(state.terminalDevice, port, component, bitRate, modulation.name());
             //setting the modulation by calling rpc
             rpcResponse = state.setModulationRpc(port, component, editConfig);
             if (rpcResponse) {
                 // TODO OSNR is valid only for receiver so need to modify
-                osnr = state.fetchDeviceSnr(state.cassini, port);
+                osnr = state.fetchDeviceSnr(state.terminalDevice, port);
                 if (osnr <= OSNR_THRESHOLD_VALUE) {
                     log.error("Channel not possible for this OSNR Value : {}", osnr);
                 }
             }
         } else { // check if bitrate is greater than 100 Gig
             modulation = ModulationScheme.DP_16QAM;
-            editConfig = state.modulationEditConfig(state.cassini, port, component, bitRate, modulation.name());
+            editConfig = state.modulationEditConfig(state.terminalDevice, port, component, bitRate, modulation.name());
             //setting the modulation by calling rpc
             rpcResponse = state.setModulationRpc(port, component, editConfig);
             if (rpcResponse) {
                 //TODO OSNR is valid only for receiver so need to modify
-                osnr =  state.fetchDeviceSnr(state.cassini, port);
+                osnr =  state.fetchDeviceSnr(state.terminalDevice, port);
                 if (osnr <= OSNR_THRESHOLD_VALUE) {
                     modulation = ModulationScheme.DP_8QAM;
-                    editConfig =  state.modulationEditConfig(state.cassini, port, component, bitRate,
+                    editConfig =  state.modulationEditConfig(state.terminalDevice, port, component, bitRate,
                                                              modulation.name());
                     //setting the modulation by calling rpc
                     rpcResponse = state.setModulationRpc(port, component, editConfig);
                     if (rpcResponse) {
                         // TODO OSNR is valid only for receiver so need to modify
-                        osnr = state.fetchDeviceSnr(state.cassini, port);
+                        osnr = state.fetchDeviceSnr(state.terminalDevice, port);
                         if (osnr <= OSNR_THRESHOLD_VALUE) {
                             log.warn("Channel not possible for this OSNR Value : {}." +
                                              " Please reduce the channel bitrate.", osnr);
@@ -254,6 +256,21 @@
         state.setModulationScheme(port, component, bitRate);
     }
 
+    /**
+     * Get the Modulation Scheme on the component.
+     *
+     * @param conf HierarchicalConfiguration for path ../optical-channel/config
+     * @return Optional<ModulationScheme>
+     **/
+    public Optional<ModulationScheme> getModulation(XMLConfiguration conf) {
+        HierarchicalConfiguration config =
+                        conf.configurationAt("components/component/optical-channel/config");
+
+                String modulationScheme = String.valueOf(config.getString("modulation"));
+
+        return Optional.of(modulationSchemeType(modulationScheme));
+    }
+
     /*
      *
      * Set the ComponentType to invoke proper methods for different template T.
@@ -271,7 +288,7 @@
         }
 
 
-        state.cassini = this;
+        state.terminalDevice = this;
     }
 
     /*
@@ -318,7 +335,7 @@
         };
 
 
-        TerminalDeviceModulationConfig cassini;
+        TerminalDeviceModulationConfig terminalDevice;
 
         /*
          * mirror method in the internal class.
@@ -328,12 +345,12 @@
          */
         Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
             NetconfSession session = NetconfSessionUtility
-                    .getNetconfSession(cassini.getDeviceId(), cassini.getController());
+                    .getNetconfSession(terminalDevice.getDeviceId(), terminalDevice.getController());
             checkNotNull(session);
-            String filter = createModulationFilter(cassini, port);
+            String filter = createModulationFilter(terminalDevice, port);
             StringBuilder rpcReq = new StringBuilder();
             rpcReq.append(RPC_TAG_NETCONF_BASE)
-                    .append(cassini.getModulationSchemeRequestRpc(filter))
+                    .append(terminalDevice.getModulationSchemeRequestRpc(filter))
                     .append(RPC_CLOSE_TAG);
             log.debug("RPC Call for Getting Modulation : \n {}", rpcReq.toString());
             XMLConfiguration xconf = NetconfSessionUtility.executeRpc(session, rpcReq.toString());
@@ -342,12 +359,7 @@
                 return Optional.empty();
             }
             try {
-                HierarchicalConfiguration config =
-                        xconf.configurationAt("components/component/optical-channel/config");
-
-                String modulationScheme = String.valueOf(config.getString("modulation"));
-
-                return Optional.of(cassini.modulationSchemeType(modulationScheme));
+                return terminalDevice.getModulation(xconf);
             } catch (IllegalArgumentException e) {
                 return Optional.empty();
             }
@@ -360,7 +372,7 @@
          * @param power target value
          */
         void setModulationScheme(PortNumber port, Object component, long bitRate) {
-            cassini.setModulationSchemeProcessor(port, component, bitRate);
+            terminalDevice.setModulationSchemeProcessor(port, component, bitRate);
         }
 
 
@@ -436,7 +448,7 @@
 
         private double fetchDeviceSnr(TerminalDeviceModulationConfig modulationConfig, PortNumber portNumber) {
             double osnr = 0.0;
-            XMLConfiguration xconf = getTerminalDeviceSnr(cassini, portNumber);
+            XMLConfiguration xconf = getTerminalDeviceSnr(terminalDevice, portNumber);
             if (xconf == null) {
                 return osnr;
             }
@@ -461,18 +473,19 @@
 
         public String modulationEditConfig(TerminalDeviceModulationConfig modulationConfig, PortNumber portNumber,
                                            Object component, long bitRate, String modulation) {
-            return cassini.modulationEditConfigRequestRpc(modulationConfig, portNumber, component, bitRate, modulation);
+            return terminalDevice.modulationEditConfigRequestRpc(modulationConfig, portNumber,
+                                                                 component, bitRate, modulation);
         }
 
         public boolean setModulationRpc(PortNumber port, Object component, String editConfig) {
             NetconfSession session = NetconfSessionUtility
-                    .getNetconfSession(cassini.getDeviceId(), cassini.getController());
+                    .getNetconfSession(terminalDevice.getDeviceId(), terminalDevice.getController());
             checkNotNull(session);
             boolean response = true;
             StringBuilder rpcReq = new StringBuilder();
             rpcReq.append(RPC_TAG_NETCONF_BASE)
                     .append("<edit-config>")
-                    .append("<target><" + cassini.getDataStoreId() + "/></target>")
+                    .append("<target><" + terminalDevice.getDataStoreId() + "/></target>")
                     .append("<config>")
                     .append(editConfig)
                     .append("</config>")
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/AbstractTerminalDeviceFlowRuleProgrammable.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/AbstractTerminalDeviceFlowRuleProgrammable.java
index ee50f7f..ac56c69 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/AbstractTerminalDeviceFlowRuleProgrammable.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/AbstractTerminalDeviceFlowRuleProgrammable.java
@@ -257,7 +257,7 @@
         filt.append("  <name/>");
         filt.append("  <state/>");
         filt.append("  <oc-opt-term:optical-channel xmlns:oc-opt-term"
-                + " = 'http://openconfig.net/yang/terminal-device'>");
+                            + " = 'http://openconfig.net/yang/terminal-device'>");
         filt.append("    <oc-opt-term:config>");
         filt.append("     <oc-opt-term:line-port/>");
         filt.append("    </oc-opt-term:config>");
@@ -278,7 +278,7 @@
      * @return the channel component name or null
      */
     protected String getOpticalChannel(NetconfSession session,
-                                     PortNumber portNumber) {
+                                       PortNumber portNumber) {
         try {
             checkNotNull(session);
             checkNotNull(portNumber);
@@ -324,14 +324,14 @@
      * @param portNumber ONOS port number of the Line port ().
      * @return the channel component name or null
      */
-    private String getOpticalChannel(PortNumber portNumber) {
+    protected String getOpticalChannel(PortNumber portNumber) {
         Port clientPort = handler().get(DeviceService.class).getPort(did(), portNumber);
         return clientPort.annotations().value(OC_NAME);
     }
 
 
     public abstract void setOpticalChannelFrequency(NetconfSession session,
-                                            String optChannel, Frequency freq)
+                                                    String optChannel, Frequency freq)
             throws NetconfException;
 
 
@@ -361,7 +361,7 @@
         if (!frp.isReceiver()) {
             String optChannel = getOpticalChannel(frp.getPortNumber());
             setOpticalChannelFrequency(session, optChannel,
-                    frp.getCentralFrequency());
+                                       frp.getCentralFrequency());
             return optChannel + ":" + frp.getCentralFrequency().asGHz();
         }
         return String.valueOf(frp.getCentralFrequency().asGHz());
