ONOS-5454 [TE Tunnel NBI ] Interact with tetunnel APP to provide CRUD interfaces for RESTconf request

Change-Id: I5b2dad9d65c72cb9adc7f313272319ea8046a6a8
diff --git a/apps/tenbi/utils/pom.xml b/apps/tenbi/utils/pom.xml
index e866a85..89ad331 100644
--- a/apps/tenbi/utils/pom.xml
+++ b/apps/tenbi/utils/pom.xml
@@ -45,6 +45,27 @@
             <artifactId>onos-app-tetopology-api</artifactId>
             <version>${project.version}</version>
         </dependency>
-     </dependencies>
-
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-tetunnel-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>3.2.0</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Private-Package>
+                            org.onosproject.yang.gen.*,
+                        </Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/apps/tenbi/utils/src/main/java/org/onosproject/teyang/utils/tunnel/BasicConverter.java b/apps/tenbi/utils/src/main/java/org/onosproject/teyang/utils/tunnel/BasicConverter.java
new file mode 100644
index 0000000..3b7ee37
--- /dev/null
+++ b/apps/tenbi/utils/src/main/java/org/onosproject/teyang/utils/tunnel/BasicConverter.java
@@ -0,0 +1,97 @@
+/*
+ * 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.tunnel;
+
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev20130715.ietfinettypes.IpAddress;
+
+/**
+ * Basic converter tools for ietf NBI & SBI.
+ */
+public abstract class BasicConverter {
+
+    //no instantiation
+    private BasicConverter() {
+
+    }
+
+    /**
+     * Converts a long value to IpAddress.
+     *
+     * @param value long value
+     * @return ip address
+     */
+    static IpAddress longToIp(long value) {
+        StringBuilder sb = new StringBuilder();
+        sb.append((value >> 24) & 0xFF).append(".");
+        sb.append((value >> 16) & 0xFF).append(".");
+        sb.append((value >> 8) & 0xFF).append(".");
+        sb.append(value & 0xFF);
+        return IpAddress.fromString(sb.toString());
+    }
+
+    /**
+     * Converts a long value to byte array.
+     *
+     * @param value long value
+     * @return byte array
+     */
+    static byte[] longToByte(long value) {
+        long temp = value;
+        byte[] b = new byte[8];
+        for (int i = 0; i < b.length; i++) {
+            b[i] = new Long(temp & 0xff).byteValue();
+            temp = temp >> 8;
+        }
+        return b;
+    }
+
+    /**
+     * Converts a IP address to long value.
+     *
+     * @param ipAddress IP address
+     * @return long value
+     */
+    static long ipToLong(IpAddress ipAddress) {
+        long[] ip = new long[4];
+        String strIp = ipAddress.toString();
+        int position1 = strIp.indexOf(".");
+        int position2 = strIp.indexOf(".", position1 + 1);
+        int position3 = strIp.indexOf(".", position2 + 1);
+        ip[0] = Long.parseLong(strIp.substring(0, position1));
+        ip[1] = Long.parseLong(strIp.substring(position1 + 1, position2));
+        ip[2] = Long.parseLong(strIp.substring(position2 + 1, position3));
+        ip[3] = Long.parseLong(strIp.substring(position3 + 1));
+        return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
+    }
+
+    /**
+     * Converts byte array to long value.
+     *
+     * @param bytes byte array
+     * @return long value
+     */
+    static long bytesToLong(byte[] bytes) {
+        return ((long) bytes[7] & 255L) << 56 |
+                ((long) bytes[6] & 255L) << 48 |
+                ((long) bytes[5] & 255L) << 40 |
+                ((long) bytes[4] & 255L) << 32 |
+                ((long) bytes[3] & 255L) << 24 |
+                ((long) bytes[2] & 255L) << 16 |
+                ((long) bytes[1] & 255L) << 8 |
+                (long) bytes[0] & 255L;
+    }
+}
diff --git a/apps/tenbi/utils/src/main/java/org/onosproject/teyang/utils/tunnel/TunnelConverter.java b/apps/tenbi/utils/src/main/java/org/onosproject/teyang/utils/tunnel/TunnelConverter.java
new file mode 100755
index 0000000..30d42b0
--- /dev/null
+++ b/apps/tenbi/utils/src/main/java/org/onosproject/teyang/utils/tunnel/TunnelConverter.java
@@ -0,0 +1,439 @@
+/*
+ * 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.tunnel;
+
+import com.google.common.collect.Lists;
+import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetopology.management.api.node.TeNodeKey;
+import org.onosproject.tetopology.management.api.node.TtpKey;
+import org.onosproject.tetunnel.api.tunnel.DefaultTeTunnel;
+import org.onosproject.tetunnel.api.tunnel.TeTunnel;
+import org.onosproject.tetunnel.api.tunnel.TeTunnelKey;
+import org.onosproject.tetunnel.api.tunnel.path.DefaultTePath;
+import org.onosproject.tetunnel.api.tunnel.path.DefaultTeRouteUnnumberedLink;
+import org.onosproject.tetunnel.api.tunnel.path.TePath;
+import org.onosproject.tetunnel.api.tunnel.path.TeRouteSubobject;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.IetfTe;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.IetfTeOpParam;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.DefaultTe;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.Te;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.Type;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type.DefaultDynamic;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type.DefaultExplicit;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type.explicit.DefaultExplicitRouteObjects;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type.explicit.ExplicitRouteObjects;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.Config;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.DefaultPrimaryPaths;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.DefaultState;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.PrimaryPaths;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.State;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.DefaultTunnels;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.Tunnels;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.tunnels.DefaultTunnel;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.tunnels.Tunnel;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProt1Forn;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtBidir1To1;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtReroute;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtRerouteExtra;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtType;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtUnidir1To1;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtUnprotected;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.PathSignalingRsvpte;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.PathSignalingSr;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.RouteIncludeEro;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.StateDown;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.StateUp;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TunnelP2Mp;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TunnelP2p;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TunnelType;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.explicitroutesubobject.type.DefaultUnnumberedLink;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.explicitroutesubobject.type.UnnumberedLink;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.onosproject.tetunnel.api.tunnel.TeTunnel.LspProtectionType;
+import static org.onosproject.tetunnel.api.tunnel.path.TeRouteSubobject.Type.UNNUMBERED_LINK;
+import static org.onosproject.teyang.utils.tunnel.BasicConverter.bytesToLong;
+import static org.onosproject.teyang.utils.tunnel.BasicConverter.ipToLong;
+import static org.onosproject.teyang.utils.tunnel.BasicConverter.longToByte;
+import static org.onosproject.teyang.utils.tunnel.BasicConverter.longToIp;
+import static org.slf4j.LoggerFactory.getLogger;
+
+
+/**
+ * Tunnel convert utils.
+ */
+public final class TunnelConverter {
+
+    private static final Logger log = getLogger(TunnelConverter.class);
+    private static final String DEFAULT_PATH_NAME = "ietfPath";
+    private static final String DEFAULT_PATH_CONSTRAINT = "ietfPath";
+    private static final int DEFAULT_PATH_PREFERENCE = 1;
+    private static final boolean DEFAULT_CSPF_STATE = true;
+    private static final boolean DEFAULT_LOCKDOWN_STATE = true;
+
+    // no instantiation
+    private TunnelConverter() {
+    }
+
+    /**
+     * Build a general IETF TE object with a giving tunnel list. for there are
+     * many kind of attributes in IETF TE, now we only care about the tunnel
+     * attributes.
+     *
+     * @param tunnels tunnels in the TE network
+     * @return IETF te info in the TE network
+     */
+    public static IetfTe buildIetfTeWithTunnels(List<Tunnel> tunnels) {
+        Tunnels teTunnels = new DefaultTunnels
+                .TunnelsBuilder()
+                .tunnel(tunnels)
+                .build();
+        Te te = new DefaultTe
+                .TeBuilder()
+                .tunnels(teTunnels)
+                .build();
+        return new IetfTeOpParam
+                .IetfTeBuilder()
+                .te(te)
+                .yangIetfTeOpType(IetfTe.OnosYangOpType.NONE)
+                .build();
+    }
+
+    public static IetfTe buildIetfTe(TeTunnel teTunnel) {
+        Tunnel tunnel = te2YangTunnelConverter(teTunnel);
+        return buildIetfTeWithTunnels(Lists.newArrayList(tunnel));
+    }
+
+    /**
+     * Converts a specific te tunnel defined in the APP to the general te tunnel
+     * defined in YANG model.
+     *
+     * @param tunnel te tunnel defined in APP
+     * @return tunnel defined in YANG model
+     */
+    public static Tunnel te2YangTunnelConverter(TeTunnel tunnel) {
+        List<PrimaryPaths> pathsList = new ArrayList<>();
+        //TODO add path info after yang tool change to guava from google-collect
+        tunnel.primaryPaths()
+                .forEach(tePath -> pathsList.add(te2YangPrimaryPath(tePath)));
+
+        Tunnel.TunnelBuilder builder = new DefaultTunnel
+                .TunnelBuilder()
+                .type(te2YangTunnelType(tunnel.type()))
+                .name(tunnel.name())
+                .identifier(tunnel.teTunnelKey().teTunnelId())
+                .state(te2YangTunnelState(tunnel))
+                .primaryPaths(pathsList);
+
+        return builder.build();
+    }
+
+    private static State te2YangTunnelState(TeTunnel tunnel) {
+        State.StateBuilder stateBuilder = new DefaultState.StateBuilder();
+        stateBuilder.name(tunnel.name())
+                .identifier((int) tunnel.teTunnelKey().teTunnelId())
+                .source((longToIp(tunnel.srcNode().teNodeId())))
+                .destination((longToIp(tunnel.dstNode().teNodeId())))
+                .srcTpId(longToByte(tunnel.srcTp().ttpId()))
+                .dstTpId(longToByte(tunnel.dstTp().ttpId()))
+                .adminStatus(te2YangStateType(tunnel.adminStatus()))
+                .lspProtectionType(
+                        te2YangProtectionType(tunnel.lspProtectionType()))
+                .type(te2YangTunnelType(tunnel.type()))
+                .build();
+        return stateBuilder.build();
+    }
+
+    private static PrimaryPaths te2YangPrimaryPath(TePath tePath) {
+        DefaultPrimaryPaths.PrimaryPathsBuilder builder = new DefaultPrimaryPaths
+                .PrimaryPathsBuilder()
+                .name(DEFAULT_PATH_NAME)
+                .preference(DEFAULT_PATH_PREFERENCE)
+                .state(te2YangPrimaryPathState(tePath))
+                .yangPrimaryPathsOpType(IetfTe.OnosYangOpType.NONE);
+        return builder.build();
+    }
+
+    private static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
+            .te.rev20160705.ietfte.p2pprimarypathparams.State
+    te2YangPrimaryPathState(TePath tePath) {
+
+        List<TeRouteSubobject> teRouteSubobjects = tePath.explicitRoute();
+
+        List<ExplicitRouteObjects> routeObjects = new ArrayList<>();
+        teRouteSubobjects.forEach(teRouteSubobject -> {
+            routeObjects.add(te2YangRouteSubobject(teRouteSubobject));
+        });
+        DefaultExplicit.ExplicitBuilder explicitBuilder =
+                DefaultExplicit.builder().explicitRouteObjects(routeObjects);
+
+        return new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.
+                te.rev20160705.ietfte.p2pprimarypathparams.DefaultState
+                .StateBuilder()
+                .type(explicitBuilder.build())
+                .pathNamedConstraint(DEFAULT_PATH_CONSTRAINT)
+                .noCspf(DEFAULT_CSPF_STATE)
+                .lockdown(DEFAULT_LOCKDOWN_STATE)
+                .build();
+    }
+
+    private static ExplicitRouteObjects
+    te2YangRouteSubobject(TeRouteSubobject routeSubobject) {
+
+        TeRouteSubobject.Type type = routeSubobject.type();
+        UnnumberedLink yanglink = null;
+        //TODO implement other kind of TeRouteSubobject type
+        if (type == UNNUMBERED_LINK) {
+            DefaultTeRouteUnnumberedLink unnumberedLink =
+                    (DefaultTeRouteUnnumberedLink) routeSubobject;
+            TeNodeKey nodeKey = unnumberedLink.node();
+            TtpKey ttpKey = unnumberedLink.ttp();
+
+            yanglink = DefaultUnnumberedLink.builder()
+                    .routerId(longToIp(nodeKey.teNodeId()))
+                    .interfaceId(ttpKey.ttpId())
+                    .build();
+
+        }
+
+        //TODO implement other kind of explicitRoute usage type
+        return DefaultExplicitRouteObjects.builder()
+                .type(yanglink)
+                .explicitRouteUsage(RouteIncludeEro.class)
+                .build();
+    }
+
+    /**
+     * Converts a YANG TE tunnel defined in the YANG model to a specific TE
+     * tunnel defined in the TE tunnel APP.
+     *
+     * @param tunnel yang tunnel object
+     * @return default Te tunnel defined in TE tunnel APP
+     */
+    public static DefaultTeTunnel yang2TeTunnel(org.onosproject.yang.gen.v1.
+                                                        urn.ietf.params.xml.
+                                                        ns.yang.ietf.te.
+                                                        rev20160705.ietfte.
+                                                        tunnelsgrouping.
+                                                        tunnels.Tunnel
+                                                        tunnel,
+                                                TeTopologyKey topologyKey) {
+        //get config info
+        Config config = tunnel.config();
+
+        //build basic attribute, node and ttp
+        TeNodeKey srcNodeKey = new TeNodeKey(topologyKey, ipToLong(config.source()));
+        TeNodeKey dstNodeKey = new TeNodeKey(topologyKey, ipToLong(config.destination()));
+
+        TtpKey srcTtpKey = new TtpKey(srcNodeKey, bytesToLong(config.srcTpId()));
+        TtpKey dstTtpKey = new TtpKey(srcNodeKey, bytesToLong(config.dstTpId()));
+
+        //check if paths have been set
+        List<PrimaryPaths> primaryPaths = tunnel.primaryPaths();
+        List<TePath> paths = new ArrayList<>();
+        primaryPaths.forEach(primaryPath -> paths.add(
+                yang2TePrimaryPaths(primaryPath, topologyKey)));
+
+        //build the te tunnel
+        DefaultTeTunnel.Builder builder = new DefaultTeTunnel.Builder();
+
+        return builder.teTunnelKey(new TeTunnelKey(topologyKey, config.identifier()))
+                .name(config.name())
+                .type(yang2TeTunnelType(config.type()))
+                .lspProtectionType(yang2TeProtectionType(config.lspProtectionType()))
+                .adminState(yang2TeStateType(config.adminStatus()))
+                .srcNode(srcNodeKey)
+                .dstNode(dstNodeKey)
+                .srcTp(srcTtpKey)
+                .dstTp(dstTtpKey)
+                .primaryPaths(paths).build();
+    }
+
+    private static TePath yang2TePrimaryPaths(PrimaryPaths primaryPath,
+                                              TeTopologyKey topologyKey) {
+        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.
+                rev20160705.ietfte.p2pprimarypathparams.Config
+                pathConfig = primaryPath.config();
+
+        TePath tePath;
+        TePath.Type tePathType = null;
+        Type type = pathConfig.type();
+
+        if (type == null) {
+            return new DefaultTePath(TePath.Type.DYNAMIC,
+                                     Lists.newArrayList(),
+                                     Lists.newArrayList(),
+                                     Lists.newArrayList());
+        }
+
+        Class<? extends Type> typeClass = type.getClass();
+
+        List<TeRouteSubobject> routeSubobjects = new ArrayList<>();
+
+        if (typeClass.isAssignableFrom(DefaultExplicit.class)) {
+            DefaultExplicit explicitPath = (DefaultExplicit) type;
+            explicitPath
+                    .explicitRouteObjects()
+                    .forEach(o -> routeSubobjects.add(
+                            yang2TeRouteSubobject(o, topologyKey)));
+            tePathType = TePath.Type.EXPLICIT;
+
+        } else if (typeClass.isAssignableFrom(DefaultDynamic.class)) {
+            tePathType = TePath.Type.DYNAMIC;
+        }
+
+        tePath = new DefaultTePath(tePathType,
+                                   Lists.newArrayList(),
+                                   routeSubobjects,
+                                   Lists.newArrayList());
+        return tePath;
+    }
+
+    private static TeRouteSubobject
+    yang2TeRouteSubobject(ExplicitRouteObjects routeObject,
+                          TeTopologyKey topologyKey) {
+
+        //TODO implement other types of route type
+        DefaultUnnumberedLink type = (DefaultUnnumberedLink) routeObject.type();
+        TeNodeKey nodeKey = new TeNodeKey(topologyKey, ipToLong(type.routerId()));
+        TtpKey tpId = new TtpKey(nodeKey, type.interfaceId());
+        return new DefaultTeRouteUnnumberedLink(nodeKey, tpId);
+    }
+
+    private static TeTunnel.Type yang2TeTunnelType(Class type) {
+        TeTunnel.Type tunnelType = null;
+        if (type.isAssignableFrom(TunnelP2Mp.class)) {
+            tunnelType = TeTunnel.Type.P2MP;
+        } else if (type.isAssignableFrom(TunnelP2p.class)) {
+            tunnelType = TeTunnel.Type.P2P;
+        } else if (type.isAssignableFrom(PathSignalingRsvpte.class)) {
+            tunnelType = TeTunnel.Type.PATH_SIGNALING_RSVPTE;
+        } else if (type.isAssignableFrom(PathSignalingSr.class)) {
+            tunnelType = TeTunnel.Type.PATH_SIGNALING_SR;
+        }
+        return tunnelType;
+    }
+
+
+    private static Class<? extends TunnelType> te2YangTunnelType(TeTunnel.Type type) {
+        Class<? extends TunnelType> tunnelType = null;
+        switch (type) {
+
+            case P2P:
+                tunnelType = TunnelP2p.class;
+                break;
+            case P2MP:
+                tunnelType = TunnelP2Mp.class;
+                break;
+            case PATH_SIGNALING_RSVPTE:
+                tunnelType = PathSignalingRsvpte.class;
+
+                break;
+            case PATH_SIGNALING_SR:
+                tunnelType = PathSignalingSr.class;
+                break;
+            default:
+                log.error("Unknown te tunnel type {}", type.toString());
+        }
+        return tunnelType;
+    }
+
+    private static LspProtectionType
+    yang2TeProtectionType(Class<? extends LspProtType> protType) {
+        LspProtectionType type = null;
+        if (protType.isAssignableFrom(LspProt1Forn.class)) {
+            type = LspProtectionType.LSP_PROT_1_FOR_N;
+        } else if (protType.isAssignableFrom(LspProtBidir1To1.class)) {
+            type = LspProtectionType.LSP_PROT_BIDIR_1_TO_1;
+        } else if (protType.isAssignableFrom(LspProtReroute.class)) {
+            type = LspProtectionType.LSP_PROT_REROUTE;
+        } else if (protType.isAssignableFrom(LspProtRerouteExtra.class)) {
+            type = LspProtectionType.LSP_PROT_REROUTE_EXTRA;
+        } else if (protType.isAssignableFrom(LspProtUnidir1To1.class)) {
+            type = LspProtectionType.LSP_PROT_UNIDIR_1_TO_1;
+        } else if (protType.isAssignableFrom(LspProtUnprotected.class)) {
+            type = LspProtectionType.LSP_PROT_UNPROTECTED;
+        }
+        return type;
+    }
+
+    private static Class<? extends LspProtType>
+    te2YangProtectionType(LspProtectionType protType) {
+        Class<? extends LspProtType> type = null;
+        switch (protType) {
+
+            case LSP_PROT_UNPROTECTED:
+                type = LspProtUnprotected.class;
+                break;
+            case LSP_PROT_REROUTE:
+                type = LspProtReroute.class;
+                break;
+            case LSP_PROT_REROUTE_EXTRA:
+                type = LspProtRerouteExtra.class;
+                break;
+            case LSP_PROT_UNIDIR_1_TO_1:
+                type = LspProtUnidir1To1.class;
+                break;
+            case LSP_PROT_BIDIR_1_TO_1:
+                type = LspProtBidir1To1.class;
+                break;
+            case LSP_PROT_1_FOR_N:
+                type = LspProt1Forn.class;
+                break;
+            default:
+                log.error("Unknown te tunnel type {}", protType.toString());
+        }
+        return type;
+    }
+
+    private static TeTunnel.State
+    yang2TeStateType(Class<? extends org.onosproject.yang.gen.v1.urn.ietf.
+            params.xml.ns.yang.ietf.te.types.
+            rev20160705.ietftetypes.StateType> stateType) {
+        TeTunnel.State teStateType = null;
+        if (stateType.isAssignableFrom(StateUp.class)) {
+            teStateType = TeTunnel.State.UP;
+        } else if (stateType.isAssignableFrom(StateDown.class)) {
+            teStateType = TeTunnel.State.DOWN;
+        }
+        return teStateType;
+    }
+
+    private static Class<? extends org.onosproject.yang.gen.v1.urn.ietf.params.
+            xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.StateType>
+    te2YangStateType(TeTunnel.State stateType) {
+        Class<? extends org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.
+                ietf.te.types.rev20160705.ietftetypes.StateType> state = null;
+
+        switch (stateType) {
+
+            case DOWN:
+                state = StateDown.class;
+                break;
+            case UP:
+                state = StateUp.class;
+                break;
+            default:
+                log.error("Unknown te tunnel type {}", stateType.toString());
+
+        }
+        return state;
+    }
+}
diff --git a/apps/tenbi/utils/src/main/java/org/onosproject/teyang/utils/tunnel/package-info.java b/apps/tenbi/utils/src/main/java/org/onosproject/teyang/utils/tunnel/package-info.java
new file mode 100644
index 0000000..ae4586a
--- /dev/null
+++ b/apps/tenbi/utils/src/main/java/org/onosproject/teyang/utils/tunnel/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * The utilities for conversions between TE tunnel APP and IETF TE tunnel Yang
+ * generated Java code.
+ */
+package org.onosproject.teyang.utils.tunnel;
\ No newline at end of file
diff --git a/apps/tenbi/utils/src/test/java/org/onosproject/teyang/utils/tunnel/BasicConverterTest.java b/apps/tenbi/utils/src/test/java/org/onosproject/teyang/utils/tunnel/BasicConverterTest.java
new file mode 100644
index 0000000..a49bbc3
--- /dev/null
+++ b/apps/tenbi/utils/src/test/java/org/onosproject/teyang/utils/tunnel/BasicConverterTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2016-present 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.tunnel;
+
+import org.junit.Test;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev20130715.ietfinettypes.IpAddress;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test of the basic converter tools.
+ */
+public class BasicConverterTest {
+    private byte[] bytes1 = new byte[]{1, 1, 1, 1, 0, 0, 0, 0};
+    private byte[] bytes2 = new byte[]{2, 2, 2, 2, 0, 0, 0, 0};
+    private byte[] bytes3 = new byte[]{2, 0, 0, 0, 0, 0, 0, 0};
+    private IpAddress ip1 = IpAddress.fromString("1.1.1.1");
+    private IpAddress ip2 = IpAddress.fromString("2.2.2.2");
+    private long longNum1 = 16843009;
+    private long longNum2 = 33686018;
+    private static final String CVT_F = "Convert failed: ";
+
+
+    @Test
+    public void longToIp() throws Exception {
+        assertEquals(CVT_F + "longToIp", ip1, BasicConverter.longToIp(longNum1));
+        assertEquals(CVT_F + "longToIp", ip2, BasicConverter.longToIp(longNum2));
+    }
+
+    @Test
+    public void longToByte() throws Exception {
+        assertArrayEquals(CVT_F + "longToByte", bytes1,
+                          BasicConverter.longToByte(longNum1));
+        assertArrayEquals(CVT_F + "longToByte", bytes2,
+                          BasicConverter.longToByte(longNum2));
+    }
+
+    @Test
+    public void ipToLong() throws Exception {
+        assertEquals(CVT_F + "ipToLong", longNum1, BasicConverter.ipToLong(ip1));
+        assertEquals(CVT_F + "ipToLong", longNum2, BasicConverter.ipToLong(ip2));
+    }
+
+    @Test
+    public void bytesToLong() throws Exception {
+        assertEquals(CVT_F + "bytesToLong", longNum1,
+                     BasicConverter.bytesToLong(bytes1));
+        assertEquals(CVT_F + "bytesToLong", longNum2,
+                     BasicConverter.bytesToLong(bytes2));
+
+        assertEquals(CVT_F + "bytesToLong", 2,
+                     BasicConverter.bytesToLong(bytes3));
+    }
+}
\ No newline at end of file