[ONOS-4879][ONOS-5024][ONOS-5025]TE Topology NBI

The APP introduces IETF TE Topology YANG models as RESTCONF NBI,
and it works as an adapter for data conversion between
YMS(YANG generated JAVA classes) and TE Topology Core subsystem.

The APP implements the following interfaces:
IetfNetworkService Interface
IetfTopologyService Interface
IetfNetworkTopologyService Interface

Change-Id: I761ff684bde4b64ca42bb1b0d5b1ddfb8a2377fd
diff --git a/apps/tenbi/utils/src/main/java/org/onosproject/teyang/utils/topology/LinkConverter.java b/apps/tenbi/utils/src/main/java/org/onosproject/teyang/utils/topology/LinkConverter.java
new file mode 100644
index 0000000..24518d8
--- /dev/null
+++ b/apps/tenbi/utils/src/main/java/org/onosproject/teyang/utils/topology/LinkConverter.java
@@ -0,0 +1,980 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * 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.teyang.utils.topology;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+import org.onosproject.tetopology.management.api.KeyId;
+import org.onosproject.tetopology.management.api.link.ExternalDomain;
+import org.onosproject.tetopology.management.api.link.LinkProtectionType;
+import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
+import org.onosproject.tetopology.management.api.link.PathElement;
+import org.onosproject.tetopology.management.api.link.TeLink;
+import org.onosproject.tetopology.management.api.link.UnderlayBackupPath;
+import org.onosproject.tetopology.management.api.link.UnderlayPath;
+import org.onosproject.tetopology.management.api.node.TeNetworkTopologyId;
+import org.onosproject.tetopology.management.api.node.TerminationPointKey;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ietfnetwork.NetworkId;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ietfnetwork.NodeId;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
+               .ietfnetworktopology.LinkId;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
+               .ietfnetworktopology.TpId;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
+               .ietfnetworktopology.networks.network.augmentedndnetwork.DefaultLink;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
+               .ietfnetworktopology.networks.network.augmentedndnetwork.DefaultLink.LinkBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
+               .ietfnetworktopology.networks.network.augmentedndnetwork.Link;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
+               .ietfnetworktopology.networks.network.augmentedndnetwork.link.DefaultDestination;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
+               .ietfnetworktopology.networks.network.augmentedndnetwork.link.DefaultSource;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
+               .ietfnetworktopology.networks.network.augmentedndnetwork.link.DefaultSupportingLink;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
+                .ietfnetworktopology.networks.network.augmentedndnetwork.link.Destination
+                .DestinationBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
+               .ietfnetworktopology.networks.network.augmentedndnetwork.link.Source.SourceBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
+               .ietfnetworktopology.networks.network.augmentedndnetwork.link.SupportingLink;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
+               .ietfnetworktopology.networks.network.augmentedndnetwork.link.SupportingLink
+               .SupportingLinkBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.augmentednwnetworks.te.templates.linktemplate
+               .telinkattributes.LinkProtectionTypeEnum;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.AugmentedNtLink;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.DefaultAugmentedNtLink;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.DefaultAugmentedNtLink.AugmentedNtLinkBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.DefaultTe;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.DefaultTe.TeBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.Config;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+.ietftetopology.networks.network.link.augmentedntlink.te.Config.ConfigBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.DefaultConfig;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.DefaultState;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.State;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+.ietftetopology.networks.network.link.augmentedntlink.te.State.StateBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.DefaultTeLinkAttributes;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.TeLinkAttributes;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.TeLinkAttributes
+               .TeLinkAttributesBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+               .DefaultExternalDomain;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+               .DefaultExternalDomain.ExternalDomainBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes.DefaultTeSrlgs;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes.DefaultUnderlay;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+               .DefaultUnreservedBandwidth;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes.TeSrlgs
+               .TeSrlgsBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes.Underlay;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes.Underlay
+               .UnderlayBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+               .UnreservedBandwidth;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+               .UnreservedBandwidth.UnreservedBandwidthBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+               .underlay.DefaultUnderlayBackupPath;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology
+               .networks.network.link.augmentedntlink.te.config.telinkattributes.underlay
+               .DefaultUnderlayBackupPath.UnderlayBackupPathBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+               .underlay.DefaultUnderlayPrimaryPath;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+               .underlay.DefaultUnderlayTrailDes.UnderlayTrailDesBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+               .underlay.DefaultUnderlayTrailSrc.UnderlayTrailSrcBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+               .underlay.UnderlayPrimaryPath;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+               .underlay.UnderlayPrimaryPath.UnderlayPrimaryPathBuilder;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+               .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+               .underlay.underlayprimarypath.DefaultPathElement;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.Srlg;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TeLinkAccessType;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TeNodeId;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TeTopologyId;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TeTpId;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705
+               .ietftetypes.telinkaccesstype.TeLinkAccessTypeEnum;
+
+import com.google.common.collect.Lists;
+
+/**
+ * The conversion functions.
+ */
+public final class LinkConverter {
+    private static final String
+        E_NULL_TELINK_UNDERLAY_PATH = "TeSubsystem link underlayPath object cannot be null";
+    private static final String
+        E_NULL_TELINK_DATA = "TeSubsystem teLink data cannot be null";
+    private static final String
+        E_NULL_TELINK = "TeSubsystem teLink object cannot be null";
+    private static final String
+        E_NULL_YANG_TELINK_CONFIG = "YANG telink config object cannot be null";
+    private static final String
+        E_NULL_YANG_TELINK = "YANG Link object cannot be null";
+
+    // no instantiation
+    private LinkConverter() {
+    }
+
+    private static UnderlayBuilder te2YangConfigUnderlayPrimaryPath(
+            UnderlayBuilder yangBuilder,
+            org.onosproject.tetopology.management.api.link.UnderlayPrimaryPath tePath) {
+        UnderlayPrimaryPathBuilder pathBuilder =
+                                       DefaultUnderlayPrimaryPath.builder();
+        if (tePath.pathElements() != null) {
+            for (PathElement pathElementTe : tePath.pathElements()) {
+                org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                   .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te
+                   .config.telinkattributes.underlay.underlayprimarypath.PathElement
+                   .PathElementBuilder pathElementYangBuilder = DefaultPathElement.builder();
+                // FIXME: pathElementTe does not have any getter or
+                // setter at the moment --> pathElementYangBuilder =
+                // pathElementYangBuilder.pathElementId(pathElementTe.getPathElementId());
+                pathBuilder = pathBuilder.addToPathElement(pathElementYangBuilder.build());
+            }
+        }
+        pathBuilder = pathBuilder.networkIdRef(NetworkId.fromString(
+                                               tePath.ref().getNetworkId().toString()))
+                                 .teTopologyIdRef(TeTopologyId.fromString(
+                                               tePath.ref().getTopologyId().topologyId()));
+        return yangBuilder.underlayPrimaryPath(pathBuilder.build());
+    }
+
+    private static UnderlayBuilder te2YangConfigUnderlayBackupPaths(
+            UnderlayBuilder yangBuilder,
+            List<org.onosproject.tetopology.management.api.link.UnderlayBackupPath> tePaths) {
+
+        for (UnderlayBackupPath tePath : tePaths) {
+            UnderlayBackupPathBuilder pathBuilder = DefaultUnderlayBackupPath.builder();
+            pathBuilder = pathBuilder.index(tePath.index());
+            pathBuilder = pathBuilder.networkIdRef(NetworkId.fromString(
+                                                        tePath.ref().getNetworkId().toString()))
+                                     .teTopologyIdRef(TeTopologyId.fromString(
+                                                        tePath.ref().getTopologyId().topologyId()));
+            for (PathElement backupPathElementTe : tePath.pathElements()) {
+                org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                   .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te
+                   .config.telinkattributes.underlay.underlaybackuppath.PathElement
+                   .PathElementBuilder elementBuilder =
+                org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                   .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te
+                   .config.telinkattributes.underlay.underlaybackuppath.DefaultPathElement.builder();
+                // FIXME: backupPathElementTe does not have any
+                // getter or setter at the moment -->
+                // elementBuilder =
+                // elementBuilder.pathElementId(backupPathElementTe.getPathElementId());
+                pathBuilder = pathBuilder.addToPathElement(elementBuilder.build());
+            }
+            yangBuilder = yangBuilder.addToUnderlayBackupPath(pathBuilder.build());
+        }
+
+        return yangBuilder;
+    }
+
+    /**
+     * TE Link underlay path Config object conversion from TE Topology subsystem to YANG.
+     *
+     * @param  tePath TE underlay path object
+     * @return Link underlay path Config YANG object
+     */
+    private static Underlay teSubsystem2YangConfigUnderlayPath(UnderlayPath tePath) {
+        checkNotNull(tePath, E_NULL_TELINK_UNDERLAY_PATH);
+        UnderlayBuilder builder =
+                DefaultUnderlay.builder().underlayProtectionType(tePath.protectionType());
+
+        if (tePath.primaryPath() != null) {
+            builder = te2YangConfigUnderlayPrimaryPath(builder, tePath.primaryPath());
+        }
+        if (tePath.trailSrc() != null) {
+            builder = builder.underlayTrailSrc(
+                                  new UnderlayTrailSrcBuilder()
+                                          .networkRef(NetworkId.fromString(
+                                                  tePath.trailSrc().networkId().toString()))
+                                          .nodeRef(NodeId.fromString(
+                                                  tePath.trailSrc().nodeId().toString()))
+                                          .tpRef(TpId.fromString(
+                                                  tePath.trailSrc().tpId().toString()))
+                                          .build());
+        }
+        if (tePath.trailDes() != null) {
+            builder = builder.underlayTrailDes(
+                                  new UnderlayTrailDesBuilder()
+                                          .networkRef(NetworkId.fromString(
+                                                  tePath.trailDes().networkId().toString()))
+                                          .nodeRef(NodeId.fromString(
+                                                  tePath.trailDes().nodeId().toString()))
+                                          .tpRef(TpId.fromString(
+                                                  tePath.trailDes().tpId().toString()))
+                                          .build());
+        }
+        if (tePath.backupPaths() != null) {
+            builder = te2YangConfigUnderlayBackupPaths(builder, tePath.backupPaths());
+        }
+
+        return builder.build();
+    }
+
+    private static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                      .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te
+                      .state.telinkattributes.Underlay.UnderlayBuilder
+            te2YangStateUnderlayPrimaryPath(
+                   org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                      .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te
+                      .state.telinkattributes.Underlay.UnderlayBuilder yangBuilder,
+                   org.onosproject.tetopology.management.api.link.UnderlayPrimaryPath tePath) {
+        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+            .ietftetopology.networks.network.link.augmentedntlink.te.state.telinkattributes
+            .underlay.UnderlayPrimaryPath.UnderlayPrimaryPathBuilder pathBuilder =
+        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+            .ietftetopology.networks.network.link.augmentedntlink.te.state.telinkattributes
+            .underlay.DefaultUnderlayPrimaryPath.builder();
+        if (tePath.pathElements() != null) {
+            for (PathElement pathElementTe : tePath.pathElements()) {
+                org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                   .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te
+                   .state.telinkattributes.underlay.underlayprimarypath.PathElement
+                   .PathElementBuilder pathElementYangBuilder =
+                org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                   .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te
+                   .state.telinkattributes.underlay.underlayprimarypath.DefaultPathElement
+                   .builder();
+                // FIXME: pathElementTe does not have any getter or
+                // setter at the moment --> pathElementYangBuilder =
+                // pathElementYangBuilder.pathElementId(pathElementTe.getPathElementId());
+                pathBuilder = pathBuilder.addToPathElement(pathElementYangBuilder.build());
+            }
+        }
+        pathBuilder = pathBuilder.networkIdRef(NetworkId.fromString(
+                                               tePath.ref().getNetworkId().toString()))
+                                 .teTopologyIdRef(TeTopologyId.fromString(
+                                               tePath.ref().getTopologyId().topologyId()));
+        return yangBuilder.underlayPrimaryPath(pathBuilder.build());
+    }
+
+    private static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                      .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te
+                      .state.telinkattributes.Underlay.UnderlayBuilder
+           te2YangStateUnderlayBackupPaths(
+                   org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                   .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te
+                   .state.telinkattributes.Underlay.UnderlayBuilder yangBuilder,
+            List<org.onosproject.tetopology.management.api.link.UnderlayBackupPath> tePaths) {
+
+        for (UnderlayBackupPath tePath : tePaths) {
+            org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+            .ietftetopology.networks.network.link.augmentedntlink.te.state.telinkattributes
+            .underlay.UnderlayBackupPath.UnderlayBackupPathBuilder
+            pathBuilder = org.onosproject.yang.gen.v1.urn.ietf.params.xml
+            .ns.yang.ietf.te.topology.rev20160708.ietftetopology.networks.network.link.augmentedntlink
+            .te.state.telinkattributes.underlay.DefaultUnderlayBackupPath
+                    .builder();
+
+            pathBuilder = pathBuilder.index(tePath.index());
+            pathBuilder = pathBuilder.networkIdRef(NetworkId.fromString(
+                                                        tePath.ref().getNetworkId().toString()))
+                                     .teTopologyIdRef(TeTopologyId.fromString(
+                                                        tePath.ref().getTopologyId().topologyId()));
+            for (PathElement backupPathElementTe : tePath.pathElements()) {
+                org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                   .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te
+                   .state.telinkattributes.underlay.underlaybackuppath.PathElement
+                   .PathElementBuilder elementBuilder =
+                org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                   .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te
+                   .state.telinkattributes.underlay.underlaybackuppath.DefaultPathElement.builder();
+                // FIXME: backupPathElementTe does not have any
+                // getter or setter at the moment -->
+                // elementBuilder =
+                // elementBuilder.pathElementId(backupPathElementTe.getPathElementId());
+                pathBuilder = pathBuilder.addToPathElement(elementBuilder.build());
+            }
+            yangBuilder = yangBuilder.addToUnderlayBackupPath(pathBuilder.build());
+        }
+
+        return yangBuilder;
+    }
+
+    /**
+     * TE Link underlay path State object conversion from TE Topology subsystem to YANG.
+     *
+     * @param tePath TE underlay object
+     * @return Link underlay path State YANG object
+     */
+    private static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                       .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te
+                       .state.telinkattributes.Underlay
+                   teSubsystem2YangStateUnderlayPath(UnderlayPath tePath) {
+        checkNotNull(tePath, E_NULL_TELINK_UNDERLAY_PATH);
+
+        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+            .ietftetopology.networks.network.link.augmentedntlink.te.state.telinkattributes
+            .Underlay.UnderlayBuilder builder =
+        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+            .ietftetopology.networks.network.link.augmentedntlink.te.state.telinkattributes
+            .DefaultUnderlay.builder().underlayProtectionType(tePath.protectionType());
+
+        if (tePath.primaryPath() != null) {
+            builder = te2YangStateUnderlayPrimaryPath(builder, tePath.primaryPath());
+
+        }
+        if (tePath.trailSrc() != null) {
+            builder = builder.underlayTrailSrc(
+                          new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te
+                                  .topology.rev20160708.ietftetopology.networks.network.link
+                                  .augmentedntlink.te.state.telinkattributes.underlay
+                                  .DefaultUnderlayTrailSrc.UnderlayTrailSrcBuilder()
+                              .networkRef(NetworkId.fromString(
+                                              tePath.trailSrc().networkId().toString()))
+                              .nodeRef(NodeId.fromString(
+                                              tePath.trailSrc().nodeId().toString()))
+                              .tpRef(TpId.fromString(
+                                              tePath.trailSrc().tpId().toString()))
+                              .build());
+        }
+        if (tePath.trailDes() != null) {
+            builder = builder.underlayTrailDes(
+                          new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te
+                                   .topology.rev20160708.ietftetopology.networks.network.link
+                                   .augmentedntlink.te.state.telinkattributes.underlay
+                                   .DefaultUnderlayTrailDes.UnderlayTrailDesBuilder()
+                              .networkRef(NetworkId.fromString(
+                                              tePath.trailDes().networkId().toString()))
+                              .nodeRef(NodeId.fromString(
+                                              tePath.trailDes().nodeId().toString()))
+                              .tpRef(TpId.fromString(
+                                              tePath.trailDes().tpId().toString()))
+                              .build());
+        }
+        if (tePath.backupPaths() != null) {
+            builder = te2YangStateUnderlayBackupPaths(builder, tePath.backupPaths());
+        }
+
+        return builder.build();
+    }
+
+    /**
+     * TE Link Config object conversion from TE Topology subsystem to YANG.
+     *
+     * @param teLink TE link object
+     * @return TE Link Config YANG object
+     */
+    private static Config teLink2YangConfig(TeLink teLink) {
+        checkNotNull(teLink, E_NULL_TELINK_DATA);
+
+        TeLinkAttributesBuilder attrBuilder = DefaultTeLinkAttributes.builder();
+        if (teLink.linkIndex() != null) {
+            attrBuilder = attrBuilder.linkIndex(teLink.linkIndex());
+        }
+        if (teLink.name() != null) {
+            attrBuilder = attrBuilder.name(teLink.name());
+        }
+        if (teLink.adminStatus() != null) {
+            attrBuilder = attrBuilder
+                    .adminStatus(EnumConverter
+                            .teSubsystem2YangAdminStatus(teLink
+                            .adminStatus()));
+        }
+        if (teLink.accessType() != null) {
+            attrBuilder = attrBuilder
+                    .accessType(teSubsystem2YangTeLinkAccess(teLink
+                            .accessType()));
+        }
+        if (teLink.linkProtectionType() != null) {
+            attrBuilder = attrBuilder
+                    .linkProtectionType(teSubsystem2YangLinkProtectionType(teLink
+                            .linkProtectionType()));
+        }
+        if (teLink.maxLinkBandwidth() != null) {
+            attrBuilder = attrBuilder.maxLinkBandwidth(teLink.maxLinkBandwidth());
+        }
+        if (teLink.maxResvLinkBandwidth() != null) {
+            attrBuilder = attrBuilder.maxResvLinkBandwidth(teLink.maxResvLinkBandwidth());
+        }
+        attrBuilder = attrBuilder.teDefaultMetric(teLink.teDefaultMetric());
+        if (teLink.teSrlgs() != null) {
+            TeSrlgsBuilder teSrlgsBuilder = DefaultTeSrlgs.builder();
+            for (Long srlgLongVal : teLink.teSrlgs()) {
+                teSrlgsBuilder = teSrlgsBuilder.addToValue(new Srlg(srlgLongVal));
+            }
+            attrBuilder = attrBuilder.teSrlgs(teSrlgsBuilder.build());
+        }
+        attrBuilder = attrBuilder.isAbstract(teLink.isAbstract());
+        if (teLink.underlayPath() != null) {
+            attrBuilder = attrBuilder.underlay(
+                              teSubsystem2YangConfigUnderlayPath(teLink.underlayPath()));
+        }
+        if (teLink.externalDomain() != null) {
+            ExternalDomainBuilder edBuilder =
+                    DefaultExternalDomain.builder()
+                                         .plugId(teLink.externalDomain().plugId())
+                                         .remoteTeLinkTpId(TeTpId.fromString(
+                                                  teLink.externalDomain().remoteTeLinkTpId().toString()))
+                                         .remoteTeNodeId(TeNodeId.fromString(
+                                                  teLink.externalDomain().remoteTeNodeId().toString()));
+            attrBuilder = attrBuilder.externalDomain(edBuilder.build());
+        }
+
+        if (teLink.unreservedBandwidths() != null) {
+            for (org.onosproject.tetopology.management.api.link.UnreservedBandwidth unResBwTe :
+                        teLink.unreservedBandwidths()) {
+                UnreservedBandwidthBuilder urBuilder =
+                        DefaultUnreservedBandwidth.builder()
+                                                  .bandwidth(unResBwTe.bandwidth())
+                                                  .priority(unResBwTe.priority());
+                attrBuilder = attrBuilder.addToUnreservedBandwidth(urBuilder.build());
+            }
+        }
+
+        ConfigBuilder yangConfigBuilder = DefaultConfig.builder()
+                                                       .teLinkAttributes(attrBuilder.build());
+        return yangConfigBuilder.build();
+    }
+
+    private static LinkProtectionTypeEnum
+                        teSubsystem2YangLinkProtectionType(LinkProtectionType linkProtectionType) {
+        switch (linkProtectionType) {
+        case ENHANCED:
+            return LinkProtectionTypeEnum.ENHANCED;
+        case EXTRA_TRAFFIC:
+            return LinkProtectionTypeEnum.EXTRA_TRAFFIC;
+        case SHARED:
+            return LinkProtectionTypeEnum.SHARED;
+        case UNPROTECTED:
+            return LinkProtectionTypeEnum.UNPROTECTED;
+        case YANGAUTOPREFIX1_FOR_1:
+            return LinkProtectionTypeEnum.YANGAUTOPREFIX1_FOR_1;
+        case YANGAUTOPREFIX1_PLUS_1:
+            return LinkProtectionTypeEnum.YANGAUTOPREFIX1_PLUS_1;
+        default:
+            return null;
+        }
+    }
+
+    private static TeLinkAccessType teSubsystem2YangTeLinkAccess(
+                       org.onosproject.tetopology.management.api.link.TeLinkAccessType accessType) {
+        switch (accessType) {
+        case MULTI_ACCESS:
+            return TeLinkAccessType.of(TeLinkAccessTypeEnum.MULTI_ACCESS);
+        case POINT_TO_POINT:
+            return TeLinkAccessType.of(TeLinkAccessTypeEnum.POINT_TO_POINT);
+        default:
+            return null;
+        }
+    }
+
+    /**
+     * TE Link State object conversion from TE Topology subsystem to YANG.
+     *
+     * @param teLink TE link object
+     * @return TE Link State YANG object
+     */
+    private static State teLink2YangState(TeLink teLink) {
+        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+            .ietftetopology.networks.network.link.augmentedntlink.te.state.TeLinkAttributes
+            .TeLinkAttributesBuilder attrBuilder =
+        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+            .ietftetopology.networks.network.link.augmentedntlink.te.state.DefaultTeLinkAttributes
+            .builder()
+            .teDefaultMetric(teLink.teDefaultMetric())
+            .isAbstract(teLink.isAbstract());
+        if (teLink.linkIndex() != null) {
+            attrBuilder = attrBuilder.linkIndex(teLink.linkIndex());
+        }
+        if (teLink.name() != null) {
+            attrBuilder = attrBuilder.name(teLink.name());
+        }
+        if (teLink.adminStatus() != null) {
+            attrBuilder = attrBuilder
+                    .adminStatus(EnumConverter
+                            .teSubsystem2YangAdminStatus(teLink
+                            .adminStatus()));
+        }
+        if (teLink.accessType() != null) {
+            attrBuilder = attrBuilder
+                    .accessType(teSubsystem2YangTeLinkAccess(teLink
+                            .accessType()));
+        }
+        if (teLink.linkProtectionType() != null) {
+            attrBuilder = attrBuilder
+                    .linkProtectionType(teSubsystem2YangStateLinkProtectionType(teLink
+                            .linkProtectionType()));
+        }
+        if (teLink.maxLinkBandwidth() != null) {
+            attrBuilder = attrBuilder.maxLinkBandwidth(teLink.maxLinkBandwidth());
+        }
+        if (teLink.maxResvLinkBandwidth() != null) {
+            attrBuilder = attrBuilder.maxResvLinkBandwidth(teLink.maxResvLinkBandwidth());
+        }
+        if (teLink.teSrlgs() != null) {
+            org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+                .ietftetopology.networks.network.link.augmentedntlink.te.state.telinkattributes
+                .TeSrlgs.TeSrlgsBuilder srlgsBuilder =
+            org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+                .ietftetopology.networks.network.link.augmentedntlink.te.state.telinkattributes
+                .DefaultTeSrlgs.builder();
+            for (Long srlgLongVal : teLink.teSrlgs()) {
+                srlgsBuilder = srlgsBuilder.addToValue(new Srlg(srlgLongVal));
+            }
+            attrBuilder = attrBuilder.teSrlgs(srlgsBuilder.build());
+        }
+        if (teLink.underlayPath() != null) {
+            attrBuilder = attrBuilder.underlay(teSubsystem2YangStateUnderlayPath(teLink.underlayPath()));
+        }
+        if (teLink.externalDomain() != null) {
+            org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+                    .ietftetopology.networks.network.link.augmentedntlink.te.state.telinkattributes
+                    .ExternalDomain.ExternalDomainBuilder edBuilder =
+            org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+                    .ietftetopology.networks.network.link.augmentedntlink.te.state.telinkattributes
+                    .DefaultExternalDomain.builder()
+                                          .plugId(teLink.externalDomain().plugId())
+                                          .remoteTeLinkTpId(TeTpId.fromString(
+                                                  teLink.externalDomain().remoteTeLinkTpId().toString()))
+                                          .remoteTeNodeId(TeNodeId.fromString(
+                                                  teLink.externalDomain().remoteTeNodeId().toString()));
+            attrBuilder = attrBuilder.externalDomain(edBuilder.build());
+        }
+        if (teLink.unreservedBandwidths() != null) {
+            for (org.onosproject.tetopology.management.api.link.UnreservedBandwidth unResBwTe :
+                    teLink.unreservedBandwidths()) {
+                org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+                    .ietftetopology.networks.network.link.augmentedntlink.te.state.telinkattributes
+                    .UnreservedBandwidth.UnreservedBandwidthBuilder urBuilder =
+                org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+                    .ietftetopology.networks.network.link.augmentedntlink.te.state.telinkattributes
+                    .DefaultUnreservedBandwidth.builder()
+                                               .bandwidth(unResBwTe.bandwidth())
+                                               .priority(unResBwTe.priority());
+                attrBuilder = attrBuilder.addToUnreservedBandwidth(urBuilder.build());
+            }
+        }
+
+        StateBuilder yangStateBuilder = DefaultState.builder()
+                                                    .teLinkAttributes(attrBuilder.build());
+        if (teLink.opStatus() != null) {
+            yangStateBuilder = yangStateBuilder
+                    .operStatus(EnumConverter
+                            .teSubsystem2YangOperStatus(teLink
+                            .opStatus()));
+        }
+
+        return yangStateBuilder.build();
+    }
+
+    private static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.
+        rev20160708.ietftetopology.networks.network.link.augmentedntlink.te.state.informationsourceentry.
+        LinkProtectionTypeEnum teSubsystem2YangStateLinkProtectionType(LinkProtectionType linkProtectionType) {
+        switch (linkProtectionType) {
+        case ENHANCED:
+            return org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.
+                    rev20160708.ietftetopology.networks.network.link.augmentedntlink.te.state.informationsourceentry.
+                    LinkProtectionTypeEnum.ENHANCED;
+        case EXTRA_TRAFFIC:
+            return org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.
+                    rev20160708.ietftetopology.networks.network.link.augmentedntlink.te.state.informationsourceentry.
+                    LinkProtectionTypeEnum.EXTRA_TRAFFIC;
+        case SHARED:
+            return org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.
+                    rev20160708.ietftetopology.networks.network.link.augmentedntlink.te.state.informationsourceentry.
+                    LinkProtectionTypeEnum.SHARED;
+        case UNPROTECTED:
+            return org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.
+                    rev20160708.ietftetopology.networks.network.link.augmentedntlink.te.state.informationsourceentry.
+                    LinkProtectionTypeEnum.UNPROTECTED;
+        case YANGAUTOPREFIX1_FOR_1:
+            return org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.
+                    rev20160708.ietftetopology.networks.network.link.augmentedntlink.te.state.informationsourceentry.
+                    LinkProtectionTypeEnum.YANGAUTOPREFIX1_FOR_1;
+        case YANGAUTOPREFIX1_PLUS_1:
+            return org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.
+                    rev20160708.ietftetopology.networks.network.link.augmentedntlink.te.state.informationsourceentry.
+                    LinkProtectionTypeEnum.YANGAUTOPREFIX1_PLUS_1;
+        default:
+            return null;
+        }
+    }
+
+    /**
+     * Link object conversion from TE Topology subsystem to YANG.
+     *
+     * @param teLink TE subsystem link object
+     * @return YANG link object
+     */
+    public static Link teSubsystem2YangLink(
+            org.onosproject.tetopology.management.api.link.NetworkLink teLink) {
+        checkNotNull(teLink, E_NULL_TELINK);
+
+        LinkId linkId = LinkId.fromString(teLink.linkId().toString());
+        LinkBuilder builder = DefaultLink.builder().linkId(linkId);
+        if (teLink.getSupportingLinkIds() != null) {
+            List<SupportingLink> slinks = Lists.newArrayList();
+            SupportingLinkBuilder spLinkBuilder = DefaultSupportingLink.builder();
+            for (NetworkLinkKey linkKey : teLink.getSupportingLinkIds()) {
+                slinks.add(spLinkBuilder.networkRef(NetworkId.fromString(
+                                                    linkKey.networkId().toString()))
+                                        .linkRef(LinkId.fromString(
+                                                    linkKey.linkId().toString()))
+                                        .build());
+            }
+            builder = builder.supportingLink(slinks);
+        }
+        if (teLink.getSource() != null) {
+            SourceBuilder sourceBuilder = DefaultSource
+                                              .builder()
+                                              .sourceNode(NodeId.fromString(
+                                                   teLink.getSource().nodeId().toString()))
+                                              .sourceTp(TpId.fromString(
+                                                   teLink.getSource().tpId().toString()));
+            builder = builder.source(sourceBuilder.build());
+        }
+        if (teLink.getDestination() != null) {
+            DestinationBuilder destBuilder = DefaultDestination
+                                                 .builder()
+                                                 .destNode(NodeId.fromString(
+                                                      teLink.getDestination().nodeId().toString()))
+                                                 .destTp(TpId.fromString(
+                                                      teLink.getDestination().tpId().toString()));
+            builder = builder.destination(destBuilder.build());
+        }
+
+        if (teLink.getTe() != null) {
+            TeLink teData = teLink.getTe();
+            TeBuilder yangTeBuilder = DefaultTe.builder()
+                                               .config(teLink2YangConfig(teData))
+                                               .state(teLink2YangState(teData));
+            AugmentedNtLinkBuilder linkAugmentBuilder =
+                    DefaultAugmentedNtLink.builder()
+                                          .te(yangTeBuilder.build());
+            builder.addYangAugmentedInfo(linkAugmentBuilder.build(), AugmentedNtLink.class);
+        }
+
+        return builder.build();
+    }
+
+    private static org.onosproject.tetopology.management.api.link.UnderlayPath
+           yang2TeSubsystemUnderlayPrimaryPath(
+                            org.onosproject.tetopology.management.api.link.UnderlayPath teUnderlay,
+                            UnderlayPrimaryPath yangpath) {
+        org.onosproject.tetopology.management.api.link.UnderlayPrimaryPath teUnderlayPrimaryPath =
+                new org.onosproject.tetopology.management.api.link.UnderlayPrimaryPath();
+        teUnderlayPrimaryPath.setRef(new TeNetworkTopologyId(KeyId.keyId(
+                                             yangpath.networkIdRef().toString()),
+                                     new org.onosproject.tetopology.management.api.TeTopologyId(
+                                             yangpath.providerIdRef().uint32(),
+                                             yangpath.clientIdRef().uint32(),
+                                             yangpath.teTopologyIdRef().toString())));
+
+        List<PathElement> pathElementList = Lists.newArrayList();
+        for (org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+                .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+                .underlay.underlayprimarypath.PathElement pathElementConfigYang :
+                    yangpath.pathElement()) {
+            //PathElement tePathElement = new PathElement();
+            // FIXME: tePathElement does not have any getter
+            // or setter at the moment -->
+            // tePathElement.set...
+            // TODO: construct the tePathElement object
+            // properly using pathElementConfigYang
+            //pathElementList.add(tePathElement);
+        }
+        teUnderlayPrimaryPath.setPathElement(pathElementList);
+        teUnderlay.setPrimaryPath(teUnderlayPrimaryPath);
+
+        return teUnderlay;
+    }
+
+    private static org.onosproject.tetopology.management.api.link.UnderlayPath
+            yang2TeSubsystemUnderlayBackupPaths(
+                     org.onosproject.tetopology.management.api.link.UnderlayPath teUnderlay,
+                     List<org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te
+                             .topology.rev20160708.ietftetopology.networks.network.link
+                             .augmentedntlink.te.config.telinkattributes.underlay
+                             .UnderlayBackupPath> yangpaths) {
+        List<UnderlayBackupPath> underlayBackupPathsList = Lists.newArrayList();
+        for (org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
+                .ietftetopology.networks.network.link.augmentedntlink.te.config.telinkattributes
+                    .underlay.UnderlayBackupPath yangConfig : yangpaths) {
+            UnderlayBackupPath ubp = new UnderlayBackupPath();
+            ubp.setIndex(yangConfig.index());
+            ubp.setRef(new TeNetworkTopologyId(KeyId.keyId(yangConfig.networkIdRef().toString()),
+                                               new org.onosproject.tetopology.management.api.TeTopologyId(
+                                                       yangConfig.providerIdRef().uint32(),
+                                                       yangConfig.clientIdRef().uint32(),
+                                                       yangConfig.teTopologyIdRef().toString()
+                                              )));
+            List<PathElement> backupPathElementList = Lists.newArrayList();
+            for (org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology
+                    .rev20160708.ietftetopology.networks.network.link.augmentedntlink.te.config
+                    .telinkattributes.underlay.underlaybackuppath.PathElement
+                        pathElementBackupYang : yangConfig.pathElement()) {
+                //PathElement tePathElementBackup = new PathElement();
+                // FIXME: tePathElement does not have any
+                // getter or setter at the moment -->
+                // tePathElement.set...
+                // TODO: construct the tePathElement object
+                // properly using pathElementBackupYang
+                //backupPathElementList.add(tePathElementBackup);
+            }
+            ubp.setPathElement(backupPathElementList);
+        }
+        teUnderlay.setBackupPath(underlayBackupPathsList);
+
+        return teUnderlay;
+    }
+
+    /**
+     * TE Link underlay path Config object conversion from YANG to TE Topology subsystem.
+     *
+     * @param yangLinkAtrr YANG link Config YANG object
+     * @return teSubsystem TE underlay path object
+     */
+    private static org.onosproject.tetopology.management.api.link.UnderlayPath
+                    yang2TeSubsystemUnderlayPath(TeLinkAttributes yangLinkAtrr) {
+        checkNotNull(yangLinkAtrr, E_NULL_YANG_TELINK_CONFIG);
+
+        org.onosproject.tetopology.management.api.link.UnderlayPath teUnderlay =
+                new org.onosproject.tetopology.management.api.link.UnderlayPath();
+
+        teUnderlay.setProtectionType(yangLinkAtrr.underlay().underlayProtectionType());
+
+        if (yangLinkAtrr.underlay().underlayPrimaryPath() != null) {
+            teUnderlay = yang2TeSubsystemUnderlayPrimaryPath(teUnderlay,
+                                    yangLinkAtrr.underlay().underlayPrimaryPath());
+        }
+
+        if (yangLinkAtrr.underlay().underlayBackupPath() != null) {
+            teUnderlay = yang2TeSubsystemUnderlayBackupPaths(teUnderlay,
+                    yangLinkAtrr.underlay().underlayBackupPath());
+        }
+
+        if (yangLinkAtrr.underlay().underlayTrailSrc() != null) {
+            teUnderlay.setTrailSrc(new TerminationPointKey(
+                                            KeyId.keyId(yangLinkAtrr.underlay().underlayTrailSrc()
+                                                            .networkRef().uri().toString()),
+                                            KeyId.keyId(yangLinkAtrr.underlay().underlayTrailSrc()
+                                                            .nodeRef().uri().toString()),
+                                            KeyId.keyId(yangLinkAtrr.underlay().underlayTrailSrc()
+                                                            .tpRef().uri().toString())));
+        }
+
+        if (yangLinkAtrr.underlay().underlayTrailDes() != null) {
+            teUnderlay.setTrailDes(new TerminationPointKey(
+                                            KeyId.keyId(yangLinkAtrr.underlay().underlayTrailDes()
+                                                            .networkRef().uri().toString()),
+                                            KeyId.keyId(yangLinkAtrr.underlay().underlayTrailDes()
+                                                            .nodeRef().uri().toString()),
+                                            KeyId.keyId(yangLinkAtrr.underlay().underlayTrailDes()
+                                                            .tpRef().uri().toString())));
+        }
+
+        return teUnderlay;
+    }
+
+    private static TeLink yang2TeLinkAttributes(TeLinkAttributes yangLinkAtrr,
+                                                State opState) {
+        TeLink te = new TeLink(yangLinkAtrr.linkIndex());
+        if (yangLinkAtrr.name() != null) {
+            te.setName(yangLinkAtrr.name());
+        }
+        if (yangLinkAtrr.adminStatus() != null) {
+            te.setAdminStatus(EnumConverter.yang2TeSubsystemAdminStatus(
+                                                yangLinkAtrr.adminStatus()));
+        }
+        if (opState != null && opState.operStatus() != null) {
+            te.setOpStatus(EnumConverter.yang2TeSubsystemOpStatus(
+                                             opState.operStatus()));
+        }
+        if (yangLinkAtrr.accessType() != null) {
+            te.setAccessType(yang2TeSubsystemAccessType(
+                                 yangLinkAtrr.accessType()));
+        }
+        if (yangLinkAtrr.linkProtectionType() != null) {
+            te.setLinkProtectionType(yang2TeSubsystemLinkProtectionType(
+                                         yangLinkAtrr.linkProtectionType()));
+        }
+        if (yangLinkAtrr.maxLinkBandwidth() != null) {
+            te.setMaxLinkBandwidth(yangLinkAtrr.maxLinkBandwidth());
+        }
+        if (yangLinkAtrr.maxResvLinkBandwidth() != null) {
+            te.setMaxResvLinkBandwidth(yangLinkAtrr.maxResvLinkBandwidth());
+        }
+        te.setTeDefaultMetric(yangLinkAtrr.teDefaultMetric());
+        te.setIsAbstract(yangLinkAtrr.isAbstract());
+        if (yangLinkAtrr.teSrlgs() != null) {
+            List<Long> srlgs = Lists.newArrayList();
+            for (Srlg srlgConfigYang : yangLinkAtrr.teSrlgs().value()) {
+                srlgs.add(srlgConfigYang.uint32());
+            }
+            te.setTeSrlgs(srlgs);
+        }
+        if (yangLinkAtrr.externalDomain() != null) {
+            te.setExternalDomain(new ExternalDomain(
+                    KeyId.keyId(yangLinkAtrr.externalDomain()
+                                    .remoteTeNodeId().toString()),
+                    KeyId.keyId(yangLinkAtrr.externalDomain()
+                                    .remoteTeLinkTpId().toString()),
+                    yangLinkAtrr.externalDomain().plugId()));
+        }
+        if (yangLinkAtrr.underlay() != null) {
+            te.setUnderlayPath(yang2TeSubsystemUnderlayPath(yangLinkAtrr));
+        }
+        if (yangLinkAtrr.unreservedBandwidth() != null) {
+            List<org.onosproject.tetopology.management.api.link.UnreservedBandwidth>
+                    unreservedBandwidths = Lists.newArrayList();
+            for (UnreservedBandwidth urBwYang : yangLinkAtrr.unreservedBandwidth()) {
+                org.onosproject.tetopology.management.api.link.UnreservedBandwidth unResBw =
+                        new org.onosproject.tetopology.management.api.link.UnreservedBandwidth(
+                                urBwYang.priority(),
+                                urBwYang.bandwidth());
+                unreservedBandwidths.add(unResBw);
+            }
+            te.setUnreservedBandwidths(unreservedBandwidths);
+        }
+        return te;
+    }
+
+    private static LinkProtectionType
+        yang2TeSubsystemLinkProtectionType(LinkProtectionTypeEnum linkProtectionType) {
+        switch (linkProtectionType) {
+        case ENHANCED:
+            return LinkProtectionType.ENHANCED;
+        case EXTRA_TRAFFIC:
+            return LinkProtectionType.EXTRA_TRAFFIC;
+        case SHARED:
+            return LinkProtectionType.SHARED;
+        case UNPROTECTED:
+            return LinkProtectionType.UNPROTECTED;
+        case YANGAUTOPREFIX1_FOR_1:
+            return LinkProtectionType.YANGAUTOPREFIX1_FOR_1;
+        case YANGAUTOPREFIX1_PLUS_1:
+            return LinkProtectionType.YANGAUTOPREFIX1_PLUS_1;
+        default:
+            return null;
+        }
+    }
+
+    private static org.onosproject.tetopology.management.api.link.TeLinkAccessType
+        yang2TeSubsystemAccessType(TeLinkAccessType accessType) {
+        switch (accessType.enumeration()) {
+        case MULTI_ACCESS:
+            return org.onosproject.tetopology.management.api.link.TeLinkAccessType.MULTI_ACCESS;
+        case POINT_TO_POINT:
+            return org.onosproject.tetopology.management.api.link.TeLinkAccessType.POINT_TO_POINT;
+        default:
+            return null;
+        }
+    }
+
+    /**
+     * Link object conversion from YANG to TE Topology subsystem.
+     *
+     * @param yangLink YANG link object
+     * @param networkId YANG networkId object
+     * @return TE subsystem link object
+     */
+    public static org.onosproject.tetopology.management.api.link.NetworkLink
+            yang2TeSubsystemLink(Link yangLink, NetworkId networkId) {
+        checkNotNull(yangLink, E_NULL_YANG_TELINK);
+
+        org.onosproject.tetopology.management.api.link.DefaultNetworkLink link =
+                new org.onosproject.tetopology.management.api.link.DefaultNetworkLink(
+                        KeyId.keyId(yangLink.linkId().uri().toString()));
+
+        if (yangLink.supportingLink() != null) {
+            List<NetworkLinkKey> spLinkIds = Lists.newArrayList();
+            for (SupportingLink yangSpLink : yangLink.supportingLink()) {
+                NetworkLinkKey linkKey = new NetworkLinkKey(KeyId.keyId(yangSpLink.networkRef().uri().toString()),
+                                                            KeyId.keyId(yangSpLink.linkRef().uri().toString()));
+                spLinkIds.add(linkKey);
+            }
+            link.setSupportingLinkIds(spLinkIds);
+        }
+
+        if (yangLink.source() != null) {
+            TerminationPointKey source = new TerminationPointKey(
+                                                 KeyId.keyId(networkId.uri().toString()),
+                                                 KeyId.keyId(yangLink.source().sourceNode().uri().toString()),
+                                                 KeyId.keyId(yangLink.source().sourceTp().uri().toString()));
+            link.setSource(source);
+        }
+
+        if (yangLink.destination() != null) {
+            TerminationPointKey destination = new TerminationPointKey(
+                                                      KeyId.keyId(networkId.uri().toString()),
+                                                      KeyId.keyId(yangLink.destination().destNode().uri().toString()),
+                                                      KeyId.keyId(yangLink.destination().destTp().uri().toString()));
+            link.setDestination(destination);
+        }
+
+        if (yangLink.yangAugmentedInfoMap() != null && !yangLink.yangAugmentedInfoMap().isEmpty()) {
+
+            AugmentedNtLink yangLinkAugment =
+                    (AugmentedNtLink) yangLink.yangAugmentedInfo(AugmentedNtLink.class);
+            if (yangLinkAugment != null &&
+                    yangLinkAugment.te() != null &&
+                    yangLinkAugment.te().config() != null) {
+                TeLinkAttributes yangLinkAtrr =
+                        yangLinkAugment.te().config().teLinkAttributes();
+                if (yangLinkAtrr != null && yangLinkAtrr.linkIndex() != null) {
+                    TeLink te = yang2TeLinkAttributes(yangLinkAtrr, yangLinkAugment.te().state());
+                    link.setTe(te);
+                }
+            }
+        }
+        return link;
+    }
+
+}