[ODTN]add NETCONF driver for Infinera and OPENCONFIG handler

Handler can easily create List<CharSequence> of OPENCONFIG by managing
ModelObject and Annotation together.
Handler also gives an alias to ModelObject of the same name in another
package(eg DefaultConfig), making it easier to handle within the same
class.

Change-Id: Ie4481f4020954518dc4c3c6deaced6d9e348c885
diff --git a/apps/odtn/api/BUCK b/apps/odtn/api/BUCK
index 23ac161..6883ca4 100644
--- a/apps/odtn/api/BUCK
+++ b/apps/odtn/api/BUCK
@@ -7,6 +7,8 @@
     '//models/openconfig:onos-models-openconfig',
     '//apps/yang:onos-apps-yang',
     '//apps/config:onos-apps-config',
+    '//models/openconfig-infinera:onos-models-openconfig-infinera',
+    '//protocols/netconf/api:onos-protocols-netconf-api',
 ]
 
 TEST_DEPS = [
@@ -22,6 +24,8 @@
     'org.onosproject.yang',
     'org.onosproject.models.tapi',
     'org.onosproject.models.openconfig',
+    'org.onosproject.models.openconfig-infinera',
+    'org.onosproject.netconf',
 ]
 
 # TODO probably bucklet, etc. should escape title & description
diff --git a/apps/odtn/api/BUILD b/apps/odtn/api/BUILD
old mode 100644
new mode 100755
index 4df56b5..97a583a
--- a/apps/odtn/api/BUILD
+++ b/apps/odtn/api/BUILD
@@ -4,6 +4,8 @@
     "//models/openconfig:onos-models-openconfig",
     "//apps/yang:onos-apps-yang",
     "//apps/config:onos-apps-config",
+    "//models/openconfig-infinera:onos-models-openconfig-infinera",
+    "//protocols/netconf/api:onos-protocols-netconf-api",
 ]
 
 osgi_jar_with_tests(
@@ -15,6 +17,8 @@
     "org.onosproject.yang",
     "org.onosproject.models.tapi",
     "org.onosproject.models.openconfig",
+    "org.onosproject.models.openconfig-infinera",
+    "org.onosproject.netconf",
 ]
 
 # TODO probably bucklet, etc. should escape title & description
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/AbstractOdtnTerminalDeviceDriver.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/AbstractOdtnTerminalDeviceDriver.java
new file mode 100755
index 0000000..420770a
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/AbstractOdtnTerminalDeviceDriver.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.behaviour;
+
+import com.google.common.io.CharSource;
+import org.onlab.util.XmlString;
+import org.onosproject.net.DeviceId;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfDevice;
+import org.onosproject.netconf.NetconfException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.util.List;
+import java.util.Optional;
+
+import static org.onlab.osgi.DefaultServiceDirectory.getService;
+import static org.onosproject.odtn.utils.YangToolUtil.toCharSequence;
+import static org.onosproject.odtn.utils.YangToolUtil.toDocument;
+
+/**
+ * Utility class for NETCONF driver.
+ */
+public abstract class AbstractOdtnTerminalDeviceDriver {
+
+    protected final Logger log = LoggerFactory.getLogger(getClass());
+
+    private static final String ENAME_ENVELOPE_RPC        = "rpc";
+    private static final String ENAME_ENVELOPE_EDITCONFIG = "edit-config";
+    private static final String ENAME_ENVELOPE_TARGET     = "target";
+    private static final String ENAME_ENVELOPE_RUNNING    = "running";
+    private static final String ENAME_ENVELOPE_CONFIG     = "config";
+
+    private static final String NAMESPACE                 = "urn:ietf:params:xml:ns:netconf:base:1.0";
+    private static final String CONFIG_NAMESPACE_NS       = "http://www.w3.org/2000/xmlns/";
+    private static final String CONFIG_NS_PRIFIX          = "xmlns:xc";
+
+    protected Document buildEditConfigBody(List<CharSequence> nodes) {
+
+        Document doc;
+        try {
+            doc = DocumentBuilderFactory.newInstance()
+                    .newDocumentBuilder().newDocument();
+        } catch (ParserConfigurationException e) {
+            log.error("Unexpected error", e);
+            throw new IllegalStateException(e);
+        }
+
+        Element appendRoot = addEditConfigEnvelope(doc);
+
+        for (CharSequence node : nodes) {
+            Document ldoc = toDocument(CharSource.wrap(node));
+            Element cfgRoot = ldoc.getDocumentElement();
+
+            // move (or copy) node to another Document
+            appendRoot.appendChild(Optional.ofNullable(doc.adoptNode(cfgRoot))
+                                       .orElseGet(() -> doc.importNode(cfgRoot, true)));
+        }
+
+        log.info("XML:\n{}", XmlString.prettifyXml(toCharSequence(doc)));
+        return doc;
+    }
+
+    protected void configureDevice(DeviceId did, Document doc) {
+
+        NetconfController ctr = getService(NetconfController.class);
+        Optional.ofNullable(ctr.getNetconfDevice(did))
+                .map(NetconfDevice::getSession)
+                .ifPresent(session -> {
+                    try {
+                        session.rpc(toCharSequence(doc, false).toString()).join();
+                    } catch (NetconfException e) {
+                        log.error("Exception thrown", e);
+                    }
+                });
+    }
+
+    public Element addEditConfigEnvelope(Document doc) {
+
+        // netconf rpc boilerplate part without message-id
+        // rpc
+        //  +- edit-config
+        //      +- target
+        //      |   +- running
+        //      +- config
+        Element rpc = doc.createElementNS(NAMESPACE, ENAME_ENVELOPE_RPC);
+        doc.appendChild(rpc);
+        Element editConfig = doc.createElement(ENAME_ENVELOPE_EDITCONFIG);
+        rpc.appendChild(editConfig);
+        Element target = doc.createElement(ENAME_ENVELOPE_TARGET);
+        editConfig.appendChild(target);
+        target.appendChild(doc.createElement(ENAME_ENVELOPE_RUNNING));
+
+        Element config = doc.createElement(ENAME_ENVELOPE_CONFIG);
+        config.setAttributeNS(CONFIG_NAMESPACE_NS, CONFIG_NS_PRIFIX, NAMESPACE);
+        editConfig.appendChild(config);
+
+        return config;
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/InfineraTransceiver.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/InfineraTransceiver.java
new file mode 100755
index 0000000..e2517a4
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/InfineraTransceiver.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.behaviour;
+
+import com.google.common.base.Strings;
+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.odtn.behaviour.OdtnTerminalDeviceDriver.Operation;
+import org.onosproject.odtn.utils.openconfig.OpenConfigAssignmentHandler;
+import org.onosproject.odtn.utils.openconfig.OpenConfigChannelHandler;
+import org.onosproject.odtn.utils.openconfig.OpenConfigConfigOfAssignmentHandler;
+import org.onosproject.odtn.utils.openconfig.OpenConfigConfigOfChannelHandler;
+import org.onosproject.odtn.utils.openconfig.OpenConfigLogicalChannelAssignmentsHandler;
+import org.onosproject.odtn.utils.openconfig.OpenConfigLogicalChannelsHandler;
+import org.onosproject.odtn.utils.openconfig.OpenConfigTerminalDeviceHandler;
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20161222.openconfigterminaldevice.terminallogicalchanassignmentconfig.AssignmentTypeEnum;
+
+import org.slf4j.Logger;
+
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.List;
+import static org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery.OC_NAME;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Utility class for NETCONF driver.
+ */
+public class InfineraTransceiver extends AbstractHandlerBehaviour
+        implements ConfigurableTransceiver {
+
+    private final Logger log = getLogger(getClass());
+
+    private static final String ANOTATION_NAME   = "xc:operation";
+
+    @Override
+    public List<CharSequence> enable(PortNumber client, PortNumber line, boolean enable) {
+
+        log.debug("enable() infinera route");
+        DeviceId did = this.data().deviceId();
+        Port clientPort = handler().get(DeviceService.class).getPort(did, client);
+        if (clientPort == null) {
+            log.warn("{} does not exist on {}", client, did);
+            return Collections.emptyList();
+        }
+        String clientName = clientPort.annotations().value(OC_NAME);
+        if (Strings.isNullOrEmpty(clientName)) {
+            log.warn("{} annotations not exist on {}@{}", OC_NAME, client, did);
+            return Collections.emptyList();
+        }
+
+        Port linePort = handler().get(DeviceService.class).getPort(did, line);
+        if (linePort == null) {
+            log.warn("{} does not exist on {}", line, did);
+            return Collections.emptyList();
+        }
+        String lineName = linePort.annotations().value(OC_NAME);
+        if (Strings.isNullOrEmpty(lineName)) {
+            log.warn("{} annotations not exist on {}@{}", OC_NAME, line, did);
+            return Collections.emptyList();
+        }
+
+        // create <terminal-device xmlns="http://openconfig.net/yang/terminal-device">
+        //        </terminal-device>
+        OpenConfigTerminalDeviceHandler terminalDevice = new OpenConfigTerminalDeviceHandler();
+
+        // add <logical-channels></logical-channels>
+        OpenConfigLogicalChannelsHandler logicalChannels =
+            new OpenConfigLogicalChannelsHandler(terminalDevice);
+
+        // add <channel><index>"clientName"</index></channel>
+        OpenConfigChannelHandler channel =
+            new OpenConfigChannelHandler(clientName, logicalChannels);
+
+        // add <config><index>"clientName"</index></config>
+        OpenConfigConfigOfChannelHandler configOfChannel =
+            new OpenConfigConfigOfChannelHandler(channel);
+        configOfChannel.addIndex(clientName);
+
+        // add <logical-channel-assignments xc:operation="merge/delete">
+        OpenConfigLogicalChannelAssignmentsHandler logicalChannelAssignments =
+            new OpenConfigLogicalChannelAssignmentsHandler(channel);
+        if (enable) {
+            logicalChannelAssignments.addAnnotation(ANOTATION_NAME, Operation.MERGE.value());
+        } else {
+            logicalChannelAssignments.addAnnotation(ANOTATION_NAME, Operation.DELETE.value());
+        }
+
+        // add <assignment><index>"clientName"</index></assignment>
+        OpenConfigAssignmentHandler assignment =
+            new OpenConfigAssignmentHandler(clientName, logicalChannelAssignments);
+
+        // add <config><assignment-type>LOGICAL_CHANNEL</assignment-type>
+        //             <logical-channel>"lineName"</logical-channel>
+        //             <allocation>100</allocation>
+        //     </config>
+        OpenConfigConfigOfAssignmentHandler configOfAssignment =
+            new OpenConfigConfigOfAssignmentHandler(assignment);
+        configOfAssignment.addAssignmentType(AssignmentTypeEnum.LOGICAL_CHANNEL);
+        configOfAssignment.addLogicalChannel(lineName);
+        configOfAssignment.addAllocation(BigDecimal.valueOf(100));
+
+        return terminalDevice.getListCharSequence();
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/PlainTransceiver.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/PlainTransceiver.java
old mode 100644
new mode 100755
index 111dfee..53a7085
--- a/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/PlainTransceiver.java
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/behaviour/PlainTransceiver.java
@@ -16,10 +16,6 @@
 package org.onosproject.odtn.behaviour;
 
 import static org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery.OC_NAME;
-import static org.onosproject.odtn.utils.YangToolUtil.toCharSequence;
-import static org.onosproject.odtn.utils.YangToolUtil.toCompositeData;
-import static org.onosproject.odtn.utils.YangToolUtil.toResourceData;
-import static org.onosproject.odtn.utils.YangToolUtil.toXmlCompositeStream;
 import static org.slf4j.LoggerFactory.getLogger;
 
 import java.util.Collections;
@@ -30,13 +26,15 @@
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.odtn.utils.openconfig.Transceiver;
-import org.onosproject.yang.model.DataNode;
-import org.onosproject.yang.model.ResourceId;
+import org.onosproject.odtn.behaviour.OdtnTerminalDeviceDriver.Operation;
+import org.onosproject.odtn.utils.openconfig.OpenConfigComponentsHandler;
+import org.onosproject.odtn.utils.openconfig.OpenConfigComponentHandler;
+import org.onosproject.odtn.utils.openconfig.OpenConfigConfigOfComponentHandler;
+import org.onosproject.odtn.utils.openconfig.OpenConfigConfigOfTransceiverHandler;
+import org.onosproject.odtn.utils.openconfig.OpenConfigTransceiverHandler;
 import org.slf4j.Logger;
 
 import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
 
 /**
  * Plain OpenConfig based implementation.
@@ -46,6 +44,8 @@
 
     private final Logger log = getLogger(getClass());
 
+    private static final String ANOTATION_NAME   = "xc:operation";
+
     @Override
     public List<CharSequence> enable(PortNumber client, PortNumber line, boolean enable) {
         DeviceId did = this.data().deviceId();
@@ -63,12 +63,34 @@
     }
 
     @Override
-    public List<CharSequence> enable(String component, boolean enable) {
-        List<DataNode> nodes = Transceiver.enable(component, enable);
+    public List<CharSequence> enable(String componentName, boolean enable) {
+        // create <components xmlns="http://openconfig.net/yang/platform"
+        //                    xc:operation="merge/delete">
+        //        </components>
+        OpenConfigComponentsHandler components = new OpenConfigComponentsHandler();
+        if (enable) {
+            components.addAnnotation(ANOTATION_NAME, Operation.MERGE.value());
+        } else {
+            components.addAnnotation(ANOTATION_NAME, Operation.DELETE.value());
+        }
 
-        ResourceId empty = ResourceId.builder().build();
-        return Lists.transform(nodes,
-                   node -> toCharSequence(toXmlCompositeStream(toCompositeData(toResourceData(empty, node)))));
+        // add <component><name>"componentName"</name></component>
+        OpenConfigComponentHandler component
+            = new OpenConfigComponentHandler(componentName, components);
+
+        // add <config><name>"componentName"</name></config>
+        OpenConfigConfigOfComponentHandler configOfComponent
+            = new OpenConfigConfigOfComponentHandler(component);
+        configOfComponent.addName(componentName);
+
+        // add <transceiver xmlns="http://openconfig.net/yang/platform/transceiver"></transceiver>
+        OpenConfigTransceiverHandler transceiver = new OpenConfigTransceiverHandler(component);
+
+        // add <config><enabled>true/false</enabled></config>
+        OpenConfigConfigOfTransceiverHandler configOfTransceiver
+            = new OpenConfigConfigOfTransceiverHandler(transceiver);
+        configOfTransceiver.addEnabled(enable);
+
+        return components.getListCharSequence();
     }
-
 }
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/YangToolUtil.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/YangToolUtil.java
old mode 100644
new mode 100755
index b0d56cb..f820441
--- a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/YangToolUtil.java
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/YangToolUtil.java
@@ -22,6 +22,7 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.StringWriter;
+import java.util.List;
 
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
@@ -47,6 +48,7 @@
 import org.onosproject.yang.model.ModelObjectData;
 import org.onosproject.yang.model.ResourceData;
 import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.runtime.AnnotatedNodeInfo;
 import org.onosproject.yang.runtime.CompositeData;
 import org.onosproject.yang.runtime.CompositeStream;
 import org.onosproject.yang.runtime.DefaultCompositeData;
@@ -270,6 +272,27 @@
     }
 
     /**
+     * Converts ResourceData & AnnotatedNodeInfo into CompositeData.
+     *
+     * @param input ResourceData to convert
+     * @param annotatedNodeInfos AnnotatedNodeInfoList to convert
+     * @return CompositeData
+     */
+    public static CompositeData toCompositeData(
+            ResourceData input,
+            List<AnnotatedNodeInfo> annotatedNodeInfos) {
+        CompositeData.Builder builder =
+                DefaultCompositeData.builder();
+        builder.resourceData(input);
+
+        // Set AnnotationNodeInfo
+        annotatedNodeInfos.stream()
+                .forEach(a -> builder.addAnnotatedNodeInfo(a));
+
+        return builder.build();
+    }
+
+    /**
      * Converts DataNode into ResourceData.
      *
      * @param resourceId pointing to parent of {@code dataNode}, YANG-wise.
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigAssignmentHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigAssignmentHandler.java
new file mode 100755
index 0000000..c608038
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigAssignmentHandler.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20161222.openconfigterminaldevice.terminallogicalchanassignmenttop.logicalchannelassignments.DefaultAssignment;
+
+import org.onosproject.yang.model.KeyLeaf;
+
+/**
+ * Utility class to deal with OPENCONFIG Assignment ModelObject & Annotation.
+ */
+public final class OpenConfigAssignmentHandler
+        extends OpenConfigObjectHandler<DefaultAssignment> {
+
+    private static final String OPENCONFIG_NAME = "assignment";
+    private static final String KEY_LEAF_NAME = "index";
+    private static final String NAME_SPACE = "http://openconfig.net/yang/terminal-device";
+
+    /**
+     * OpenConfigAssignmentHandler Constructor.
+     *
+     * @param keyValue String of target OPENCONFIG's key
+     * @param parent OpenConfigLogicalChannelAssignmentsHandler of
+     *               parent OPENCONFIG(logical-channel-assignments)
+     */
+    public OpenConfigAssignmentHandler(String keyValue,
+                                       OpenConfigLogicalChannelAssignmentsHandler parent) {
+        modelObject = new DefaultAssignment();
+        modelObject.index(keyValue);
+        setResourceId(OPENCONFIG_NAME, NAME_SPACE,
+                      new KeyLeaf(KEY_LEAF_NAME, NAME_SPACE, keyValue),
+                      parent.getResourceIdBuilder());
+        annotatedNodeInfos = parent.getAnnotatedNodeInfoList();
+
+        parent.addAssignment(this);
+    }
+
+    /**
+     * Add Config to modelObject of target OPENCONFIG.
+     *
+     * @param config OpenConfigConfigOfAssignmentHandler having Config to be set for modelObject
+     * @return OpenConfigAssignmentHandler of target OPENCONFIG
+     */
+    public OpenConfigAssignmentHandler addConfig(OpenConfigConfigOfAssignmentHandler config) {
+        modelObject.config(config.getModelObject());
+        return this;
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigChannelHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigChannelHandler.java
new file mode 100755
index 0000000..3ab6d8e
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigChannelHandler.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20161222.openconfigterminaldevice.terminallogicalchanneltop.logicalchannels.DefaultChannel;
+
+import org.onosproject.yang.model.KeyLeaf;
+
+/**
+ * Utility class to deal with OPENCONFIG Channel ModelObject & Annotation.
+ */
+public final class OpenConfigChannelHandler
+        extends OpenConfigObjectHandler<DefaultChannel> {
+
+    private static final String OPENCONFIG_NAME = "channel";
+    private static final String KEY_LEAF_NAME = "index";
+    private static final String NAME_SPACE = "http://openconfig.net/yang/terminal-device";
+
+    /**
+     * OpenConfigChannelHandler Constructor.
+     *
+     * @param keyValue String of target OPENCONFIG's key
+     * @param parent OpenConfigLogicalChannelsHandler of parent OPENCONFIG(logical-channels)
+     */
+    public OpenConfigChannelHandler(String keyValue, OpenConfigLogicalChannelsHandler parent) {
+        modelObject = new DefaultChannel();
+        modelObject.index(keyValue);
+        setResourceId(OPENCONFIG_NAME, NAME_SPACE,
+                      new KeyLeaf(KEY_LEAF_NAME, NAME_SPACE, keyValue),
+                      parent.getResourceIdBuilder());
+        annotatedNodeInfos = parent.getAnnotatedNodeInfoList();
+
+        parent.addChannel(this);
+    }
+
+    /**
+     * Add Config to modelObject of target OPENCONFIG.
+     *
+     * @param config OpenConfigConfigOfChannelHandler having Config to be set for modelObject
+     * @return OpenConfigChannelHandler of target OPENCONFIG
+     */
+    public OpenConfigChannelHandler addConfig(OpenConfigConfigOfChannelHandler config) {
+        modelObject.config(config.getModelObject());
+        return this;
+    }
+
+    /**
+     * Add LogicalChannelAssignments to modelObject of target OPENCONFIG.
+     *
+     * @param logicalChannelAssignments OpenConfigLogicalChannelAssignmentsHandler having
+     *                                  LogicalChannelAssignments to be set for modelObject
+     * @return OpenConfigChannelHandler of target OPENCONFIG
+     */
+    public OpenConfigChannelHandler addLogicalChannelAssignments(
+           OpenConfigLogicalChannelAssignmentsHandler logicalChannelAssignments) {
+        modelObject.logicalChannelAssignments(logicalChannelAssignments.getModelObject());
+        return this;
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigComponentHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigComponentHandler.java
new file mode 100755
index 0000000..4cb2b18
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigComponentHandler.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.gen.v1.openconfigplatform.rev20161222.openconfigplatform.platformcomponenttop.components.DefaultComponent;
+import org.onosproject.yang.gen.v1.openconfigplatformtransceiver.rev20170708.openconfigplatformtransceiver.components.component.DefaultAugmentedOcPlatformComponent;
+
+import org.onosproject.yang.model.KeyLeaf;
+
+/**
+ * Utility class to deal with OPENCONFIG Componet ModelObject & Annotation.
+ */
+public final class OpenConfigComponentHandler
+        extends OpenConfigObjectHandler<DefaultComponent> {
+
+    private static final String OPENCONFIG_NAME = "component";
+    private static final String KEY_LEAF_NAME = "name";
+    private static final String NAME_SPACE = "http://openconfig.net/yang/platform";
+
+    private DefaultAugmentedOcPlatformComponent augmentedOcPlatformComponent;
+
+    /**
+     * OpenConfigComponentHandler Constructor.
+     *
+     * @param keyValue String of target OPENCONFIG's key
+     * @param parent OpenConfigComponentsHandler of parent OPENCONFIG(components)
+     */
+    public OpenConfigComponentHandler(String keyValue, OpenConfigComponentsHandler parent) {
+        modelObject = new DefaultComponent();
+        modelObject.name(keyValue);
+        setResourceId(OPENCONFIG_NAME, NAME_SPACE,
+                      new KeyLeaf(KEY_LEAF_NAME, NAME_SPACE, keyValue),
+                      parent.getResourceIdBuilder());
+        annotatedNodeInfos = parent.getAnnotatedNodeInfoList();
+        augmentedOcPlatformComponent = new DefaultAugmentedOcPlatformComponent();
+
+        parent.addComponent(this);
+    }
+
+    /**
+     * Add Transceiver to modelObject of target OPENCONFIG.
+     *
+     * @param transceiver OpenConfigTransceiverHandler having Transceiver to be set for modelObject
+     * @return OpenConfigComponentHandler of target OPENCONFIG
+     */
+    public OpenConfigComponentHandler addTransceiver(OpenConfigTransceiverHandler transceiver) {
+        augmentedOcPlatformComponent.transceiver(transceiver.getModelObject());
+        modelObject.addAugmentation(augmentedOcPlatformComponent);
+        return this;
+    }
+
+    /**
+     * Add Config to modelObject of target OPENCONFIG.
+     *
+     * @param config OpenConfigConfigOfComponentHandler having Config to be set for modelObject
+     * @return OpenConfigComponentHandler of target OPENCONFIG
+     */
+    public OpenConfigComponentHandler addConfig(OpenConfigConfigOfComponentHandler config) {
+        modelObject.config(config.getModelObject());
+        return this;
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigComponentsHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigComponentsHandler.java
new file mode 100755
index 0000000..1dc568c
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigComponentsHandler.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.gen.v1.openconfigplatform.rev20161222.openconfigplatform.platformcomponenttop.DefaultComponents;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.runtime.AnnotatedNodeInfo;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.stream.Collectors;
+import com.google.common.collect.ImmutableList;
+
+import static org.onosproject.odtn.utils.YangToolUtil.toCharSequence;
+import static org.onosproject.odtn.utils.YangToolUtil.toCompositeData;
+import static org.onosproject.odtn.utils.YangToolUtil.toDataNode;
+import static org.onosproject.odtn.utils.YangToolUtil.toResourceData;
+import static org.onosproject.odtn.utils.YangToolUtil.toXmlCompositeStream;
+
+/**
+ * Utility class to deal with OPENCONFIG Componets ModelObject & Annotation.
+ */
+public final class OpenConfigComponentsHandler
+        extends OpenConfigObjectHandler<DefaultComponents> {
+
+    private static final String OPENCONFIG_NAME = "components";
+    private static final String NAME_SPACE = "http://openconfig.net/yang/platform";
+
+    /**
+     * OpenConfigComponentsHandler Constructor.
+     */
+    public OpenConfigComponentsHandler() {
+        modelObject = new DefaultComponents();
+        setResourceId(OPENCONFIG_NAME, NAME_SPACE, null, null);
+        annotatedNodeInfos = new ArrayList<AnnotatedNodeInfo>();
+    }
+
+    /**
+     * Add Component to modelObject of target OPENCONFIG.
+     *
+     * @param component OpenConfigComponentHandler having Component to be set for modelObject
+     * @return OpenConfigComponentsHandler of target OPENCONFIG
+     */
+    public OpenConfigComponentsHandler addComponent(OpenConfigComponentHandler component) {
+        modelObject.addToComponent(component.getModelObject());
+        return this;
+    }
+
+    /**
+     * Get List<CharSequence> of target OPENCONFIG.
+     *
+     * @return List<CharSequence> of target OPENCONFIG
+     */
+    public List<CharSequence> getListCharSequence() {
+        return ImmutableList.of(toDataNode((ModelObject) getModelObject())).stream()
+                            .map(node -> toCharSequence(toXmlCompositeStream(
+                                         toCompositeData(toResourceData(
+                                                         ResourceId.builder().build(), node),
+                                         annotatedNodeInfos))))
+                            .collect(Collectors.toList());
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigConfigOfAssignmentHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigConfigOfAssignmentHandler.java
new file mode 100755
index 0000000..7c7ade2
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigConfigOfAssignmentHandler.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20161222.openconfigterminaldevice.terminallogicalchanassignmentconfig.AssignmentTypeEnum;
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20161222.openconfigterminaldevice.terminallogicalchanassignmenttop.logicalchannelassignments.assignment.DefaultConfig;
+
+import java.math.BigDecimal;
+
+/**
+ * Utility class to deal with OPENCONFIG Assignment/Config ModelObject & Annotation.
+ */
+public final class OpenConfigConfigOfAssignmentHandler
+        extends OpenConfigObjectHandler<DefaultConfig> {
+
+    private static final String OPENCONFIG_NAME = "config";
+    private static final String NAME_SPACE = "http://openconfig.net/yang/terminal-device";
+
+    /**
+     * OpenConfigConfigOfAssignmentHandler Constructor.
+     *
+     * @param parent OpenConfigAssignmentHandler of parent OPENCONFIG(assignment)
+     */
+    public OpenConfigConfigOfAssignmentHandler(OpenConfigAssignmentHandler parent) {
+        modelObject = new DefaultConfig();
+        setResourceId(OPENCONFIG_NAME, NAME_SPACE, null, parent.getResourceIdBuilder());
+        annotatedNodeInfos = parent.getAnnotatedNodeInfoList();
+
+        parent.addConfig(this);
+    }
+
+    /**
+     * Add child OPENCONFIG(assignment-type).
+     *
+     * @param assignmentType AssignmentTypeEnum to be set for modelObject
+     * @return OpenConfigConfigOfAssignmentHandler of target OPENCONFIG
+     */
+    public OpenConfigConfigOfAssignmentHandler addAssignmentType(
+                                               AssignmentTypeEnum assignmentType) {
+        modelObject.assignmentType(assignmentType);
+        return this;
+    }
+
+    /**
+     * Add child OPENCONFIG(logical-channel).
+     *
+     * @param logicalChannel String to be set for modelObject
+     * @return OpenConfigConfigOfAssignmentHandler of target OPENCONFIG
+     */
+    public OpenConfigConfigOfAssignmentHandler addLogicalChannel(String logicalChannel) {
+        modelObject.logicalChannel(logicalChannel);
+        return this;
+    }
+
+    /**
+     * Add child OPENCONFIG(allocation).
+     *
+     * @param allocation BigDecimal to be set for modelObject
+     * @return OpenConfigConfigOfAssignmentHandler of target OPENCONFIG
+     */
+    public OpenConfigConfigOfAssignmentHandler addAllocation(BigDecimal allocation) {
+        modelObject.allocation(allocation);
+        return this;
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigConfigOfChannelHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigConfigOfChannelHandler.java
new file mode 100755
index 0000000..f422121
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigConfigOfChannelHandler.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20161222.openconfigterminaldevice.terminallogicalchanneltop.logicalchannels.channel.DefaultConfig;
+
+/**
+ * Utility class to deal with OPENCONFIG Channel/Config ModelObject & Annotation.
+ */
+public final class OpenConfigConfigOfChannelHandler
+        extends OpenConfigObjectHandler<DefaultConfig> {
+
+    private static final String OPENCONFIG_NAME = "config";
+    private static final String NAME_SPACE = "http://openconfig.net/yang/terminal-device";
+
+    /**
+     * OpenConfigConfigOfAssignmentHandler Constructor.
+     *
+     * @param parent OpenConfigChannelHandler of parent OPENCONFIG(channel)
+     */
+    public OpenConfigConfigOfChannelHandler(OpenConfigChannelHandler parent) {
+        modelObject = new DefaultConfig();
+        setResourceId(OPENCONFIG_NAME, NAME_SPACE, null, parent.getResourceIdBuilder());
+        annotatedNodeInfos = parent.getAnnotatedNodeInfoList();
+
+        parent.addConfig(this);
+    }
+
+    /**
+     * Add child OPENCONFIG(index).
+     *
+     * @param index String to be set for modelObject
+     * @return OpenConfigConfigOfChannelHandler of target OPENCONFIG
+     */
+    public OpenConfigConfigOfChannelHandler addIndex(String index) {
+        modelObject.index(index);
+        return this;
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigConfigOfComponentHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigConfigOfComponentHandler.java
new file mode 100755
index 0000000..09eb63e
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigConfigOfComponentHandler.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.gen.v1.openconfigplatform.rev20161222.openconfigplatform.platformcomponenttop.components.component.DefaultConfig;
+
+/**
+ * Utility class to deal with OPENCONFIG Componet/Config ModelObject & Annotation.
+ */
+public final class OpenConfigConfigOfComponentHandler
+        extends OpenConfigObjectHandler<DefaultConfig> {
+
+    private static final String OPENCONFIG_NAME = "config";
+    private static final String NAME_SPACE = "http://openconfig.net/yang/platform";
+
+    /**
+     * OpenConfigConfigOfComponentHandler Constructor.
+     *
+     * @param parent OpenConfigTransceiverHandler of parent OPENCONFIG(component)
+     */
+    public OpenConfigConfigOfComponentHandler(OpenConfigComponentHandler parent) {
+        modelObject = new DefaultConfig();
+        setResourceId(OPENCONFIG_NAME, NAME_SPACE, null, parent.getResourceIdBuilder());
+        annotatedNodeInfos = parent.getAnnotatedNodeInfoList();
+
+        parent.addConfig(this);
+    }
+
+    /**
+     * Add name to modelObject of target OPENCONFIG.
+     *
+     * @param name String to be set for modelObject
+     * @return OpenConfigConfigOfComponentHandler of target OPENCONFIG
+     */
+    public OpenConfigConfigOfComponentHandler addName(String name) {
+        modelObject.name(name);
+        return this;
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigConfigOfTransceiverHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigConfigOfTransceiverHandler.java
new file mode 100755
index 0000000..8a271fd
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigConfigOfTransceiverHandler.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.gen.v1.openconfigplatformtransceiver.rev20170708.openconfigplatformtransceiver.porttransceivertop.transceiver.DefaultConfig;
+
+/**
+ * Utility class to deal with OPENCONFIG Transceiver/Config ModelObject & Annotation.
+ */
+public final class OpenConfigConfigOfTransceiverHandler
+        extends OpenConfigObjectHandler<DefaultConfig> {
+
+    private static final String OPENCONFIG_NAME = "config";
+    private static final String NAME_SPACE = "http://openconfig.net/yang/platform/transceiver";
+
+    /**
+     * OpenConfigConfigOfTransceiverHandler Constructor.
+     *
+     * @param parent OpenConfigTransceiverHandler of parent OPENCONFIG(tranceiver)
+     */
+    public OpenConfigConfigOfTransceiverHandler(OpenConfigTransceiverHandler parent) {
+        modelObject = new DefaultConfig();
+        setResourceId(OPENCONFIG_NAME, NAME_SPACE, null, parent.getResourceIdBuilder());
+        annotatedNodeInfos = parent.getAnnotatedNodeInfoList();
+
+        parent.addConfig(this);
+    }
+
+    /**
+     * Add enabled to modelObject of target OPENCONFIG.
+     *
+     * @param enabled boolean to be set for modelObject
+     * @return OpenConfigConfigOfTransceiverHandler of target OPENCONFIG
+     */
+    public OpenConfigConfigOfTransceiverHandler addEnabled(boolean enabled) {
+        modelObject.enabled(enabled);
+        return this;
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigLogicalChannelAssignmentsHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigLogicalChannelAssignmentsHandler.java
new file mode 100755
index 0000000..5432b8f
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigLogicalChannelAssignmentsHandler.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20161222.openconfigterminaldevice.terminallogicalchanassignmenttop.DefaultLogicalChannelAssignments;
+
+/**
+ * Utility class to deal with OPENCONFIG LogicalChannelAssignments ModelObject & Annotation.
+ */
+public final class OpenConfigLogicalChannelAssignmentsHandler
+        extends OpenConfigObjectHandler<DefaultLogicalChannelAssignments> {
+
+    private static final String OPENCONFIG_NAME = "logical-channel-assignments";
+    private static final String NAME_SPACE = "http://openconfig.net/yang/terminal-device";
+
+    /**
+     * OpenConfigLogicalChannelAssignmentsHandler Constructor.
+     *
+     * @param parent OpenConfigChannelHandler of parent OPENCONFIG(channel)
+     */
+    public OpenConfigLogicalChannelAssignmentsHandler(OpenConfigChannelHandler parent) {
+        modelObject = new DefaultLogicalChannelAssignments();
+        setResourceId(OPENCONFIG_NAME, NAME_SPACE, null, parent.getResourceIdBuilder());
+        annotatedNodeInfos = parent.getAnnotatedNodeInfoList();
+
+        parent.addLogicalChannelAssignments(this);
+    }
+
+    /**
+     * Add Assignment to modelObject of target OPENCONFIG.
+     *
+     * @param assignment OpenConfigAssignmentHandler having Assignment to be set for modelObject
+     * @return OpenConfigLogicalChannelAssignmentsHandler of target OPENCONFIG
+     */
+    public OpenConfigLogicalChannelAssignmentsHandler addAssignment(
+                                                      OpenConfigAssignmentHandler assignment) {
+        modelObject.addToAssignment(assignment.getModelObject());
+        return this;
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigLogicalChannelsHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigLogicalChannelsHandler.java
new file mode 100755
index 0000000..7e3eb32
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigLogicalChannelsHandler.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20161222.openconfigterminaldevice.terminallogicalchanneltop.DefaultLogicalChannels;
+
+/**
+ * Utility class to deal with OPENCONFIG LogicalChannels ModelObject & Annotation.
+ */
+public final class OpenConfigLogicalChannelsHandler
+        extends OpenConfigObjectHandler<DefaultLogicalChannels> {
+
+    private static final String OPENCONFIG_NAME = "logical-channels";
+    private static final String NAME_SPACE = "http://openconfig.net/yang/terminal-device";
+
+    /**
+     * OpenConfigLogicalChannelsHandler Constructor.
+     *
+     * @param parent OpenConfigTerminalDeviceHandler of parent OPENCONFIG(terminal-device)
+     */
+    public OpenConfigLogicalChannelsHandler(OpenConfigTerminalDeviceHandler parent) {
+        modelObject = new DefaultLogicalChannels();
+        setResourceId(OPENCONFIG_NAME, NAME_SPACE, null, parent.getResourceIdBuilder());
+        annotatedNodeInfos = parent.getAnnotatedNodeInfoList();
+
+        parent.addLogicalChannels(this);
+    }
+
+    /**
+     * Add Channel to modelObject of target OPENCONFIG.
+     *
+     * @param channel OpenConfigChannelHandler having Channel to be set for modelObject
+     * @return OpenConfigLogicalChannelsHandler of target OPENCONFIG
+     */
+    public OpenConfigLogicalChannelsHandler addChannel(OpenConfigChannelHandler channel) {
+        modelObject.addToChannel(channel.getModelObject());
+        return this;
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigObjectHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigObjectHandler.java
new file mode 100644
index 0000000..16958b6
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigObjectHandler.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.model.KeyLeaf;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.runtime.AnnotatedNodeInfo;
+import org.onosproject.yang.runtime.Annotation;
+import org.onosproject.yang.runtime.DefaultAnnotatedNodeInfo;
+import org.onosproject.yang.runtime.DefaultAnnotation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.List;
+
+/**
+ * Utility abstract class to deal with OPENCONFIG ModelObject & Annotation.
+ *
+ * @param <O> modelOject to be dealt with
+ */
+public abstract class OpenConfigObjectHandler<O extends ModelObject> {
+    protected final Logger log = LoggerFactory.getLogger(getClass());
+    protected O modelObject;
+    protected ResourceId resourceId;
+    protected List<AnnotatedNodeInfo> annotatedNodeInfos;
+
+    /**
+     * Get modelObject instance.
+     *
+     * @return ModelObject of target OPENCONFIG
+     */
+    public O getModelObject() {
+        return modelObject;
+    }
+
+    /**
+     * Get resourceId instance.
+     *
+     * @return ResourceId of target OPENCONFIG
+     */
+    public ResourceId getResourceId() {
+        return resourceId;
+    }
+
+    /**
+     * Set resourceId instance.
+     *
+     * @param openconfigName String of target OPENCONFIG name
+     * @param openconfigNameSpace String of target OPENCONFIG namespace
+     * @param keyLeaf KeyLeaf of target OPENCONFIG
+     * @param pBuilder ResourceId.Builder of parent OPENCONFIG
+     */
+    protected void setResourceId(String openconfigName, String openconfigNameSpace,
+                                        KeyLeaf keyLeaf, ResourceId.Builder pBuilder) {
+        ResourceId.Builder ridBuilder = ResourceId.builder();
+        if (pBuilder != null) {
+            ridBuilder = pBuilder.addBranchPointSchema(openconfigName, openconfigNameSpace);
+        } else {
+            ridBuilder = ridBuilder.addBranchPointSchema(openconfigName,
+                                                         openconfigNameSpace);
+        }
+
+        if (keyLeaf != null) {
+            ridBuilder = ridBuilder.addKeyLeaf(
+                             keyLeaf.leafSchema().name(),
+                             keyLeaf.leafSchema().namespace(),
+                             keyLeaf.leafValue());
+        }
+
+        resourceId = ridBuilder.build();
+    }
+
+    /**
+     * Get ridBuilder instance.
+     *
+     * @return ResourceId.Builder of target OPENCONFIG
+     */
+    public ResourceId.Builder getResourceIdBuilder() {
+        try {
+            return resourceId.copyBuilder();
+        } catch (CloneNotSupportedException e) {
+            log.error("Exception thrown", e);
+            return null;
+        }
+    }
+
+    /**
+     * Add Annotation for annotaedNodeinfos.
+     *
+     * @param key String of Annotation's key
+     * @param value String of Annotation's value
+     */
+    public void addAnnotation(String key, String value) {
+        AnnotatedNodeInfo.Builder builder = DefaultAnnotatedNodeInfo.builder();
+
+        AnnotatedNodeInfo preAnnotate = annotatedNodeInfos.stream()
+                                        .filter(annotatedNodeInfo -> annotatedNodeInfo.resourceId()
+                                                                     .equals(resourceId))
+                                        .findFirst()
+                                        .orElse(null);
+
+        if (preAnnotate != null) {
+             annotatedNodeInfos.remove(preAnnotate);
+             for (Annotation annotation : preAnnotate.annotations()) {
+                  builder.addAnnotation(annotation);
+             }
+        }
+
+        annotatedNodeInfos.add(builder.addAnnotation(new DefaultAnnotation(key, value))
+                                      .resourceId(resourceId)
+                                      .build());
+    }
+
+    /**
+     * Get annotatedNodeInfos instance.
+     *
+     * @return List<AnnotatedNodeInfo> of all OPENCONFIG
+     */
+    public List<AnnotatedNodeInfo> getAnnotatedNodeInfoList() {
+        return annotatedNodeInfos;
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigTerminalDeviceHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigTerminalDeviceHandler.java
new file mode 100755
index 0000000..728a596
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigTerminalDeviceHandler.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.gen.v1.openconfigterminaldevice.rev20161222.openconfigterminaldevice.terminaldevicetop.DefaultTerminalDevice;
+
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.runtime.AnnotatedNodeInfo;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.stream.Collectors;
+import com.google.common.collect.ImmutableList;
+
+import static org.onosproject.odtn.utils.YangToolUtil.toCharSequence;
+import static org.onosproject.odtn.utils.YangToolUtil.toCompositeData;
+import static org.onosproject.odtn.utils.YangToolUtil.toDataNode;
+import static org.onosproject.odtn.utils.YangToolUtil.toResourceData;
+import static org.onosproject.odtn.utils.YangToolUtil.toXmlCompositeStream;
+
+/**
+ * Utility class to deal with OPENCONFIG TerminalDevice ModelObject & Annotation.
+ */
+public final class OpenConfigTerminalDeviceHandler
+        extends OpenConfigObjectHandler<DefaultTerminalDevice> {
+
+    private static final String OPENCONFIG_NAME = "terminal-device";
+    private static final String NAME_SPACE = "http://openconfig.net/yang/terminal-device";
+
+    /**
+     * OpenConfigTerminalDeviceHandler Constructor.
+     */
+    public OpenConfigTerminalDeviceHandler() {
+        modelObject = new DefaultTerminalDevice();
+        setResourceId(OPENCONFIG_NAME, NAME_SPACE, null, null);
+        annotatedNodeInfos = new ArrayList<AnnotatedNodeInfo>();
+    }
+
+    /**
+     * Add LogicalChannels to modelObject of target OPENCONFIG.
+     *
+     * @param logicalChannels OpenConfigLogicalChannelsHandler having LogicalChannels to be set for
+     *                        modelObject
+     * @return OpenConfigTerminalDeviceHandler of target OPENCONFIG
+     */
+    public OpenConfigTerminalDeviceHandler addLogicalChannels(
+                                           OpenConfigLogicalChannelsHandler logicalChannels) {
+        modelObject.logicalChannels(logicalChannels.getModelObject());
+        return this;
+    }
+
+    /**
+     * Get List<CharSequence> of target OPENCONFIG.
+     *
+     * @return List<CharSequence> of target OPENCONFIG
+     */
+    public List<CharSequence> getListCharSequence() {
+        return ImmutableList.of(toDataNode((ModelObject) getModelObject())).stream()
+                            .map(node -> toCharSequence(toXmlCompositeStream(
+                                         toCompositeData(toResourceData(
+                                                         ResourceId.builder().build(), node),
+                                         annotatedNodeInfos))))
+                            .collect(Collectors.toList());
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigTransceiverHandler.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigTransceiverHandler.java
new file mode 100755
index 0000000..562cb25
--- /dev/null
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/OpenConfigTransceiverHandler.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018-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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.odtn.utils.openconfig;
+
+import org.onosproject.yang.gen.v1.openconfigplatformtransceiver.rev20170708.openconfigplatformtransceiver.porttransceivertop.DefaultTransceiver;
+
+/**
+ * Utility class to deal with OPENCONFIG Transceiver ModelObject & Annotation.
+ */
+public final class OpenConfigTransceiverHandler
+        extends OpenConfigObjectHandler<DefaultTransceiver> {
+
+    private static final String OPENCONFIG_NAME = "transceiver";
+    private static final String NAME_SPACE = "http://openconfig.net/yang/platform/transceiver";
+
+    /**
+     * OpenConfigTransceiverHandler Constructor.
+     *
+     * @param parent OpenConfigComponentHandler of parent OPENCONFIG(component)
+     */
+    public OpenConfigTransceiverHandler(OpenConfigComponentHandler parent) {
+        modelObject = new DefaultTransceiver();
+        setResourceId(OPENCONFIG_NAME, NAME_SPACE, null, parent.getResourceIdBuilder());
+        annotatedNodeInfos = parent.getAnnotatedNodeInfoList();
+
+        parent.addTransceiver(this);
+    }
+
+    /**
+     * Add Config to modelObject of target OPENCONFIG.
+     *
+     * @param config OpenConfigConfigOfTransceiverHandler having Config to be set for modelObject
+     * @return OpenConfigTransceiverHandler of target OPENCONFIG
+     */
+    public OpenConfigTransceiverHandler addConfig(OpenConfigConfigOfTransceiverHandler config) {
+        modelObject.config(config.getModelObject());
+        return this;
+    }
+}
diff --git a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/Transceiver.java b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/Transceiver.java
old mode 100644
new mode 100755
index 66ca6cd..17220e0
--- a/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/Transceiver.java
+++ b/apps/odtn/api/src/main/java/org/onosproject/odtn/utils/openconfig/Transceiver.java
@@ -15,8 +15,6 @@
  */
 package org.onosproject.odtn.utils.openconfig;
 
-import static org.onosproject.odtn.utils.YangToolUtil.toDataNode;
-
 import java.util.List;
 
 import org.onosproject.yang.gen.v1.openconfigplatform.rev20161222.openconfigplatform.platformcomponenttop.DefaultComponents;
@@ -32,6 +30,8 @@
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableList;
 
+import static org.onosproject.odtn.utils.YangToolUtil.toDataNode;
+
 /**
  * Utility methods dealing with OpenConfig transceiver.
  * <p>
@@ -40,27 +40,6 @@
 @Beta
 public abstract class Transceiver {
 
-    public static List<DataNode> enable(String componentName, boolean enable) {
-
-        DefaultComponents components = new DefaultComponents();
-
-        Component component = PlainPlatform.componentWithName(componentName);
-        components.addToComponent(component);
-
-        // augmented 'component' shim
-        DefaultAugmentedOcPlatformComponent tcomponent = new DefaultAugmentedOcPlatformComponent();
-
-        DefaultTransceiver transceiver = new DefaultTransceiver();
-
-        Config configt = new DefaultConfig();
-        configt.enabled(enable); // phase 1.0 flag
-        transceiver.config(configt);
-        tcomponent.transceiver(transceiver);
-        component.addAugmentation(tcomponent);
-
-        return ImmutableList.of(toDataNode(components));
-    }
-
     public static List<DataNode> preconf(String componentName) {
         DefaultComponents components = new DefaultComponents();
 
diff --git a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DefaultOdtnTerminalDeviceDriver.java b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DefaultOdtnTerminalDeviceDriver.java
old mode 100644
new mode 100755
index 8f75100..1bb34a8
--- a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DefaultOdtnTerminalDeviceDriver.java
+++ b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DefaultOdtnTerminalDeviceDriver.java
@@ -22,27 +22,15 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceService;
-import org.onosproject.netconf.NetconfDevice;
-import org.onosproject.netconf.NetconfException;
 import org.onosproject.odtn.behaviour.ConfigurableTransceiver;
 import org.onosproject.odtn.behaviour.OdtnTerminalDeviceDriver;
+import org.onosproject.odtn.behaviour.AbstractOdtnTerminalDeviceDriver;
 import org.onosproject.odtn.behaviour.PlainTransceiver;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onlab.osgi.DefaultServiceDirectory.getService;
 
-import static org.onosproject.odtn.utils.YangToolUtil.toCharSequence;
-import static org.onosproject.odtn.utils.YangToolUtil.toDocument;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.onlab.util.XmlString;
-import org.onosproject.netconf.NetconfController;
 import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import com.google.common.io.CharSource;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -55,7 +43,8 @@
  * some critical problem to configure actual devices and netconf servers,
  * as a workaround this posts netconf edit-config directly.
  */
-public final class DefaultOdtnTerminalDeviceDriver implements OdtnTerminalDeviceDriver {
+public final class DefaultOdtnTerminalDeviceDriver
+        extends AbstractOdtnTerminalDeviceDriver implements OdtnTerminalDeviceDriver {
 
     protected final Logger log = LoggerFactory.getLogger(getClass());
 
@@ -95,68 +84,4 @@
         Document doc = buildEditConfigBody(nodes);
         configureDevice(did, doc);
     }
-
-    private Document buildEditConfigBody(List<CharSequence> nodes) {
-
-        Document doc;
-        try {
-            doc = DocumentBuilderFactory.newInstance()
-                    .newDocumentBuilder().newDocument();
-        } catch (ParserConfigurationException e) {
-            log.error("Unexpected error", e);
-            throw new IllegalStateException(e);
-        }
-
-        Element config = addEditConfigEnvelope(doc);
-
-        for (CharSequence node : nodes) {
-            Document ldoc = toDocument(CharSource.wrap(node));
-            Element cfgRoot = ldoc.getDocumentElement();
-
-            cfgRoot.setAttribute("xc:operation", Operation.MERGE.value());
-
-            // move (or copy) node to another Document
-            config.appendChild(Optional.ofNullable(doc.adoptNode(cfgRoot))
-                    .orElseGet(() -> doc.importNode(cfgRoot, true)));
-
-        }
-
-        log.info("XML:\n{}", XmlString.prettifyXml(toCharSequence(doc)));
-        return doc;
-    }
-
-    private Element addEditConfigEnvelope(Document doc) {
-
-        // netconf rpc boilerplate part without message-id
-        Element rpc = doc.createElementNS("urn:ietf:params:xml:ns:netconf:base:1.0", "rpc");
-        doc.appendChild(rpc);
-        Element editConfig = doc.createElement("edit-config");
-        rpc.appendChild(editConfig);
-        Element target = doc.createElement("target");
-        editConfig.appendChild(target);
-        target.appendChild(doc.createElement("running"));
-
-        Element config = doc.createElement("config");
-        config.setAttributeNS("http://www.w3.org/2000/xmlns/",
-                "xmlns:xc",
-                "urn:ietf:params:xml:ns:netconf:base:1.0");
-        editConfig.appendChild(config);
-
-        return config;
-    }
-
-    private void configureDevice(DeviceId did, Document doc) {
-
-        NetconfController ctr = getService(NetconfController.class);
-        Optional.ofNullable(ctr.getNetconfDevice(did))
-                .map(NetconfDevice::getSession)
-                .ifPresent(session -> {
-                    try {
-                        session.rpc(toCharSequence(doc, false).toString()).join();
-                    } catch (NetconfException e) {
-                        log.error("Exception thrown", e);
-                    }
-                });
-    }
-
 }
diff --git a/drivers/odtn-driver/src/main/resources/odtn-drivers.xml b/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
index bb59920..1657d65 100644
--- a/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
+++ b/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
@@ -33,7 +33,7 @@
         <behaviour api="org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery"
                    impl="org.onosproject.drivers.odtn.InfineraOpenConfigDeviceDiscovery"/>
         <behaviour api="org.onosproject.odtn.behaviour.ConfigurableTransceiver"
-                   impl="org.onosproject.odtn.behaviour.PlainTransceiver"/>
+                   impl="org.onosproject.odtn.behaviour.InfineraTransceiver"/>
     </driver>
     <driver name="nokia-1830" manufacturer="nokia" hwVersion="1830" swVersion="R10.1.1">
         <behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery"
diff --git a/models/openconfig-infinera/src/main/yang/openconfig-terminal-device@2016-12-22.yang b/models/openconfig-infinera/src/main/yang/openconfig-terminal-device@2016-12-22.yang
index 3bea3e8..9b2dd46 100644
--- a/models/openconfig-infinera/src/main/yang/openconfig-terminal-device@2016-12-22.yang
+++ b/models/openconfig-infinera/src/main/yang/openconfig-terminal-device@2016-12-22.yang
@@ -677,7 +677,8 @@
       "Configuration data for logical channels";
 
     leaf index {
-      type uint32;
+      //type uint32;
+      type string;
       description
         "Index of the current logical channel";
     }