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

Change-Id: I5b2dad9d65c72cb9adc7f313272319ea8046a6a8
diff --git a/apps/tenbi/pom.xml b/apps/tenbi/pom.xml
index 0f59a82..304ed80 100644
--- a/apps/tenbi/pom.xml
+++ b/apps/tenbi/pom.xml
@@ -31,6 +31,7 @@
 
     <modules>
         <module>topology</module>
+        <module>tunnel</module>
         <module>yangmodel</module>
         <module>utils</module>
     </modules>
diff --git a/apps/tenbi/tunnel/app.xml b/apps/tenbi/tunnel/app.xml
new file mode 100755
index 0000000..78997d3
--- /dev/null
+++ b/apps/tenbi/tunnel/app.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * 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.
+  ~  */
+  -->
+<app name="org.onosproject.tenbi.tunnel" origin="HUAWEI" version="${project.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-app-tenbi-yangmodel/${project.version}</artifact>
+</app>
+
diff --git a/apps/tenbi/tunnel/features.xml b/apps/tenbi/tunnel/features.xml
new file mode 100755
index 0000000..9610045
--- /dev/null
+++ b/apps/tenbi/tunnel/features.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ /*
+  ~  * 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.
+  ~  */
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <repository>mvn:${project.groupId}/onos-app-tenbi-yangmodel/${project.version}/xml/features</repository>
+    <feature name="${project.artifactId}" version="${project.version}" description="${project.description}">
+        <feature>onos-api</feature>
+        <feature>onos-app-tenbi-yangmodel</feature>
+        <bundle>mvn:${project.groupId}/onos-app-tetopology-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-yms-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-tetunnel-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-tenbi-utils/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
+    </feature>
+</features>
diff --git a/apps/tenbi/tunnel/pom.xml b/apps/tenbi/tunnel/pom.xml
new file mode 100755
index 0000000..23f761f
--- /dev/null
+++ b/apps/tenbi/tunnel/pom.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~  * 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.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>onos-app-tenbi</artifactId>
+        <groupId>org.onosproject</groupId>
+        <version>1.8.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>onos-app-tenbi-tunnel</artifactId>
+    <packaging>bundle</packaging>
+    <description>IETF TE Tunnel NBI</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-tenbi-yangmodel</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-tenbi-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-yms-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-incubator-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-tetunnel-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-tetopology-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
+        </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.*,
+                            org.onosproject.teyang.*,
+                            <!--org.onosproject.tetopology.management.api.*,-->
+                        </Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/apps/tenbi/tunnel/src/main/java/org/onosproject/tenbi/tunnel/TeTunnelNbiManager.java b/apps/tenbi/tunnel/src/main/java/org/onosproject/tenbi/tunnel/TeTunnelNbiManager.java
new file mode 100755
index 0000000..38bd667
--- /dev/null
+++ b/apps/tenbi/tunnel/src/main/java/org/onosproject/tenbi/tunnel/TeTunnelNbiManager.java
@@ -0,0 +1,152 @@
+/*
+ * 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.tenbi.tunnel;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.event.AbstractListenerManager;
+import org.onosproject.tetopology.management.api.TeTopology;
+import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetopology.management.api.TeTopologyService;
+import org.onosproject.tetunnel.api.TeTunnelAdminService;
+import org.onosproject.tetunnel.api.TeTunnelService;
+import org.onosproject.tetunnel.api.tunnel.DefaultTeTunnel;
+import org.onosproject.tetunnel.api.tunnel.TeTunnel;
+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.IetfTeService;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.IetfTeEvent;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.IetfTeEventListener;
+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;
+import org.onosproject.yms.ymsm.YmsService;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.tetopology.management.api.TeTopology.BIT_MERGED;
+import static org.onosproject.teyang.utils.tunnel.TunnelConverter.buildIetfTeWithTunnels;
+import static org.onosproject.teyang.utils.tunnel.TunnelConverter.te2YangTunnelConverter;
+import static org.onosproject.teyang.utils.tunnel.TunnelConverter.yang2TeTunnel;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * The IETF TE Tunnel NBI Manager implementation.
+ */
+@Component(immediate = true)
+@Service
+public class TeTunnelNbiManager
+        extends AbstractListenerManager<IetfTeEvent, IetfTeEventListener>
+        implements IetfTeService {
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected YmsService ymsService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TeTunnelService tunnelService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TeTopologyService toplogyService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TeTunnelAdminService tunnelAdminService;
+
+    @Activate
+    protected void activate() {
+        ymsService.registerService(this, IetfTeService.class, null);
+        ymsService.registerService(this, IetfTeTypes.class, null);
+        log.info("started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        ymsService.unRegisterService(this, IetfTeService.class);
+        ymsService.unRegisterService(this, IetfTeTypes.class);
+        log.info("stopped");
+    }
+
+    @Override
+    public IetfTe getIetfTe(IetfTeOpParam ietfTe) {
+        List<Tunnel> tunnels = new ArrayList<>();
+        Collection<TeTunnel> teTunnels = tunnelService.getTeTunnels();
+        teTunnels.forEach(teTunnel -> {
+            Tunnel tunnel = te2YangTunnelConverter(teTunnel);
+            tunnels.add(tunnel);
+        });
+        IetfTe newIetfTe = buildIetfTeWithTunnels(tunnels);
+        return ietfTe.processSubtreeFiltering(newIetfTe, false);
+    }
+
+    @Override
+    public void setIetfTe(IetfTeOpParam ietfTe) {
+        checkNotNull(ietfTe, "Ietf te params should not be null");
+        //FIXME use topology id configured by user
+        // for there is no topology id param in the definition of te tunnel
+        // we use the merged topology id as the default topology where we create
+        // the tunnel, need to talk with the ietf-te draft writer.
+        TeTopologyKey topologyKey = getTopologyKey();
+        if (topologyKey == null) {
+            log.error("No usable topology now!");
+            return;
+        }
+
+        ietfTe.te().tunnels().tunnel().forEach(tunnel -> {
+            DefaultTeTunnel teTunnel = yang2TeTunnel(tunnel, topologyKey);
+            tunnelAdminService.createTeTunnel(teTunnel);
+        });
+    }
+
+    @Override
+    public void globalsRpc() {
+
+    }
+
+    @Override
+    public void interfacesRpc() {
+
+    }
+
+    @Override
+    public void tunnelsRpc() {
+        //TODO add implement for the te tunnel rpc
+    }
+
+    private TeTopologyKey getTopologyKey() {
+        TeTopologyKey key = null;
+        Optional<TeTopology> teTopology = toplogyService
+                .teTopologies()
+                .teTopologies()
+                .values()
+                .stream()
+                .filter(topology -> topology.flags().get(BIT_MERGED))
+                .findFirst();
+        if (teTopology.isPresent()) {
+            TeTopology topology = teTopology.get();
+            key = topology.teTopologyId();
+        }
+        return key;
+    }
+}
diff --git a/apps/tenbi/tunnel/src/main/java/org/onosproject/tenbi/tunnel/package-info.java b/apps/tenbi/tunnel/src/main/java/org/onosproject/tenbi/tunnel/package-info.java
new file mode 100755
index 0000000..e9a797c
--- /dev/null
+++ b/apps/tenbi/tunnel/src/main/java/org/onosproject/tenbi/tunnel/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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 implementations of IETF TE Tunnel YANG NBI.
+ */
+package org.onosproject.tenbi.tunnel;
\ No newline at end of file
diff --git a/apps/tenbi/tunnel/src/test/org/onosproject/tenbi/tunnel/TeTunnelNbiManagerTest.java b/apps/tenbi/tunnel/src/test/org/onosproject/tenbi/tunnel/TeTunnelNbiManagerTest.java
new file mode 100644
index 0000000..944fd03
--- /dev/null
+++ b/apps/tenbi/tunnel/src/test/org/onosproject/tenbi/tunnel/TeTunnelNbiManagerTest.java
@@ -0,0 +1,380 @@
+/*
+ * 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.tenbi.tunnel;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+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.TeTunnelAdminService;
+import org.onosproject.tetunnel.api.TeTunnelService;
+import org.onosproject.tetunnel.api.lsp.TeLsp;
+import org.onosproject.tetunnel.api.lsp.TeLspKey;
+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.inet.types.rev20130715.ietfinettypes.IpAddress;
+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.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.DefaultConfig;
+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.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.LspProtUnprotected;
+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.StateUp;
+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.explicitroutesubobject.type.DefaultUnnumberedLink;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.tetunnel.api.tunnel.TeTunnel.LspProtectionType.LSP_PROT_REROUTE;
+import static org.onosproject.tetunnel.api.tunnel.TeTunnel.Type.P2P;
+import static org.onosproject.tetunnel.api.tunnel.path.TeRouteSubobject.Type.UNNUMBERED_LINK;
+
+/**
+ * Unit tests for TeTunnelNbiManager.
+ */
+public class TeTunnelNbiManagerTest {
+    private static final String TE_REQ_FAILED = "IETF TE reqeust failed: ";
+    private static final String NAME = "testTunnel";
+    private IpAddress srcIp = IpAddress.fromString("1.1.1.1");
+    private IpAddress dstIp = IpAddress.fromString("2.2.2.2");
+    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 long id1 = 16843009;
+    private long id2 = 33686018;
+
+
+    private TeTunnelNbiManager manager;
+    private TeTunnel testTeTunnel;
+
+
+    @Before
+    public void setUp() throws Exception {
+        manager = new TeTunnelNbiManager();
+    }
+
+    @Test
+    public void getIetfTe() throws Exception {
+        TeTunnelService tunnelService = createMock(TeTunnelService.class);
+        expect(tunnelService.getTeTunnels())
+                .andReturn(ImmutableList.of(buildTunnel()))
+                .once();
+        replay(tunnelService);
+
+        manager.tunnelService = tunnelService;
+
+        IetfTe ietfTe = manager.getIetfTe((IetfTeOpParam) buildGetIetfTeParams());
+
+        assertNotNull(TE_REQ_FAILED + "te null", ietfTe.te());
+        assertNotNull(TE_REQ_FAILED + "tunnel null", ietfTe.te().tunnels());
+
+        List<Tunnel> tunnelList = ietfTe.te().tunnels().tunnel();
+        assertEquals(TE_REQ_FAILED + "wrong tunnel size", 1, tunnelList.size());
+
+        Tunnel tunnel = tunnelList.get(0);
+        List<PrimaryPaths> pathsList = tunnel.primaryPaths();
+        assertNotNull(TE_REQ_FAILED + "path null", pathsList);
+        assertEquals(TE_REQ_FAILED + "wrong path size", 1, pathsList.size());
+
+        Type type = pathsList.get(0).state().type();
+        assertTrue(TE_REQ_FAILED + "wrong path type",
+                   type instanceof DefaultExplicit);
+        DefaultExplicit explicitPath = (DefaultExplicit) type;
+        List<ExplicitRouteObjects> routeObjectses =
+                explicitPath.explicitRouteObjects();
+        assertEquals(TE_REQ_FAILED + "wrong route size", 2, routeObjectses.size());
+
+        ExplicitRouteObjects routeObjects = routeObjectses.get(1);
+        assertTrue(TE_REQ_FAILED + "wrong route object type",
+                   routeObjects.type() instanceof DefaultUnnumberedLink);
+
+        DefaultUnnumberedLink link = (DefaultUnnumberedLink) routeObjects.type();
+        assertEquals(TE_REQ_FAILED + "wrong route id",
+                     IpAddress.fromString("0.0.0.2"), link.routerId());
+        assertEquals(TE_REQ_FAILED + "wrong interface id", 2, link.interfaceId());
+
+        State state = tunnel.state();
+        assertEquals(TE_REQ_FAILED + "wrong state",
+                     StateUp.class, state.adminStatus());
+        assertEquals(TE_REQ_FAILED + "wrong source",
+                     IpAddress.fromString("0.0.0.1"), state.source());
+    }
+
+    @Test
+    public void setIetfTe() throws Exception {
+        manager.tunnelAdminService = new TestTunnelAdmin();
+        manager.setIetfTe((IetfTeOpParam) buildPostIetfTeParams());
+        assertEquals(NAME, testTeTunnel.name());
+        List<TePath> tePaths = testTeTunnel.primaryPaths();
+        assertEquals(1, tePaths.size());
+        TePath tePath = tePaths.get(0);
+        List<TeRouteSubobject> teRouteSubobjects = tePath.explicitRoute();
+        assertEquals(2, teRouteSubobjects.size());
+        TeRouteSubobject routeSubobject = teRouteSubobjects.get(1);
+        assertEquals(UNNUMBERED_LINK, routeSubobject.type());
+        DefaultTeRouteUnnumberedLink link =
+                (DefaultTeRouteUnnumberedLink) routeSubobject;
+        assertEquals(id2, link.node().teNodeId());
+        assertEquals(id2, link.ttp().ttpId());
+
+    }
+
+    private IetfTe buildGetIetfTeParams() {
+        Te te = new DefaultTe
+                .TeBuilder()
+                .yangTeOpType(IetfTe.OnosYangOpType.NONE)
+                .build();
+        return new IetfTeOpParam
+                .IetfTeBuilder()
+                .te(te)
+                .yangIetfTeOpType(IetfTe.OnosYangOpType.NONE)
+                .build();
+    }
+
+    private IetfTe buildPostIetfTeParams() {
+        Tunnel tunnel = buildYangTunnel();
+        Tunnels teTunnels = new DefaultTunnels
+                .TunnelsBuilder()
+                .tunnel(Lists.newArrayList(tunnel))
+                .build();
+        Te te = new DefaultTe
+                .TeBuilder()
+                .tunnels(teTunnels)
+                .yangTeOpType(IetfTe.OnosYangOpType.NONE)
+                .build();
+        return new IetfTeOpParam
+                .IetfTeBuilder()
+                .te(te)
+                .yangIetfTeOpType(IetfTe.OnosYangOpType.NONE)
+                .build();
+    }
+
+    private Tunnel buildYangTunnel() {
+        TeTunnel teTunnel = buildTunnel();
+        checkNotNull(teTunnel);
+        Config config = new DefaultConfig.ConfigBuilder()
+                .name(NAME)
+                .adminStatus(StateUp.class)
+                .source(srcIp)
+                .destination(dstIp)
+                .srcTpId(bytes1)
+                .dstTpId(bytes2)
+                .type(TunnelP2p.class)
+                .lspProtectionType(LspProtUnprotected.class)
+                .build();
+
+        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.
+                rev20160705.ietftetypes.explicitroutesubobject.type.
+                UnnumberedLink yangLink1 = DefaultUnnumberedLink.builder()
+                .routerId(srcIp)
+                .interfaceId(id1)
+                .build();
+
+        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.
+                rev20160705.ietftetypes.explicitroutesubobject.type.
+                UnnumberedLink yangLink2 = DefaultUnnumberedLink.builder()
+                .routerId(dstIp)
+                .interfaceId(id2)
+                .build();
+
+        ExplicitRouteObjects routeObject1 = DefaultExplicitRouteObjects.builder()
+                .type(yangLink1)
+                .explicitRouteUsage(RouteIncludeEro.class)
+                .build();
+
+        ExplicitRouteObjects routeObject2 = DefaultExplicitRouteObjects.builder()
+                .type(yangLink2)
+                .explicitRouteUsage(RouteIncludeEro.class)
+                .build();
+
+
+        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.
+                rev20160705.ietfte.pathparamsconfig.type.Explicit explicit
+                = DefaultExplicit.builder()
+                .explicitRouteObjects(ImmutableList.of(routeObject1, routeObject2))
+                .build();
+        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.
+                rev20160705.ietfte.p2pprimarypathparams.Config pathConfig
+                = org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.
+                te.rev20160705.ietfte.p2pprimarypathparams.DefaultConfig.builder()
+                .pathNamedConstraint("onlyPath")
+                .lockdown(true)
+                .noCspf(true)
+                .type(explicit)
+                .build();
+
+        PrimaryPaths primaryPaths = DefaultPrimaryPaths.builder()
+                .config(pathConfig).build();
+
+        return DefaultTunnel.builder()
+                .name(config.name())
+                .type(config.type())
+                .config(config)
+                .primaryPaths(Lists.newArrayList(primaryPaths))
+                .build();
+    }
+
+    private TeTunnel buildTunnel() {
+        TeTopologyKey topologyKey = new TeTopologyKey(1, 2, 3);
+        TeTunnelKey teTunnelKey = new TeTunnelKey(topologyKey, 1);
+
+        TeNodeKey srcNodeKey = new TeNodeKey(topologyKey, 1);
+        TeNodeKey dstNodeKey = new TeNodeKey(topologyKey, 2);
+
+        TtpKey srcTtpKey = new TtpKey(srcNodeKey, 1);
+        TtpKey dstTtpKey = new TtpKey(srcNodeKey, 2);
+
+        TeLspKey lspKey = new TeLspKey(teTunnelKey, 1);
+
+        DefaultTeRouteUnnumberedLink unnumberedLink1 =
+                new DefaultTeRouteUnnumberedLink(srcNodeKey, srcTtpKey);
+        DefaultTeRouteUnnumberedLink unnumberedLink2 =
+                new DefaultTeRouteUnnumberedLink(dstNodeKey, dstTtpKey);
+        List<TeRouteSubobject> explicitRouteList = new ArrayList<>();
+
+        explicitRouteList.add(unnumberedLink1);
+        explicitRouteList.add(unnumberedLink2);
+        TePath tePath = new DefaultTePath(TePath.Type.EXPLICIT,
+                                          Lists.newArrayList(lspKey),
+                                          explicitRouteList,
+                                          Lists.newArrayList());
+
+        return DefaultTeTunnel.builder()
+                .teTunnelKey(teTunnelKey)
+                .name(NAME)
+                .type(P2P)
+                .adminState(TeTunnel.State.UP)
+                .srcNode(srcNodeKey)
+                .dstNode(dstNodeKey)
+                .srcTp(srcTtpKey)
+                .dstTp(dstTtpKey)
+                .lspProtectionType(LSP_PROT_REROUTE)
+                .primaryPaths(Lists.newArrayList(tePath))
+                .build();
+    }
+
+    private class TestTunnelAdmin implements TeTunnelAdminService {
+
+        @Override
+        public TunnelId createTeTunnel(TeTunnel teTunnel) {
+            TunnelId tunnelId = TunnelId.valueOf(teTunnel.teTunnelKey().toString());
+            testTeTunnel = teTunnel;
+            return tunnelId;
+        }
+
+        @Override
+        public void setTunnelId(TeTunnelKey teTunnelKey, TunnelId tunnelId) {
+
+        }
+
+        @Override
+        public void updateTeTunnel(TeTunnel teTunnel) {
+
+        }
+
+        @Override
+        public void updateTunnelState(TeTunnelKey key, org.onosproject.incubator.net.tunnel.Tunnel.State state) {
+
+        }
+
+        @Override
+        public void removeTeTunnel(TeTunnelKey teTunnelKey) {
+
+        }
+
+        @Override
+        public void removeTeTunnels() {
+
+        }
+
+        @Override
+        public void setSegmentTunnel(TeTunnelKey e2eTunnelKey, List<TeTunnelKey> segmentTunnels) {
+
+        }
+
+        @Override
+        public TeTunnel getTeTunnel(TeTunnelKey teTunnelKey) {
+            return null;
+        }
+
+        @Override
+        public TeTunnel getTeTunnel(TunnelId tunnelId) {
+            return null;
+        }
+
+        @Override
+        public TunnelId getTunnelId(TeTunnelKey teTunnelKey) {
+            return null;
+        }
+
+        @Override
+        public Collection<TeTunnel> getTeTunnels() {
+            return null;
+        }
+
+        @Override
+        public Collection<TeTunnel> getTeTunnels(TeTunnel.Type type) {
+            return null;
+        }
+
+        @Override
+        public Collection<TeTunnel> getTeTunnels(TeTopologyKey teTopologyKey) {
+            return null;
+        }
+
+        @Override
+        public TeLsp getTeLsp(TeLspKey key) {
+            return null;
+        }
+
+        @Override
+        public Collection<TeLsp> getTeLsps() {
+            return null;
+        }
+    }
+
+}
\ No newline at end of file
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
diff --git a/apps/tenbi/yangmodel/pom.xml b/apps/tenbi/yangmodel/pom.xml
index c87becf..7ff466c 100644
--- a/apps/tenbi/yangmodel/pom.xml
+++ b/apps/tenbi/yangmodel/pom.xml
@@ -33,12 +33,12 @@
         <dependency>
             <groupId>org.onosproject</groupId>
             <artifactId>onos-yang-maven-plugin</artifactId>
-            <version>1.9</version>
+            <version>1.10</version>
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
             <artifactId>onos-yang-datamodel</artifactId>
-            <version>1.9</version>
+            <version>1.10</version>
         </dependency>
     </dependencies>
 
@@ -47,7 +47,7 @@
            <plugin>
                 <groupId>org.onosproject</groupId>
                 <artifactId>onos-yang-maven-plugin</artifactId>
-                <version>1.9</version>
+                <version>1.10</version>
                 <executions>
                     <execution>
                         <goals>
diff --git a/apps/tenbi/yangmodel/src/main/yang/ietf-te.yang b/apps/tenbi/yangmodel/src/main/yang/ietf-te.yang
new file mode 100755
index 0000000..40374fe
--- /dev/null
+++ b/apps/tenbi/yangmodel/src/main/yang/ietf-te.yang
@@ -0,0 +1,882 @@
+module ietf-te {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-te";
+
+  /* Replace with IANA when assigned */
+  prefix "te";
+
+  /* Import TE generic types */
+  import ietf-te-types {
+    prefix te-types;
+  }
+
+  import ietf-inet-types {
+    prefix inet;
+  }
+
+  organization
+    "IETF Traffic Engineering Architecture and Signaling (TEAS)
+     Working Group";
+
+  contact
+    "WG Web:   <http://tools.ietf.org/wg/teas/>
+     WG List:  <mailto:teas@ietf.org>
+
+     WG Chair: Lou Berger
+               <mailto:lberger@labn.net>
+
+     WG Chair: Vishnu Pavan Beeram
+               <mailto:vbeeram@juniper.net>
+
+     Editor:   Tarek Saad
+               <mailto:tsaad@cisco.com>
+
+     Editor:   Rakesh Gandhi
+               <mailto:rgandhi@cisco.com>
+
+     Editor:   Vishnu Pavan Beeram
+               <mailto:vbeeram@juniper.net>
+
+     Editor:   Himanshu Shah
+               <mailto:hshah@ciena.com>
+
+     Editor:   Xufeng Liu
+               <mailto:xufeng.liu@ericsson.com>
+
+     Editor:   Xia Chen
+               <mailto:jescia.chenxia@huawei.com>
+
+     Editor:   Raqib Jones
+               <mailto:raqib@Brocade.com>
+
+     Editor:   Bin Wen
+               <mailto:Bin_Wen@cable.comcast.com>";
+
+  description
+    "YANG data module for TE configuration,
+    state, RPC and notifications.";
+
+  revision "2016-07-05" {
+    description "Latest update to TE generic YANG module.";
+    reference "TBD";
+  }
+
+  typedef tunnel-ref {
+    type leafref {
+      path "/te:te/te:tunnels/te:tunnel/te:name";
+    }
+    description
+      "This type is used by data models that need to reference
+       configured TE tunnel.";
+  }
+
+  /**
+   * TE tunnel generic groupings
+   */
+
+  grouping p2p-secondary-path-params {
+    description
+      "tunnel path properties.";
+    container config {
+      description
+        "Configuration parameters relating to
+        tunnel properties";
+      uses path-properties_config;
+      uses path-params_config;
+    }
+    container state {
+      config false;
+      description
+        "State information associated with tunnel
+        properties";
+      uses path-properties_config;
+      uses path-params_config;
+      uses p2p-secondary-path-params_state;
+    }
+  }
+
+  grouping p2p-primary-path-params {
+    description
+      "TE tunnel primary path properties grouping";
+    container config {
+      description
+        "Configuration parameters relating to
+        tunnel properties";
+      uses path-properties_config;
+      uses path-params_config;
+    }
+    container state {
+      config false;
+      description
+        "State information associated with tunnel
+        properties";
+      uses path-params_config;
+      uses p2p-primary-path-params_state;
+    }
+  }
+
+  grouping p2p-primary-path-params_state {
+    description "TE primary path state parameters";
+    list lsp {
+      key
+        "source destination tunnel-id lsp-id "+
+        "extended-tunnel-id type";
+      description "List of LSPs associated with the tunnel.";
+
+      leaf source {
+        type leafref {
+          path "../../../../../../lsps-state/lsp/source";
+        }
+        description
+          "Tunnel sender address extracted from
+          SENDER_TEMPLATE  object";
+        reference "RFC3209";
+      }
+      leaf destination {
+        type leafref {
+          path "../../../../../../lsps-state/lsp/destination";
+        }
+        description
+          "Tunnel endpoint address extracted from
+          SESSION object";
+        reference "RFC3209";
+      }
+      leaf tunnel-id {
+        type leafref {
+          path "../../../../../../lsps-state/lsp/tunnel-id";
+        }
+        description
+          "Tunnel identifier used in the SESSION
+          that remains constant over the life
+          of the tunnel.";
+        reference "RFC3209";
+      }
+      leaf lsp-id {
+        type leafref {
+          path "../../../../../../lsps-state/lsp/lsp-id";
+        }
+        description
+          "Identifier used in the SENDER_TEMPLATE
+          and the FILTER_SPEC that can be changed
+          to allow a sender to share resources with
+          itself.";
+        reference "RFC3209";
+      }
+      leaf extended-tunnel-id {
+        type leafref {
+          path "../../../../../../lsps-state/lsp/extended-tunnel-id";
+        }
+        description
+          "Extended Tunnel ID of the LSP.";
+        reference "RFC3209";
+      }
+      leaf type {
+        type leafref {
+          path "../../../../../../lsps-state/lsp/type";
+        }
+        description "LSP type P2P or P2MP";
+      }
+    }
+  }
+
+  grouping p2p-secondary-path-params_state {
+    description "TE secondary path state parameters";
+    list lsp {
+      key "source";
+      description "List of LSPs associated with the tunnel.";
+
+      leaf source {
+        type leafref {
+          path "../../../../../../../lsps-state/lsp/source";
+        }
+        description
+          "Tunnel sender address extracted from
+          SENDER_TEMPLATE  object";
+        reference "RFC3209";
+      }
+      leaf destination {
+        type leafref {
+          path "../../../../../../../lsps-state/lsp/destination";
+        }
+        description
+          "Tunnel endpoint address extracted from
+          SESSION object";
+        reference "RFC3209";
+      }
+      leaf tunnel-id {
+        type leafref {
+          path "../../../../../../../lsps-state/lsp/tunnel-id";
+        }
+        description
+          "Tunnel identifier used in the SESSION
+          that remains constant over the life
+          of the tunnel.";
+        reference "RFC3209";
+      }
+      leaf lsp-id {
+        type leafref {
+          path "../../../../../../../lsps-state/lsp/lsp-id";
+        }
+        description
+          "Identifier used in the SENDER_TEMPLATE
+          and the FILTER_SPEC that can be changed
+          to allow a sender to share resources with
+          itself.";
+        reference "RFC3209";
+      }
+      leaf extended-tunnel-id {
+        type leafref {
+          path "../../../../../../../lsps-state/lsp/extended-tunnel-id";
+        }
+        description
+          "Extended Tunnel ID of the LSP.";
+        reference "RFC3209";
+      }
+      leaf type {
+        type leafref {
+          path "../../../../../../../lsps-state/lsp/type";
+        }
+        description "LSP type P2P or P2MP";
+      }
+    }
+  }
+
+  grouping path-params_config {
+    description
+      "TE tunnel path parameters configuration grouping";
+    leaf path-named-constraint {
+      if-feature te-types:named-path-constraints;
+      type string;
+      description
+        "Reference to a globally defined named path
+        constraint set";
+    }
+    uses te-types:tunnel-path-selection;
+    choice type {
+      description
+        "Describes the path type";
+      case dynamic {
+        leaf dynamic {
+          type empty;
+          description
+            "A CSPF dynamically computed path";
+        }
+      }
+      case explicit {
+        leaf explicit-path-name {
+          type string;
+          description
+            "The explicit-path name";
+        }
+
+        list explicit-route-objects {
+          key "index";
+          description
+            "List of explicit route objects";
+          leaf index {
+            type uint8 {
+              range "0..255";
+            }
+            description
+              "Index of this explicit route object";
+          }
+          leaf explicit-route-usage {
+            type identityref {
+              base te-types:route-usage-type;
+            }
+            description "An explicit-route hop action.";
+          }
+          uses te-types:explicit-route-subobject;
+        }
+      }
+    }
+    leaf no-cspf {
+      type empty;
+      description
+        "Indicates no CSPF is to be attempted on this
+        path.";
+    }
+    leaf lockdown {
+      type empty;
+      description
+        "Indicates no reoptimization to be attempted for
+        this path.";
+    }
+  }
+
+  /* TE tunnel configuration data */
+  grouping tunnel-params_config {
+    description
+      "Configuration parameters relating to TE tunnel";
+    leaf name {
+      type string;
+      description "TE tunnel name.";
+    }
+    leaf type {
+      type identityref {
+        base te-types:tunnel-type;
+      }
+      description "TE tunnel type.";
+    }
+    leaf identifier {
+      type uint16;
+      description
+        "TE tunnel Identifier.";
+    }
+    leaf description {
+      type string;
+      description
+        "Textual description for this TE tunnel";
+    }
+    leaf lsp-priority-setup {
+      type uint8 {
+        range "0..7";
+      }
+      description
+        "TE LSP setup priority";
+    }
+    leaf lsp-priority-hold {
+      type uint8 {
+        range "0..7";
+      }
+      description
+        "TE LSP hold priority";
+    }
+    leaf lsp-protection-type {
+      type identityref {
+        base te-types:lsp-prot-type;
+      }
+      description "LSP protection type.";
+    }
+    leaf admin-status {
+      type identityref {
+        base te-types:state-type;
+      }
+      default te-types:state-up;
+      description "TE tunnel administrative state.";
+    }
+    leaf source {
+      type inet:ip-address;
+      description
+        "TE tunnel source address.";
+    }
+    leaf destination {
+      /* Add when check */
+      type inet:ip-address;
+      description
+        "P2P tunnel destination address";
+    }
+    leaf src-tp-id {
+      type binary;
+      description
+        "TE tunnel source termination point identifier.";
+    } 
+    leaf dst-tp-id {
+      /* Add when check */
+      type binary;
+      description
+        "TE tunnel destination termination point identifier.";
+    }
+    container hierarchical-link-id {
+        description
+          "Identifies a hierarchical link (in server layer)
+           that this tunnel is associated with.";
+        leaf local-te-node-id {
+          type te-types:te-node-id;
+          description
+            "Local TE node identifier";
+        }
+        leaf local-te-link-tp-id {
+          type te-types:te-tp-id;
+          description
+            "Local TE link termination point identifier";
+        }
+        leaf remote-te-node-id {
+          type te-types:te-node-id;
+          description
+            "Remote TE node identifier";
+        }
+        leaf te-topology-id {
+          type te-types:te-topology-id;
+          description
+            "It is presumed that a datastore will contain many
+             topologies. To distinguish between topologies it is
+             vital to have UNIQUE topology identifiers.";
+        }
+    }
+    uses te-types:tunnel-bidir-assoc-properties;
+  }
+
+  grouping tunnel-params_state {
+    description
+      "State parameters relating to TE tunnel";
+    leaf oper-status {
+      type identityref {
+        base te-types:state-type;
+      }
+      description "TE tunnel operational state.";
+    }
+  }
+
+  grouping path-properties_config {
+    description "TE path properties grouping";
+    leaf name {
+      type string;
+      description "TE path name";
+    }
+    leaf preference {
+      type uint8 {
+        range "1..255";
+      }
+      description
+        "Specifies a preference for this path. The lower the
+        number higher the preference";
+    }
+  }
+
+  /* TE tunnel configuration/state grouping */
+  grouping tunnel-properties {
+    description
+      "Top level grouping for tunnel properties.";
+    container config {
+      description
+        "Configuration parameters relating to
+         tunnel properties";
+      uses tunnel-params_config;
+    }
+    container state {
+      config false;
+      description
+        "State information associated with tunnel
+         properties";
+      uses tunnel-params_config;
+      uses tunnel-params_state;
+    }
+    list primary-paths {
+      key "name";
+      description
+        "List of primary paths for this tunnel.";
+      leaf name {
+        type leafref {
+          path "../config/name";
+        }
+        description "TE path name";
+      }
+      leaf preference {
+        type leafref {
+          path "../config/preference";
+        }
+        description
+          "Specifies a preference for this path. The lower the
+           number higher the preference";
+      }
+      uses p2p-primary-path-params;
+      list secondary-paths {
+        key "name";
+        description
+          "List of secondary paths for this tunnel.";
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description "TE path name";
+        }
+        leaf preference {
+          type leafref {
+            path "../config/preference";
+          }
+          description
+            "Specifies a preference for this path. The lower the
+            number higher the preference";
+        }
+        uses p2p-secondary-path-params;
+      }
+    }
+  }
+  /*** End of TE tunnel groupings ***/
+
+  /**
+   * LSP related generic groupings
+   */
+  grouping lsp-record-route-information_state {
+    description "recorded route information grouping";
+    container lsp-record-route {
+      description "RSVP recorded route object information";
+      list record-route-subobjects {
+        when "../origin-type != 'ingress'" {
+          description "Applicable on non-ingress LSPs only";
+        }
+        key "subobject-index";
+        description "";
+        leaf subobject-index {
+          type uint32;
+          description "RRO subobject index";
+        }
+        uses te-types:record-route-subobject;
+      }
+    }
+  }
+
+  grouping lsp-properties_state {
+    description
+      "State parameters relating to LSP";
+    leaf oper-status {
+      type identityref {
+        base te-types:state-type;
+      }
+      description "LSP operational state.";
+    }
+
+    leaf origin-type {
+      type enumeration {
+        enum ingress {
+          description
+            "Origin ingress";
+        }
+        enum egress {
+          description
+            "Origin egress";
+        }
+        enum transit {
+          description
+            "transit";
+        }
+      }
+      description
+        "Origin type of LSP relative to the location 
+        of the local switch in the path.";
+    }
+
+    leaf lsp-resource-status {
+      type enumeration {
+        enum primary {
+          description
+            "A primary LSP is a fully established LSP for
+             which the resource allocation has been committed
+             at the data plane";
+        }
+        enum secondary {
+          description
+            "A secondary LSP is an LSP that has been provisioned
+             in the control plane only; e.g. resource allocation
+             has not been committed at the data plane";
+        }
+      }
+      description "LSP resource allocation type";
+      reference "rfc4872, section 4.2.1";
+    }
+
+    leaf lsp-protection-role {
+      type enumeration {
+        enum working {
+          description
+            "A working LSP must be a primary LSP whilst a protecting
+             LSP can be either a primary or a secondary LSP. Also,
+             known as protected LSPs when working LSPs are associated
+             with protecting LSPs.";
+        }
+        enum protecting {
+          description
+            "A secondary LSP is an LSP that has been provisioned
+             in the control plane only; e.g. resource allocation
+             has not been committed at the data plane";
+        }
+      }
+      description "LSP role type";
+      reference "rfc4872, section 4.2.1";
+    }
+
+    leaf lsp-operational-status {
+      type empty;
+      description
+        "This bit is set when a protecting LSP is carrying the normal
+         traffic after protection switching";
+    }
+  }
+  /*** End of TE LSP groupings ***/
+
+  /**
+   * TE global generic groupings
+   */
+
+  /* Global named admin-groups configuration data */
+  grouping named-admin-groups_config {
+    description
+      "Global named administrative groups configuration
+      grouping";
+    list named-admin-groups {
+      if-feature te-types:extended-admin-groups;
+      if-feature te-types:named-extended-admin-groups;
+      key "name";
+      description
+        "List of named TE admin-groups";
+      leaf name {
+        type string;
+        description
+          "A string name that uniquely identifies a TE
+          interface named admin-group";
+      }
+      leaf bit-position {
+        type uint32;
+        description
+          "Bit position representing the administrative group";
+      }
+    }
+  }
+
+  /* Global named admin-srlgs configuration data */
+  grouping named-srlgs_config {
+    description
+      "Global named SRLGs configuration
+      grouping";
+    list named-srlgs {
+      if-feature te-types:named-srlg-groups;
+      key "name";
+      description
+        "A list of named SRLG groups";
+      leaf name {
+        type string;
+        description
+          "A string name that uniquely identifies a TE
+          interface named srlg";
+      }
+      leaf group {
+        type te-types:srlg;
+        description "An SRLG value";
+      }
+    }
+  }
+
+  /* Global named explicit-paths configuration data */
+  grouping named-explicit-paths_config {
+    description
+      "Global explicit path configuration
+      grouping";
+    list named-explicit-paths {
+      key "name";
+      description
+        "A list of explicit paths";
+      leaf name {
+        type string;
+        description
+          "A string name that uniquely identifies an
+          explicit path";
+      }
+      list explicit-route-objects {
+        key "index";
+        description
+          "List of explicit route objects";
+        leaf index {
+          type uint8 {
+            range "0..255";
+          }
+          description
+            "Index of this explicit route object";
+        }
+        leaf explicit-route-usage {
+          type identityref {
+            base te-types:route-usage-type;
+          }
+          description "An explicit-route hop action.";
+        }
+        uses te-types:explicit-route-subobject;
+      }
+    }
+  }
+
+  /* Global named paths constraints configuration data */
+  grouping named-path-constraints_config {
+    description
+      "Global named path constraints configuration
+      grouping";
+    list named-constraints {
+      if-feature te-types:named-path-constraints;
+      key "name";
+      description
+        "A list of named path constraints";
+      leaf name {
+        type string;
+        description
+          "A string name that uniquely identifies a
+          path constraint set";
+      }
+      uses te-types:tunnel-path-selection;
+    }
+  }
+
+  /* TE globals container data */
+  grouping globals-grouping {
+    description
+      "Globals TE system-wide configuration data grouping";
+    container globals {
+      description
+        "Globals TE system-wide configuration data container";
+      container config {
+        description
+          "Configuration parameters for system-wide
+           parameters";
+        uses named-admin-groups_config;
+        uses named-srlgs_config;
+        uses named-explicit-paths_config;
+        uses named-path-constraints_config;
+      }
+      container state {
+        config false;
+        description
+          "State for system-wide parameters";
+        uses named-admin-groups_config;
+        uses named-srlgs_config;
+        uses named-explicit-paths_config;
+        uses named-path-constraints_config;
+      }
+    }
+  }
+
+  /* TE tunnels container data */
+  grouping tunnels-grouping {
+    description
+      "Tunnels TE configuration data grouping";
+    container tunnels {
+      description
+        "Tunnels TE configuration data container";
+
+      list tunnel {
+        key "name type";
+        unique "identifier";
+        description "TE tunnel.";
+        leaf name {
+          type leafref {
+            path "../config/name";
+          }
+          description "TE tunnel name.";
+        }
+        leaf type {
+          type leafref {
+            path "../config/type";
+          }
+          description "TE tunnel type.";
+        }
+        leaf identifier {
+          type leafref {
+            path "../config/identifier";
+          }
+          description
+            "TE tunnel Identifier.";
+        }
+        uses tunnel-properties;
+      }
+    }
+  }
+
+  /* TE LSPs ephemeral state container data */
+  grouping lsps-state-grouping {
+    description
+      "LSPs state operational data grouping";
+    container lsps-state {
+      config "false";
+      description "LSPs operational state data.";
+
+      list lsp {
+        key
+          "source destination tunnel-id lsp-id "+
+          "extended-tunnel-id type";
+        description
+          "List of LSPs associated with the tunnel.";
+        leaf source {
+          type inet:ip-address;
+          description
+            "Tunnel sender address extracted from
+            SENDER_TEMPLATE  object";
+          reference "RFC3209";
+        }
+        leaf destination {
+          type inet:ip-address;
+          description
+            "Tunnel endpoint address extracted from
+            SESSION object";
+          reference "RFC3209";
+        }
+        leaf tunnel-id {
+          type uint16;
+          description
+            "Tunnel identifier used in the SESSION
+            that remains constant over the life
+            of the tunnel.";
+          reference "RFC3209";
+        }
+        leaf lsp-id {
+          type uint16;
+          description
+            "Identifier used in the SENDER_TEMPLATE
+            and the FILTER_SPEC that can be changed
+            to allow a sender to share resources with
+            itself.";
+          reference "RFC3209";
+        }
+        leaf extended-tunnel-id {
+          type inet:ip-address;
+           description
+            "Extended Tunnel ID of the LSP.";
+          reference "RFC3209";
+        }
+        leaf type {
+          type identityref {
+            base te-types:tunnel-type;
+          }
+          description "The LSP type P2P or P2MP";
+        }
+        uses lsp-properties_state;
+        uses lsp-record-route-information_state;
+      }
+    }
+  }
+  /*** End of TE global groupings ***/
+
+  /**
+   * TE configurations container
+   */
+  container te {
+    presence "Enable TE feature.";
+    description
+       "TE global container.";
+
+    /* TE Global Configuration Data */
+    uses globals-grouping;
+
+    /* TE Tunnel Configuration Data */
+    uses tunnels-grouping;
+
+    /* TE LSPs State Data */
+    uses lsps-state-grouping;
+  }
+
+  /* TE Global RPCs/execution Data */
+  rpc globals-rpc {
+    description
+      "Execution data for TE global.";
+  }
+
+  /* TE interfaces RPCs/execution Data */
+  rpc interfaces-rpc {
+    description
+      "Execution data for TE interfaces.";
+  }
+
+  /* TE Tunnel RPCs/execution Data */
+  rpc tunnels-rpc {
+    description
+      "TE tunnels RPC nodes";
+  }
+
+  /* TE Global Notification Data */
+  notification globals-notif {
+    description
+      "Notification messages for Global TE.";
+  }
+
+  /* TE Tunnel Notification Data */
+  notification tunnels-notif {
+    description
+      "Notification messages for TE tunnels.";
+  }
+}