Enhancement of tetopology implementation

To support regualar network and TE topology

Change-Id: Ib8319212d775c78f49a86a7b7685759099189967
diff --git a/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/DefaultBuilder.java b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/DefaultBuilder.java
new file mode 100644
index 0000000..564a938
--- /dev/null
+++ b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/DefaultBuilder.java
@@ -0,0 +1,330 @@
+/*
+ * 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.tetopology.management;
+
+import java.util.BitSet;
+import java.util.List;
+import java.util.Map;
+
+import org.onlab.packet.Ip4Address;
+import org.onosproject.net.DeviceId;
+import org.onosproject.tetopology.management.api.DefaultNetwork;
+import org.onosproject.tetopology.management.api.EncodingType;
+import org.onosproject.tetopology.management.api.KeyId;
+import org.onosproject.tetopology.management.api.Network;
+import org.onosproject.tetopology.management.api.SwitchingType;
+import org.onosproject.tetopology.management.api.TeConstants;
+import org.onosproject.tetopology.management.api.TeStatus;
+import org.onosproject.tetopology.management.api.TeTopologyId;
+import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetopology.management.api.link.CommonLinkData;
+import org.onosproject.tetopology.management.api.link.DefaultNetworkLink;
+import org.onosproject.tetopology.management.api.link.DefaultTeLink;
+import org.onosproject.tetopology.management.api.link.ExternalLink;
+import org.onosproject.tetopology.management.api.link.LinkBandwidth;
+import org.onosproject.tetopology.management.api.link.NetworkLink;
+import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
+import org.onosproject.tetopology.management.api.link.OduResource;
+import org.onosproject.tetopology.management.api.link.TeLink;
+import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
+import org.onosproject.tetopology.management.api.link.TeLinkTpKey;
+import org.onosproject.tetopology.management.api.link.TePathAttributes;
+import org.onosproject.tetopology.management.api.link.UnderlayPath;
+import org.onosproject.tetopology.management.api.node.CommonNodeData;
+import org.onosproject.tetopology.management.api.node.ConnectivityMatrix;
+import org.onosproject.tetopology.management.api.node.DefaultNetworkNode;
+import org.onosproject.tetopology.management.api.node.DefaultTeNode;
+import org.onosproject.tetopology.management.api.node.DefaultTerminationPoint;
+import org.onosproject.tetopology.management.api.node.DefaultTunnelTerminationPoint;
+import org.onosproject.tetopology.management.api.node.NetworkNode;
+import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
+import org.onosproject.tetopology.management.api.node.NodeTpKey;
+import org.onosproject.tetopology.management.api.node.TeNode;
+import org.onosproject.tetopology.management.api.node.TeNodeKey;
+import org.onosproject.tetopology.management.api.node.TerminationPoint;
+import org.onosproject.tetopology.management.api.node.TunnelTerminationPoint;
+import org.onosproject.tetopology.management.impl.TeMgrUtil;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Builds a sample abstract TE Topology, which consists of one node(represents
+ * an entire network), one inter-domain link and one TTP.
+ */
+public final class DefaultBuilder {
+    private static final String NODEIP = "100.10.10.10";
+    // Bandwidth in GigaBits/second
+    private static final float[] ODU0BW = {1.25f, 1.25f, 1.25f, 1.25f, 1.25f, 1.25f, 1.25f, 1.25f};
+    private static final float[] ODU2BW = {10, 10, 10, 10, 10, 10, 10, 10};
+    private static final float[] ODU3BW = {40, 40, 40, 40, 40, 40, 40, 40};
+    private static final float[] ODU4BW = {100, 100, 100, 100, 100, 100, 100, 100};
+
+    private static final String ODU2 = "ODU2";
+    private static final String ODU3 = "ODU3";
+    private static final String ODU4 = "ODU4";
+
+    private static final long PROVIDER_ID = 0x100;
+    private static final long CLIENT_ID = 0x0a0a0a0a;
+    private static final long CLIENT_NIL = 0;
+    private static final long ABSTRACT_TOPOLOGY_ID = 100;
+    private static final long NATIVE_TOPOLOGY_ID = 1;
+    private static final long NUM_TPS = 1;
+    private static final long NUM_TTPS = 1;
+    private static final boolean ABSTRACT = true;
+    private static final boolean UNABSTRACT = false;
+    private static final int FIRST_INDEX = 0;
+    private static final long INTER_DOMAIN_LINK_PLUGID = 100;
+    private static final long LINK_COST = 500;
+    private static final long LINK_DELAY = 2000;
+    private static final long LINK_SRLG = 150;
+    private static final String DOMAIN_ID = "DomainX";
+
+    private static NetworkNode networkNode;
+    private static TeNode teNode;
+    private static NetworkLink networkLink;
+    private static TeLink teLink;
+    private static Network network;
+    private static TunnelTerminationPoint ttp;
+
+    private static TeTopologyKey teTopologyKey = new TeTopologyKey(PROVIDER_ID,
+                                                                   CLIENT_ID,
+                                                                   ABSTRACT_TOPOLOGY_ID);
+
+    // no instantiation
+    private DefaultBuilder() {
+    }
+
+    private static TunnelTerminationPoint ttpBuilder(long ttpId) {
+        return new DefaultTunnelTerminationPoint(ttpId, SwitchingType.OTN_TDM_CAPABLE,
+                                                 EncodingType.LSP_ENCODING_ODUK,
+                                                 new BitSet(TeConstants.FLAG_MAX_BITS),
+                                                 null, null,
+                                                 ODU2BW); //10G for ODU2
+    }
+
+    private static TerminationPoint tpBuilder(long teTpId) {
+        return new DefaultTerminationPoint(KeyId.keyId(Long.toString(teTpId)), null, teTpId);
+    }
+
+    private static NetworkNode nodeBuilder(String nodeIp, long numTps, long numTtps,
+                                          TeTopologyKey underlayTopologyId, TeNodeKey supportTeNodeId,
+                                          TeNodeKey sourceTeNodeId, boolean isAbstract) {
+        long teNodeId = Ip4Address.valueOf(nodeIp).toInt();
+        BitSet flags = new BitSet(TeConstants.FLAG_MAX_BITS);
+
+        if (isAbstract) {
+            flags.set(TeNode.BIT_ABSTRACT);
+        }
+        CommonNodeData common = new CommonNodeData(nodeIp, TeStatus.UP, TeStatus.UP, flags);
+        Map<Long, ConnectivityMatrix> connMatrices = null;
+        List<Long> teTpIds = Lists.newArrayList();
+        Map<KeyId, TerminationPoint> tps = Maps.newHashMap();
+        for (long i = 0; i < numTps; i++) {
+            teTpIds.add(i);
+            tps.put(KeyId.keyId(Long.toString(i)), tpBuilder(i));
+        }
+        //TTP
+        Map<Long, TunnelTerminationPoint> ttps = Maps.newHashMap();
+        for (long i = 0; i < numTtps; i++) {
+            ttps.put(i, ttpBuilder(i));
+        }
+        ttp = ttps.get(FIRST_INDEX);
+        //TeNode
+        teNode = new DefaultTeNode(teNodeId, underlayTopologyId,
+                                   supportTeNodeId, sourceTeNodeId,
+                                          common, connMatrices, teTpIds, ttps, teTpIds);
+        List<NetworkNodeKey> supportingNodeIds = null;
+        if (supportTeNodeId != null) {
+            supportingNodeIds = Lists
+                    .newArrayList(TeMgrUtil.networkNodeKey(supportTeNodeId));
+        }
+
+        return new DefaultNetworkNode(KeyId.keyId(nodeIp), supportingNodeIds, teNode, tps);
+    }
+
+    private static LinkBandwidth linkBwBuilder(String odu) {
+
+        float[] maxBandwidth;  //Maximum bandwidth, Size is MAX_PRIORITY + 1
+        float[] avaiBandwidth; //Unreserved bandwidth, Size is MAX_PRIORITY + 1
+        float[] maxAvialLspBandwidth;  //Maximum available bandwidth for a LSP
+        float[] minAvialLspBandwidth;  //Minimum available bandwidth for a LSP
+        short odu0s;
+        short odu1s;
+        short odu2s;
+        short odu2es = 0;
+        short odu3s;
+        short odu4s;
+        short oduFlexes = 0;
+
+        switch (odu) {
+        case ODU3:
+            maxBandwidth = ODU3BW;
+            avaiBandwidth = ODU3BW;
+            maxAvialLspBandwidth = ODU3BW;
+            minAvialLspBandwidth = ODU0BW;
+            odu0s = 32;
+            odu1s = 16;
+            odu2s = 4;
+            odu3s = 1;
+            odu4s = 0;
+            break;
+        case ODU4:
+            maxBandwidth = ODU4BW;
+            avaiBandwidth = ODU4BW;
+            maxAvialLspBandwidth = ODU4BW;
+            minAvialLspBandwidth = ODU0BW;
+            odu0s = 80;
+            odu1s = 40;
+            odu2s = 10;
+            odu3s = 2;
+            odu4s = 1;
+            break;
+        default:
+            maxBandwidth = ODU2BW;
+            avaiBandwidth = ODU2BW;
+            maxAvialLspBandwidth = ODU2BW;
+            minAvialLspBandwidth = ODU0BW;
+            odu0s = 8;
+            odu1s = 4;
+            odu2s = 1;
+            odu3s = 0;
+            odu4s = 0;
+        }
+
+        OduResource oduRrc = new OduResource(odu0s, odu1s, odu2s, odu2es, odu3s,
+                                             odu4s, oduFlexes);
+        return new LinkBandwidth(maxBandwidth, avaiBandwidth, maxAvialLspBandwidth,
+                                 minAvialLspBandwidth, oduRrc);
+    }
+
+    private static NetworkLink linkBuilder(TeLinkTpKey teLinkKey, TeLinkTpKey peerTeLinkKey,
+                                          TeTopologyKey underlayTopologyId, TeLinkTpGlobalKey supportTeLinkId,
+                                          TeLinkTpGlobalKey sourceTeLinkId, boolean isAbstract, Long plugid,
+                                          Long cost, Long delay, List<Long> srlgs, String odu) {
+        //NetworkLink
+        KeyId linkId = TeMgrUtil.toNetworkLinkId(teLinkKey);
+        NodeTpKey source = new NodeTpKey(KeyId.keyId(Long.toString(teLinkKey.teNodeId())),
+                                         KeyId.keyId(Long.toString(teLinkKey.teLinkTpId())));
+        NodeTpKey destination = null;
+        if (peerTeLinkKey != null) {
+            destination = new NodeTpKey(KeyId.keyId(Long.toString(peerTeLinkKey.teNodeId())),
+                                        KeyId.keyId(Long.toString(peerTeLinkKey.teLinkTpId())));
+        }
+        List<NetworkLinkKey> supportingLinkIds = null;
+        if (supportTeLinkId != null) {
+            supportingLinkIds = Lists
+                    .newArrayList(TeMgrUtil.networkLinkKey(supportTeLinkId));
+        }
+        BitSet flags = new BitSet(TeConstants.FLAG_MAX_BITS);
+        if (isAbstract) {
+            flags.set(TeLink.BIT_ABSTRACT);
+        }
+        ExternalLink externalLink = null;
+
+        if (plugid != null) {
+            // Inter-Domain Link
+            flags.set(TeLink.BIT_ACCESS_INTERDOMAIN);
+            externalLink = new ExternalLink(null, plugid);
+        }
+        UnderlayPath underlayPath = null;
+        Long adminGroup = null;
+        List<Long> interLayerLocks = null;
+        teLink = new DefaultTeLink(teLinkKey, peerTeLinkKey, underlayTopologyId,
+                                          supportTeLinkId, sourceTeLinkId,
+                                          new CommonLinkData(TeStatus.UP, TeStatus.UP, flags,
+                                                             SwitchingType.OTN_TDM_CAPABLE,
+                                                             EncodingType.LSP_ENCODING_ODUK,
+                                                             externalLink, underlayPath,
+                                                             new TePathAttributes(cost, delay, srlgs),
+                                                             adminGroup, interLayerLocks, linkBwBuilder(odu)));
+        return new DefaultNetworkLink(linkId, source, destination, supportingLinkIds, teLink);
+    }
+
+    private static Network networkBuilder(TeTopologyId teTopologyId, KeyId supportingNetworkId,
+                                         Map<KeyId, NetworkNode> nodes, Map<KeyId, NetworkLink> links,
+                                         boolean serverProvided, DeviceId ownerId) {
+        KeyId networkId = TeMgrUtil.toNetworkId(teTopologyId);
+        List<KeyId> supportingNetworkIds = null;
+        if (supportingNetworkId != null) {
+            supportingNetworkIds = Lists.newArrayList(supportingNetworkId);
+        }
+        return new DefaultNetwork(networkId, supportingNetworkIds, nodes, links, teTopologyId,
+                              serverProvided, ownerId);
+    }
+
+    /**
+     * Returns the key for the sample TE Topology.
+     *
+     * @return value of TE Topology key
+     */
+    public static TeTopologyKey teTopologyKey() {
+        return teTopologyKey;
+    }
+
+    /**
+     * Returns the abstract TE Node in the sample TE Topology.
+     *
+     * @return value of TE node
+     */
+    public static TeNode teNode() {
+        return teNode;
+    }
+
+    /**
+     * Returns the TE link in the sample TE Topology.
+     *
+     * @return value of TE link
+     */
+    public static TeLink teLink() {
+        return teLink;
+    }
+
+    /**
+     * Builds a sample abstract TE Topology, which consists of one abstract node
+     * representing an entire physical network, one inter-domain link and one
+     * TTP.
+     *
+     * @return value of network with an abstract TE Topology
+     */
+    public static Network buildSampleAbstractNetwork() {
+        TeTopologyKey underlayTopologyId = new TeTopologyKey(PROVIDER_ID,
+                                                             CLIENT_NIL,
+                                                             NATIVE_TOPOLOGY_ID);
+        Map<KeyId, NetworkNode> nodes = Maps.newHashMap();
+        networkNode = nodeBuilder(NODEIP, NUM_TPS, NUM_TTPS, underlayTopologyId,
+                                  null, null, ABSTRACT);
+        nodes.put(networkNode.nodeId(), networkNode);
+
+        Map<KeyId, NetworkLink> links = Maps.newHashMap();
+        TeLinkTpKey node1tp1 = new TeLinkTpKey(networkNode.teNode().teNodeId(),
+                                               networkNode.teNode()
+                                                       .teTerminationPointIds()
+                                                       .get(FIRST_INDEX));
+        networkLink = linkBuilder(node1tp1, null, null, null, null, UNABSTRACT,
+                                  INTER_DOMAIN_LINK_PLUGID, LINK_COST,
+                                  LINK_DELAY, Lists.newArrayList(LINK_SRLG),
+                                  ODU4);
+        links.put(networkLink.linkId(), networkLink);
+        DeviceId ownerId = DeviceId.deviceId(DOMAIN_ID);
+        TeTopologyId topologyId = new TeTopologyId(PROVIDER_ID, CLIENT_ID, Long
+                .toString(ABSTRACT_TOPOLOGY_ID));
+        network = networkBuilder(topologyId, null, nodes, links, false,
+                                 ownerId);
+        return network;
+    }
+
+}
diff --git a/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/SimpleTeTopologyStore.java b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/SimpleTeTopologyStore.java
new file mode 100644
index 0000000..3abaddc
--- /dev/null
+++ b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/SimpleTeTopologyStore.java
@@ -0,0 +1,1033 @@
+/**
+ * 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.tetopology.management;
+
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_REMOVED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_REMOVED;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.BitSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+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.Service;
+import org.onosproject.net.DeviceId;
+import org.onosproject.store.AbstractStore;
+import org.onosproject.tetopology.management.api.CommonTopologyData;
+import org.onosproject.tetopology.management.api.DefaultNetwork;
+import org.onosproject.tetopology.management.api.DefaultTeTopologies;
+import org.onosproject.tetopology.management.api.DefaultTeTopology;
+import org.onosproject.tetopology.management.api.KeyId;
+import org.onosproject.tetopology.management.api.Network;
+import org.onosproject.tetopology.management.api.OptimizationType;
+import org.onosproject.tetopology.management.api.TeConstants;
+import org.onosproject.tetopology.management.api.TeTopologies;
+import org.onosproject.tetopology.management.api.TeTopology;
+import org.onosproject.tetopology.management.api.TeTopologyEvent;
+import org.onosproject.tetopology.management.api.TeTopologyId;
+import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetopology.management.api.TeUtils;
+import org.onosproject.tetopology.management.api.link.DefaultNetworkLink;
+import org.onosproject.tetopology.management.api.link.DefaultTeLink;
+import org.onosproject.tetopology.management.api.link.NetworkLink;
+import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
+import org.onosproject.tetopology.management.api.link.TeLink;
+import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
+import org.onosproject.tetopology.management.api.link.TeLinkTpKey;
+import org.onosproject.tetopology.management.api.node.ConnectivityMatrix;
+import org.onosproject.tetopology.management.api.node.ConnectivityMatrixKey;
+import org.onosproject.tetopology.management.api.node.DefaultNetworkNode;
+import org.onosproject.tetopology.management.api.node.DefaultTeNode;
+import org.onosproject.tetopology.management.api.node.DefaultTerminationPoint;
+import org.onosproject.tetopology.management.api.node.NetworkNode;
+import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
+import org.onosproject.tetopology.management.api.node.NodeTpKey;
+import org.onosproject.tetopology.management.api.node.TeNode;
+import org.onosproject.tetopology.management.api.node.TeNodeKey;
+import org.onosproject.tetopology.management.api.node.TerminationPoint;
+import org.onosproject.tetopology.management.api.node.TerminationPointKey;
+import org.onosproject.tetopology.management.api.node.TtpKey;
+import org.onosproject.tetopology.management.api.node.TunnelTerminationPoint;
+import org.onosproject.tetopology.management.impl.InternalNetwork;
+import org.onosproject.tetopology.management.impl.InternalNetworkLink;
+import org.onosproject.tetopology.management.impl.InternalNetworkNode;
+import org.onosproject.tetopology.management.impl.InternalTeLink;
+import org.onosproject.tetopology.management.impl.InternalTeNode;
+import org.onosproject.tetopology.management.impl.InternalTeTopology;
+import org.onosproject.tetopology.management.impl.InternalTerminationPoint;
+import org.onosproject.tetopology.management.impl.TeMgrUtil;
+import org.onosproject.tetopology.management.impl.TeTopologyManager;
+import org.onosproject.tetopology.management.impl.TeTopologyMapEvent;
+import org.onosproject.tetopology.management.impl.TeTopologyStore;
+import org.onosproject.tetopology.management.impl.TeTopologyStoreDelegate;
+import org.slf4j.Logger;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Implementation of the TE network store.
+ */
+@Component(immediate = true)
+@Service
+public class SimpleTeTopologyStore
+        extends AbstractStore<TeTopologyEvent, TeTopologyStoreDelegate>
+        implements TeTopologyStore {
+    private static final String STORE_NAME = "TE_NETWORK_TOPOLOGY_STORE";
+    private final Logger log = getLogger(getClass());
+
+    // Track TE topologies by TE Topology key
+    private Map<TeTopologyKey, InternalTeTopology> teTopologyMap = Maps
+            .newConcurrentMap();
+    // Track networks by network Id
+    private Map<KeyId, InternalNetwork> networkMap = Maps.newConcurrentMap();
+    // Track TE nodes by TE node key
+    private Map<TeNodeKey, InternalTeNode> teNodeMap = Maps.newConcurrentMap();
+    // Track ConnectivityMatrix by its key
+    private Map<ConnectivityMatrixKey, ConnectivityMatrix> connMatrixMap = Maps
+            .newConcurrentMap();
+    // Track Tunnel Termination Points by its key
+    private Map<TtpKey, TunnelTerminationPoint> ttpMap = Maps
+            .newConcurrentMap();
+    // Track network nodes by network node key
+    private Map<NetworkNodeKey, InternalNetworkNode> networkNodeMap = Maps
+            .newConcurrentMap();
+    // Track TE links by its key
+    private Map<TeLinkTpGlobalKey, InternalTeLink> teLinkMap = Maps
+            .newConcurrentMap();
+    // Track network links by network link key
+    private Map<NetworkLinkKey, InternalNetworkLink> networkLinkMap = Maps
+            .newConcurrentMap();
+    // Track Termination points by termination point key
+    private Map<TerminationPointKey, InternalTerminationPoint> tpMap = Maps
+            .newConcurrentMap();
+    // Track termination point keys by TE termination point Key
+    private Map<TeLinkTpGlobalKey, TerminationPointKey> tpKeyMap = Maps
+            .newConcurrentMap();
+
+    @Activate
+    public void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        teTopologyMap.clear();
+        networkMap.clear();
+        teNodeMap.clear();
+        connMatrixMap.clear();
+        networkNodeMap.clear();
+        teLinkMap.clear();
+        networkLinkMap.clear();
+        tpMap.clear();
+        tpKeyMap.clear();
+        ttpMap.clear();
+        log.info("Stopped");
+    }
+
+    @Override
+    public TeTopologies teTopologies() {
+        Map<TeTopologyKey, TeTopology> teTopologies = Maps.newHashMap();
+        if (MapUtils.isNotEmpty(teTopologyMap)) {
+            for (TeTopologyKey key : teTopologyMap.keySet()) {
+                teTopologies.put(key, teTopology(key));
+            }
+        }
+        return new DefaultTeTopologies(STORE_NAME, teTopologies);
+    }
+
+    private TeTopology teTopology(TeTopologyKey topologyId,
+                                  InternalTeTopology intTopology) {
+        if (intTopology == null) {
+            return null;
+        }
+        Map<Long, TeNode> teNodes = null;
+        if (CollectionUtils.isNotEmpty(intTopology.teNodeKeys())) {
+            teNodes = Maps.newHashMap();
+            for (TeNodeKey key : intTopology.teNodeKeys()) {
+                teNodes.put(key.teNodeId(), teNode(key));
+            }
+        }
+        Map<TeLinkTpKey, TeLink> teLinks = null;
+        if (CollectionUtils.isNotEmpty(intTopology.teLinkKeys())) {
+            teLinks = Maps.newHashMap();
+            for (TeLinkTpGlobalKey key : intTopology.teLinkKeys()) {
+                teLinks.put(key.teLinkTpKey(), teLink(key));
+            }
+        }
+        return new DefaultTeTopology(topologyId, teNodes, teLinks,
+                                     intTopology.teTopologyId(),
+                                     intTopology.topologyData());
+    }
+
+    @Override
+    public TeTopology teTopology(TeTopologyKey topologyId) {
+        InternalTeTopology intTopology = teTopologyMap.get(topologyId);
+        return teTopology(topologyId, intTopology);
+    }
+
+    private void removeTopologyeMapEntrys(InternalTeTopology curTopology) {
+        // Remove TE nodes
+        if (CollectionUtils.isNotEmpty(curTopology.teNodeKeys())) {
+            for (TeNodeKey key : curTopology.teNodeKeys()) {
+                removeTeNode(key, true);
+            }
+        }
+        // Remove TE Links
+        if (CollectionUtils.isNotEmpty(curTopology.teLinkKeys())) {
+            for (TeLinkTpGlobalKey key : curTopology.teLinkKeys()) {
+                removeTeLink(key, true);
+            }
+        }
+    }
+
+    @Override
+    public void updateTeTopology(TeTopology teTopology) {
+        InternalTeTopology curTopology = teTopologyMap
+                .get(teTopology.teTopologyId());
+        if (curTopology != null) {
+            // Existing topology update
+            // Remove existing map entries first, which should be removed by
+            // its own events
+            removeTopologyeMapEntrys(curTopology);
+        }
+        // Update TE nodes
+        List<NetworkNodeKey> nodeIds = null;
+        if (MapUtils.isNotEmpty(teTopology.teNodes())) {
+            nodeIds = Lists.newArrayList();
+            for (Map.Entry<Long, TeNode> entry : teTopology.teNodes()
+                    .entrySet()) {
+                TeNodeKey teNodeKey = new TeNodeKey(teTopology.teTopologyId(),
+                                                    entry.getKey());
+                NetworkNodeKey nodeKey = TeMgrUtil.networkNodeKey(teNodeKey);
+                updateTeNode(teNodeKey, entry.getValue(), true, true, nodeKey);
+                nodeIds.add(nodeKey);
+            }
+        }
+        // Update TE links
+        List<NetworkLinkKey> linkIds = null;
+        if (MapUtils.isNotEmpty(teTopology.teLinks())) {
+            linkIds = Lists.newArrayList();
+            for (Map.Entry<TeLinkTpKey, TeLink> entry : teTopology.teLinks()
+                    .entrySet()) {
+                TeLinkTpGlobalKey teLinkKey = new TeLinkTpGlobalKey(teTopology
+                        .teTopologyId(), entry.getKey());
+                NetworkLinkKey linkKey = TeMgrUtil.networkLinkKey(teLinkKey);
+                updateTeLink(teLinkKey, entry.getValue(), true, true, linkKey);
+                linkIds.add(linkKey);
+            }
+        }
+        // Finally Update teTopologyMap
+        InternalTeTopology newTopology = new InternalTeTopology(teTopology);
+        teTopologyMap.put(teTopology.teTopologyId(), newTopology);
+
+        if (curTopology == null) {
+            // New topology, update networkMap
+            InternalNetwork intNetwork = new InternalNetwork();
+            intNetwork.setServerProvided(false);
+            intNetwork.setTeTopologyKey(teTopology.teTopologyId());
+            intNetwork.setNodeIds(nodeIds);
+            intNetwork.setLinkIds(linkIds);
+            networkMap.put(teTopology.networkId(), intNetwork);
+        }
+    }
+
+    @Override
+    public void removeTeTopology(TeTopologyKey topologyId) {
+        // Remove it from teTopologyMap
+        InternalTeTopology topology = teTopologyMap.remove(topologyId);
+        if (topology != null) {
+            removeTopologyeMapEntrys(topology);
+            // Remove it from networkMap;
+            networkMap.remove(topology.topologyData().networkId());
+        }
+    }
+
+    @Override
+    public List<Network> networks() {
+        if (MapUtils.isEmpty(networkMap)) {
+            return null;
+        }
+        List<Network> networks = Lists.newArrayList();
+        for (KeyId networkId : networkMap.keySet()) {
+            networks.add(network(networkId));
+        }
+        return networks;
+    }
+
+    private Network network(KeyId networkId, InternalNetwork curNetwork) {
+        if (curNetwork == null) {
+            return null;
+        }
+        List<KeyId> supportingNetworkIds = curNetwork.supportingNetworkIds();
+        Map<KeyId, NetworkNode> nodes = null;
+        if (CollectionUtils.isNotEmpty(curNetwork.nodeIds())) {
+            nodes = Maps.newHashMap();
+            for (NetworkNodeKey key : curNetwork.nodeIds()) {
+                nodes.put(key.nodeId(), networkNode(key));
+            }
+        }
+        Map<KeyId, NetworkLink> links = null;
+        if (CollectionUtils.isNotEmpty(curNetwork.linkIds())) {
+            links = Maps.newHashMap();
+            for (NetworkLinkKey key : curNetwork.linkIds()) {
+                links.put(key.linkId(), networkLink(key));
+            }
+        }
+        TeTopologyId topologyId = null;
+        DeviceId ownerId = null;
+        if (curNetwork.teTopologyKey() != null
+                && teTopology(curNetwork.teTopologyKey()) != null) {
+            topologyId = new TeTopologyId(curNetwork.teTopologyKey()
+                    .providerId(), curNetwork.teTopologyKey().clientId(),
+                                          teTopology(curNetwork.teTopologyKey())
+                                                  .teTopologyIdStringValue());
+            ownerId = teTopology(curNetwork.teTopologyKey()).ownerId();
+
+        }
+        return new DefaultNetwork(networkId, supportingNetworkIds, nodes, links,
+                                  topologyId, curNetwork.serverProvided(),
+                                  ownerId);
+    }
+
+    @Override
+    public Network network(KeyId networkId) {
+        InternalNetwork curNetwork = networkMap.get(networkId);
+        return network(networkId, curNetwork);
+    }
+
+    private void removeNetworkMapEntrys(InternalNetwork curNetwork,
+                                        boolean teRemove) {
+        // Remove TE nodes
+        if (CollectionUtils.isNotEmpty(curNetwork.nodeIds())) {
+            for (NetworkNodeKey key : curNetwork.nodeIds()) {
+                removeNetworkNode(key, teRemove);
+            }
+        }
+        // Remove TE Links
+        if (CollectionUtils.isNotEmpty(curNetwork.linkIds())) {
+            for (NetworkLinkKey key : curNetwork.linkIds()) {
+                removeNetworkLink(key, teRemove);
+            }
+        }
+    }
+
+    private TeTopologyKey newTeTopologyKey(TeTopologyId teTopologyId) {
+        long idValue;
+        try {
+            idValue = Long.parseLong(teTopologyId.topologyId());
+        } catch (NumberFormatException e) {
+            // Can't get the long value from the string.
+            // Use an assigned id value from local id pool,
+            // Ideally id should be assigned per provider base.
+            idValue = nextTeTopologyId();
+        }
+        return new TeTopologyKey(teTopologyId.providerId(),
+                                 teTopologyId.clientId(), idValue);
+    }
+
+    @Override
+    public void updateNetwork(Network network) {
+        InternalNetwork curNetwork = networkMap.get(network.networkId());
+        if (curNetwork != null) {
+            // Existing topology update
+            // Remove existing map entries first,
+            removeNetworkMapEntrys(curNetwork, false);
+        }
+        TeTopologyKey topoKey = null;
+        if (network.teTopologyId() != null) {
+            topoKey = newTeTopologyKey(network.teTopologyId());
+        }
+        // Update TE nodes
+        List<TeNodeKey> teNodeKeys = null;
+        if (MapUtils.isNotEmpty(network.nodes())) {
+            teNodeKeys = Lists.newArrayList();
+            for (Map.Entry<KeyId, NetworkNode> entry : network.nodes()
+                    .entrySet()) {
+                NetworkNodeKey nodeKey = new NetworkNodeKey(network.networkId(),
+                                                            entry.getKey());
+                TeNodeKey teNodeKey = null;
+                if (topoKey != null && entry.getValue().teNode() != null) {
+                    teNodeKey = new TeNodeKey(topoKey, entry.getValue().teNode()
+                            .teNodeId());
+                }
+                updateNetworkNode(nodeKey, entry.getValue(), true, false,
+                                  teNodeKey);
+                teNodeKeys.add(teNodeKey);
+            }
+        }
+        // Update TE links
+        List<TeLinkTpGlobalKey> teLinkKeys = null;
+        if (MapUtils.isNotEmpty(network.links())) {
+            teLinkKeys = Lists.newArrayList();
+            for (Map.Entry<KeyId, NetworkLink> entry : network.links()
+                    .entrySet()) {
+                NetworkLinkKey linkKey = new NetworkLinkKey(network.networkId(),
+                                                            entry.getKey());
+                TeLinkTpGlobalKey teLinkKey = null;
+                if (topoKey != null && entry.getValue().teLink() != null) {
+                    teLinkKey = new TeLinkTpGlobalKey(topoKey, entry.getValue()
+                            .teLink().teLinkKey());
+                }
+                updateNetworkLink(linkKey, entry.getValue(), true, false,
+                                  teLinkKey);
+                teLinkKeys.add(teLinkKey);
+            }
+        }
+
+        // New network, update TE Topology first
+        if (curNetwork == null) {
+            InternalTeTopology intTopo = new InternalTeTopology(network
+                    .teTopologyId().topologyId());
+            intTopo.setTeNodeKeys(teNodeKeys);
+            intTopo.setTeLinkKeys(teLinkKeys);
+            BitSet flags = new BitSet(TeConstants.FLAG_MAX_BITS);
+            flags.set(TeTopology.BIT_LEARNT);
+            if (network.teTopologyId()
+                    .clientId() == TeTopologyManager.DEFAULT_PROVIDER_ID) {
+                // Hard rule for now
+                flags.set(TeTopology.BIT_CUSTOMIZED);
+            }
+            CommonTopologyData common = new CommonTopologyData(network
+                    .networkId(), OptimizationType.NOT_OPTIMIZED, flags, network
+                            .ownerId());
+            intTopo.setTopologydata(common);
+            teTopologyMap.put(topoKey, intTopo);
+            // Assume new topology
+            TeTopologyEvent topologyEvent = new TeTopologyEvent(TE_TOPOLOGY_ADDED,
+                                                                teTopology(topoKey));
+            notifyDelegate(topologyEvent);
+        }
+        // Finally Update networkMap
+        InternalNetwork newNetwork = new InternalNetwork(network);
+        newNetwork.setTeTopologyKey(topoKey);
+        networkMap.put(network.networkId(), newNetwork);
+        // Assume new network
+        TeTopologyEvent topologyEvent = new TeTopologyEvent(NETWORK_ADDED,
+                                                            network(network
+                                                                    .networkId()));
+        notifyDelegate(topologyEvent);
+    }
+
+    @Override
+    public void removeNetwork(KeyId networkId) {
+        // Remove it from networkMap
+        InternalNetwork network = networkMap.remove(networkId);
+        TeTopologyEvent topologyEvent = new TeTopologyEvent(NETWORK_REMOVED,
+                                                            new DefaultNetwork(networkId,
+                                                                               null,
+                                                                               null,
+                                                                               null,
+                                                                               null,
+                                                                               false,
+                                                                               null));
+        notifyDelegate(topologyEvent);
+        if (network != null && network.teTopologyKey() != null) {
+            removeNetworkMapEntrys(network, false);
+            teTopologyMap.remove(network.teTopologyKey());
+            topologyEvent = new TeTopologyEvent(TE_TOPOLOGY_REMOVED,
+                                                new DefaultTeTopology(network
+                                                        .teTopologyKey(), null, null, null, null));
+            notifyDelegate(topologyEvent);
+        }
+    }
+
+    private TeNode teNode(TeNodeKey nodeKey, InternalTeNode intNode) {
+        if (intNode == null) {
+            return null;
+        }
+        Map<Long, ConnectivityMatrix> connMatrices = null;
+        if (CollectionUtils.isNotEmpty(intNode.connMatrixKeys())) {
+            connMatrices = Maps.newHashMap();
+            for (ConnectivityMatrixKey key : intNode.connMatrixKeys()) {
+                connMatrices.put(key.entryId(), connMatrixMap.get(key));
+            }
+        }
+        List<Long> teLinkIds = null;
+        if (CollectionUtils.isNotEmpty(intNode.teLinkTpKeys())) {
+            teLinkIds = Lists.newArrayList();
+            for (TeLinkTpGlobalKey key : intNode.teLinkTpKeys()) {
+                teLinkIds = TeUtils.addListElement(teLinkIds, key.teLinkTpId());
+            }
+        }
+        List<Long> tps = null;
+        if (CollectionUtils.isNotEmpty(intNode.teTpKeys())) {
+            tps = Lists.newArrayList();
+            for (TeLinkTpGlobalKey key : intNode.teTpKeys()) {
+                tps = TeUtils.addListElement(tps, key.teLinkTpId());
+            }
+        }
+        Map<Long, TunnelTerminationPoint> ttps = null;
+        if (CollectionUtils.isNotEmpty(intNode.ttpKeys())) {
+            ttps = Maps.newHashMap();
+            for (TtpKey key : intNode.ttpKeys()) {
+                ttps.put(key.ttpId(), ttpMap.get(key));
+            }
+        }
+        return new DefaultTeNode(nodeKey.teNodeId(),
+                                 intNode.underlayTopologyKey(),
+                                 intNode.supportNodeKey(),
+                                 intNode.sourceTeNodeKey(), intNode.teData(),
+                                 connMatrices, teLinkIds, ttps, tps);
+    }
+
+    @Override
+    public TeNode teNode(TeNodeKey nodeKey) {
+        InternalTeNode intNode = teNodeMap.get(nodeKey);
+        return teNode(nodeKey, intNode);
+    }
+
+    private void removeTeNodeMapEntrys(InternalTeNode intNode) {
+        // Remove connMatrixMap entries for the node
+        if (CollectionUtils.isNotEmpty(intNode.connMatrixKeys())) {
+            for (ConnectivityMatrixKey key : intNode.connMatrixKeys()) {
+                connMatrixMap.remove(key);
+            }
+        }
+        // Remove ttpMap entries for the node
+        if (CollectionUtils.isNotEmpty(intNode.ttpKeys())) {
+            for (TtpKey key : intNode.ttpKeys()) {
+                ttpMap.remove(key);
+            }
+        }
+    }
+
+    private void updateTeNode(TeNodeKey nodeKey, TeNode node,
+                              boolean parentUpdate, boolean teNodeUpdate,
+                              NetworkNodeKey networkNodeKey) {
+        InternalTeTopology intTopo = teTopologyMap.get(nodeKey.teTopologyKey());
+        if (intTopo == null && !parentUpdate) {
+            log.error("TE Topology is not in dataStore for nodeUpdate {}",
+                      nodeKey);
+            return;
+        }
+        InternalTeNode curNode = teNodeMap.get(nodeKey);
+        // Update connMatrixMap
+        if (MapUtils.isNotEmpty(node.connectivityMatrices())) {
+            for (Map.Entry<Long, ConnectivityMatrix> entry : node
+                    .connectivityMatrices().entrySet()) {
+                connMatrixMap
+                        .put(new ConnectivityMatrixKey(nodeKey, entry.getKey()),
+                             entry.getValue());
+            }
+        }
+        // Update ttpMap
+        if (MapUtils.isNotEmpty(node.tunnelTerminationPoints())) {
+            for (Map.Entry<Long, TunnelTerminationPoint> entry : node
+                    .tunnelTerminationPoints().entrySet()) {
+                ttpMap.put(new TtpKey(nodeKey, entry.getKey()),
+                           entry.getValue());
+            }
+        }
+        // Update TE Termination Points
+
+        // Update teNodeMap
+        InternalTeNode intNode = new InternalTeNode(nodeKey, node,
+                                                    networkNodeKey,
+                                                    parentUpdate);
+        teNodeMap.put(nodeKey, intNode);
+        if (curNode == null && !parentUpdate && intTopo != null) {
+            // Update InternalTeTopology
+            intTopo.setChildUpdate(true);
+            TeUtils.addListElement(intTopo.teNodeKeys(), nodeKey);
+        }
+        // Update networkNodeMap
+        if (teNodeUpdate) {
+            updateNetworkNode(networkNodeKey, networkNode(node), parentUpdate,
+                              teNodeUpdate, nodeKey);
+        }
+    }
+
+    private NetworkNode networkNode(TeNode node) {
+        KeyId nodeId = KeyId.keyId(Long.toString(node.teNodeId()));
+        List<NetworkNodeKey> supportingNodeIds = null;
+        if (node.supportingTeNodeId() != null) {
+            supportingNodeIds = Lists.newArrayList();
+            supportingNodeIds.add(new NetworkNodeKey(TeMgrUtil.toNetworkId((node
+                    .supportingTeNodeId().teTopologyKey())), KeyId.keyId(Long
+                            .toString(node.supportingTeNodeId().teNodeId()))));
+        }
+        Map<KeyId, TerminationPoint> tps = null;
+        if (node.teTerminationPointIds() != null) {
+            tps = Maps.newHashMap();
+            for (Long teTpId : node.teTerminationPointIds()) {
+                tps.put(KeyId.keyId(Long.toString(teTpId)),
+                        new DefaultTerminationPoint(KeyId
+                                .keyId(Long.toString(teTpId)), null, teTpId));
+            }
+        }
+        return new DefaultNetworkNode(nodeId, supportingNodeIds, node, tps);
+    }
+
+    @Override
+    public void updateTeNode(TeNodeKey nodeKey, TeNode node) {
+        updateTeNode(nodeKey, node, false, true,
+                     TeMgrUtil.networkNodeKey(nodeKey));
+    }
+
+    private void removeTeNode(TeNodeKey nodeKey, boolean teNodeRemove) {
+        // Remove it from InternalTeTopology first
+        InternalTeTopology intTopo = teTopologyMap.get(nodeKey.teTopologyKey());
+        if (intTopo != null
+                && CollectionUtils.isNotEmpty(intTopo.teNodeKeys())) {
+            intTopo.setChildUpdate(true);
+            intTopo.teNodeKeys().remove(nodeKey);
+        }
+        // Then remove it from teNodeMap
+        InternalTeNode node = teNodeMap.remove(nodeKey);
+        removeTeNodeMapEntrys(node);
+        // Remove it from networkNodeMap
+        if (teNodeRemove && node != null) {
+            removeNetworkNode(node.networkNodeKey(), teNodeRemove);
+        }
+    }
+
+    @Override
+    public void removeTeNode(TeNodeKey nodeKey) {
+        removeTeNode(nodeKey, true);
+    }
+
+    private NetworkNode networkNode(NetworkNodeKey nodeKey,
+                                    InternalNetworkNode intNode) {
+        if (intNode == null) {
+            return null;
+        }
+        Map<KeyId, TerminationPoint> tps = Maps.newHashMap();
+        for (KeyId tpId : intNode.tpIds()) {
+            tps.put(tpId,
+                    terminationPoint(new TerminationPointKey(nodeKey, tpId)));
+
+        }
+        return new DefaultNetworkNode(nodeKey.nodeId(),
+                                      intNode.supportingNodeIds(),
+                                      teNode(intNode.teNodeKey()), tps);
+    }
+
+    @Override
+    public NetworkNode networkNode(NetworkNodeKey nodeKey) {
+        InternalNetworkNode intNode = networkNodeMap.get(nodeKey);
+        return networkNode(nodeKey, intNode);
+    }
+
+    private void updateNetworkNode(NetworkNodeKey nodeKey, NetworkNode node,
+                                   boolean parentUpdate, boolean teNodeUpdate,
+                                   TeNodeKey teNodeKey) {
+        InternalNetwork intNework = null;
+        if (!parentUpdate) {
+            intNework = networkMap.get(nodeKey.networkId());
+            if (intNework == null) {
+                log.error("Network is not in dataStore for nodeUpdate {}",
+                          nodeKey);
+                return;
+            }
+        }
+
+        InternalNetworkNode exNode = networkNodeMap.get(nodeKey);
+        if (exNode != null && CollectionUtils.isNotEmpty(exNode.tpIds())) {
+            // Remove the TerminationPoints first
+            for (KeyId tpId : exNode.tpIds()) {
+                removeTerminationPoint(new TerminationPointKey(nodeKey, tpId));
+            }
+        }
+
+        if (MapUtils.isNotEmpty(node.terminationPoints())) {
+            // Update with new TerminationPoints
+            for (Map.Entry<KeyId, TerminationPoint> entry : node
+                    .terminationPoints().entrySet()) {
+                updateTerminationPoint(new TerminationPointKey(nodeKey,
+                                                               entry.getKey()),
+                                       entry.getValue(), parentUpdate,
+                                       teNodeKey);
+            }
+        }
+
+        // Update teNodeMap first
+        if (!teNodeUpdate && teNodeKey != null && node.teNode() != null) {
+            updateTeNode(teNodeKey, node.teNode(), parentUpdate, teNodeUpdate,
+                         nodeKey);
+        }
+        // Update networkNodeMap
+        InternalNetworkNode intNode = new InternalNetworkNode(node,
+                                                              parentUpdate);
+        intNode.setTeNodeKey(teNodeKey);
+        networkNodeMap.put(nodeKey, intNode);
+        if (exNode == null && !parentUpdate && intNework != null) {
+            // Update the InternalNetwork
+            intNework.setChildUpdate(true);
+            TeUtils.addListElement(intNework.nodeIds(), nodeKey);
+        }
+    }
+
+    @Override
+    public void updateNetworkNode(NetworkNodeKey nodeKey, NetworkNode node) {
+        TeNodeKey teNodeKey = null;
+        if (node.teNode() != null) {
+            teNodeKey = new TeNodeKey(networkMap.get(nodeKey.networkId())
+                    .teTopologyKey(), node.teNode().teNodeId());
+        }
+        updateNetworkNode(nodeKey, node, false, false, teNodeKey);
+    }
+
+    private void removeNetworkNode(NetworkNodeKey nodeKey,
+                                   boolean teNodeRemove) {
+        // Update the InternalNetwork
+        InternalNetwork intNework = networkMap.get(nodeKey.networkId());
+        if (intNework != null
+                && CollectionUtils.isNotEmpty(intNework.nodeIds())) {
+            intNework.setChildUpdate(true);
+            intNework.nodeIds().remove(nodeKey.nodeId());
+        }
+        InternalNetworkNode intNode = networkNodeMap.remove(nodeKey);
+        if (intNode != null && CollectionUtils.isNotEmpty(intNode.tpIds())) {
+            // Remove the TerminationPoints first
+            for (KeyId tpId : intNode.tpIds()) {
+                removeTerminationPoint(new TerminationPointKey(nodeKey, tpId));
+            }
+        }
+        if (!teNodeRemove && intNode != null) {
+            // Now remove it from teNodeMap
+            removeTeNode(intNode.teNodeKey(), teNodeRemove);
+        }
+    }
+
+    @Override
+    public void removeNetworkNode(NetworkNodeKey nodeKey) {
+        removeNetworkNode(nodeKey, false);
+    }
+
+    private TeLink teLink(TeLinkTpGlobalKey linkKey, InternalTeLink intLink) {
+        if (intLink == null) {
+            return null;
+        }
+        return new DefaultTeLink(linkKey.teLinkTpKey(), intLink.peerTeLinkKey(),
+                                 intLink.underlayTopologyKey(),
+                                 intLink.supportingLinkKey(),
+                                 intLink.sourceTeLinkKey(), intLink.teData());
+    }
+
+    @Override
+    public TeLink teLink(TeLinkTpGlobalKey linkKey) {
+        InternalTeLink intLink = teLinkMap.get(linkKey);
+        return teLink(linkKey, intLink);
+    }
+
+    private void updateTeLink(TeLinkTpGlobalKey linkKey, TeLink link,
+                              boolean parentUpdate, boolean teLinkUpdate,
+                              NetworkLinkKey networkLinkKey) {
+        InternalTeTopology intTopo = teTopologyMap.get(linkKey.teTopologyKey());
+        if (intTopo == null && !parentUpdate) {
+            log.error("TE Topology is not in dataStore for linkUpdate {}",
+                      linkKey);
+            return;
+        }
+        InternalTeNode intNode = teNodeMap.get(linkKey.teNodeKey());
+        if (intNode == null && !parentUpdate) {
+            log.error("TE node is not in dataStore for linkUpdate {}", linkKey);
+            return;
+        }
+        InternalTeLink exLink = teLinkMap.get(linkKey);
+
+        // Update teLinkMap
+        InternalTeLink intLink = new InternalTeLink(link, parentUpdate);
+        intLink.setNetworkLinkKey(networkLinkKey);
+        teLinkMap.put(linkKey, intLink);
+        if (exLink == null && !parentUpdate) {
+            if (intTopo != null) {
+                // Update the InternalTeTopology
+                intTopo.setChildUpdate(true);
+                intTopo.setTeLinkKeys(TeUtils
+                        .addListElement(intTopo.teLinkKeys(), linkKey));
+            }
+            if (intNode != null) {
+                // Update the InternalNode
+                intNode.setChildUpdate(true);
+                intNode.setTeLinkTpKeys(TeUtils
+                        .addListElement(intNode.teLinkTpKeys(), linkKey));
+            }
+        }
+
+        // Update networkLinkMap
+        if (teLinkUpdate) {
+            updateNetworkLink(networkLinkKey, networkLink(link), parentUpdate,
+                              teLinkUpdate, linkKey);
+        }
+    }
+
+    private NetworkLink networkLink(TeLink link) {
+        KeyId linkId = TeMgrUtil.toNetworkLinkId(link.teLinkKey());
+        NodeTpKey source = null;
+        if (link.teLinkKey() != null) {
+            source = new NodeTpKey(KeyId
+                    .keyId(Long.toString(link.teLinkKey().teNodeId())), KeyId
+                            .keyId(Long
+                                    .toString(link.teLinkKey().teLinkTpId())));
+        }
+        NodeTpKey dest = null;
+        if (link.peerTeLinkKey() != null) {
+            dest = new NodeTpKey(KeyId
+                    .keyId(Long.toString(link.peerTeLinkKey().teNodeId())),
+                                 KeyId.keyId(Long.toString(link.peerTeLinkKey()
+                                         .teLinkTpId())));
+        }
+        List<NetworkLinkKey> supportingLinkIds = null;
+        if (link.supportingTeLinkId() != null) {
+            supportingLinkIds = Lists.newArrayList();
+            supportingLinkIds.add(new NetworkLinkKey(TeMgrUtil.toNetworkId(link
+                    .supportingTeLinkId().teTopologyKey()), TeMgrUtil
+                            .toNetworkLinkId(link.supportingTeLinkId()
+                                    .teLinkTpKey())));
+        }
+        return new DefaultNetworkLink(linkId, source, dest, supportingLinkIds,
+                                      link);
+    }
+
+    @Override
+    public void updateTeLink(TeLinkTpGlobalKey linkKey, TeLink link) {
+        updateTeLink(linkKey, link, false, true,
+                     TeMgrUtil.networkLinkKey(linkKey));
+    }
+
+    private void removeTeLink(TeLinkTpGlobalKey linkKey, boolean teLinkRemove) {
+        // Remove it from InternalTeTopology first
+        InternalTeTopology intTopo = teTopologyMap.get(linkKey.teTopologyKey());
+        if (intTopo != null
+                && CollectionUtils.isNotEmpty(intTopo.teLinkKeys())) {
+            intTopo.setChildUpdate(true);
+            intTopo.teLinkKeys().remove(linkKey);
+        }
+        // Remove it from InternalTeNode
+        InternalTeNode intNode = teNodeMap.get(linkKey.teNodeKey());
+        if (intNode != null
+                && CollectionUtils.isNotEmpty(intNode.teLinkTpKeys())) {
+            intNode.setChildUpdate(true);
+            intNode.teLinkTpKeys().remove(linkKey);
+        }
+        // Then remove it from teLinkMap
+        InternalTeLink link = teLinkMap.remove(linkKey);
+        if (teLinkRemove && link != null) {
+            // Remove it from networkLinkMap
+            removeNetworkLink(link.networkLinkKey(), teLinkRemove);
+        }
+    }
+
+    @Override
+    public void removeTeLink(TeLinkTpGlobalKey linkKey) {
+        removeTeLink(linkKey, true);
+    }
+
+    private NetworkLink networkLink(NetworkLinkKey linkKey,
+                                    InternalNetworkLink intLink) {
+        if (intLink == null) {
+            return null;
+        }
+        return new DefaultNetworkLink(linkKey.linkId(), intLink.source(),
+                                      intLink.destination(),
+                                      intLink.supportingLinkIds(),
+                                      teLink(intLink.teLinkKey()));
+    }
+
+    @Override
+    public NetworkLink networkLink(NetworkLinkKey linkKey) {
+        InternalNetworkLink intLink = networkLinkMap.get(linkKey);
+        return networkLink(linkKey, intLink);
+    }
+
+    private void updateNetworkLink(NetworkLinkKey linkKey, NetworkLink link,
+                                   boolean parentUpdate, boolean teLinkUpdate,
+                                   TeLinkTpGlobalKey teLinkKey) {
+        InternalNetwork intNework = null;
+        if (!parentUpdate) {
+            intNework = networkMap.get(linkKey.networkId());
+            if (intNework == null) {
+                log.error("Network is not in dataStore for linkUpdate {}",
+                          linkKey);
+                return;
+            }
+        }
+
+        InternalNetworkLink exLink = networkLinkMap.get(linkKey);
+
+        // Now update teLinkMap first
+        if (!teLinkUpdate && teLinkKey != null) {
+            updateTeLink(teLinkKey, link.teLink(), parentUpdate, teLinkUpdate,
+                         linkKey);
+        }
+        // Update networkLinkMap
+        InternalNetworkLink intLink = new InternalNetworkLink(link,
+                                                              parentUpdate);
+        intLink.setTeLinkKey(teLinkKey);
+        networkLinkMap.put(linkKey, intLink);
+        if (exLink == null && !parentUpdate && intNework != null) {
+            // Update the InternalNetwork
+            intNework.setChildUpdate(true);
+            TeUtils.addListElement(intNework.linkIds(), linkKey);
+        }
+    }
+
+    @Override
+    public void updateNetworkLink(NetworkLinkKey linkKey, NetworkLink link) {
+        TeLinkTpGlobalKey teLinkKey = null;
+        if (link.teLink() != null) {
+            teLinkKey = new TeLinkTpGlobalKey(networkMap
+                    .get(linkKey.networkId()).teTopologyKey(),
+                                              link.teLink().teLinkKey());
+        }
+
+        updateNetworkLink(linkKey, link, false, false, teLinkKey);
+    }
+
+    private void removeNetworkLink(NetworkLinkKey linkKey,
+                                   boolean teLinkRemove) {
+        // Update the InternalNetwork
+        InternalNetwork intNework = networkMap.get(linkKey.networkId());
+        if (intNework != null
+                && CollectionUtils.isNotEmpty(intNework.linkIds())) {
+            intNework.setChildUpdate(true);
+            intNework.linkIds().remove(linkKey.linkId());
+        }
+        // Remove it from networkLinkMap
+        InternalNetworkLink intLink = networkLinkMap.remove(linkKey);
+        if (!teLinkRemove && intLink != null && intLink.teLinkKey() != null) {
+            // Now remove it from teLinkMap
+            removeTeLink(intLink.teLinkKey(), teLinkRemove);
+        }
+    }
+
+    @Override
+    public void removeNetworkLink(NetworkLinkKey linkKey) {
+        removeNetworkLink(linkKey, false);
+    }
+
+    private TerminationPoint terminationPoint(TerminationPointKey tpKey) {
+        InternalTerminationPoint intTp = tpMap.get(tpKey);
+        if (intTp == null) {
+            return null;
+        }
+        return new DefaultTerminationPoint(tpKey.tpId(),
+                                           intTp.supportingTpIds(),
+                                           intTp.teTpKey().teLinkTpId());
+    }
+
+    private void updateTerminationPoint(TerminationPointKey tpKey,
+                                        TerminationPoint tp,
+                                        boolean parentUpdate,
+                                        TeNodeKey teNodeKey) {
+        TeNodeKey myTeNodeKey;
+        InternalNetworkNode intNode = null;
+        if (!parentUpdate) {
+            intNode = networkNodeMap.get(tpKey.nodeId());
+            if (intNode == null) {
+                log.error(" node is not in dataStore for tp update {}", tpKey);
+                return;
+            }
+            myTeNodeKey = intNode.teNodeKey();
+        } else {
+            myTeNodeKey = teNodeKey;
+        }
+        TeLinkTpGlobalKey teTpKey = new TeLinkTpGlobalKey(myTeNodeKey,
+                                                          tp.teTpId());
+
+        boolean newTp = tpMap.get(tpKey) == null;
+        InternalTerminationPoint intTp = new InternalTerminationPoint(tp);
+        intTp.setTeTpKey(teTpKey);
+        tpMap.put(tpKey, intTp);
+        if (newTp) {
+            // Update tpKeyMap
+            tpKeyMap.put(teTpKey, tpKey);
+            if (!parentUpdate && intNode != null) {
+                // Update InternalNetworkNode
+                intNode.setChildUpdate(true);
+                intNode.setTpIds(TeUtils.addListElement(intNode.tpIds(),
+                                                        tpKey.tpId()));
+            }
+        }
+    }
+
+    @Override
+    public void updateTerminationPoint(TerminationPointKey tpKey,
+                                       TerminationPoint tp) {
+        updateTerminationPoint(tpKey, tp, false, null);
+    }
+
+    @Override
+    public void removeTerminationPoint(TerminationPointKey tpKey) {
+        // Update InternalNetworkNode
+        InternalNetworkNode intNode = networkNodeMap.get(tpKey.nodeId());
+        if (intNode != null && CollectionUtils.isNotEmpty(intNode.tpIds())) {
+            intNode.setChildUpdate(true);
+            intNode.tpIds().remove(tpKey.tpId());
+        }
+        // Remove it from tpMap
+        InternalTerminationPoint tp = tpMap.remove(tpKey);
+        // Remove it from tpKeyMap
+        if (tp != null) {
+            tpKeyMap.remove(tp.teTpKey());
+        }
+    }
+
+    @Override
+    public TunnelTerminationPoint tunnelTerminationPoint(TtpKey ttpId) {
+        return ttpMap.get(ttpId);
+    }
+
+    @Override
+    public long nextTeTopologyId() {
+        return 0;
+    }
+
+    @Override
+    public long nextTeNodeId(TeTopologyKey topoKey) {
+        return teTopologyMap.get(topoKey).nextTeNodeId();
+    }
+
+    @Override
+    public void setNextTeNodeId(TeTopologyKey topoKey, long nextNodeId) {
+        teTopologyMap.get(topoKey).setNextTeNodeId(nextNodeId);
+    }
+
+    @Override
+    public KeyId networkId(TeTopologyKey teTopologyKey) {
+        return teTopologyMap.get(teTopologyKey).topologyData().networkId();
+    }
+
+    @Override
+    public NetworkNodeKey nodeKey(TeNodeKey teNodeKey) {
+        return teNodeMap.get(teNodeKey).networkNodeKey();
+    }
+
+    @Override
+    public NetworkLinkKey linkKey(TeLinkTpGlobalKey teLinkKey) {
+        return teLinkMap.get(teLinkKey).networkLinkKey();
+    }
+
+    @Override
+    public TerminationPointKey terminationPointKey(TeLinkTpGlobalKey teTpKey) {
+        return tpKeyMap.get(teTpKey);
+    }
+
+    @Override
+    public void setMapEventQueue(BlockingQueue<TeTopologyMapEvent> queue) {
+    }
+}
+
diff --git a/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/TeTopologyManagerTest.java b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/TeTopologyManagerTest.java
new file mode 100644
index 0000000..03d21fb
--- /dev/null
+++ b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/TeTopologyManagerTest.java
@@ -0,0 +1,182 @@
+/**
+ * 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.tetopology.management;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.NetTestTools.injectEventDispatcher;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_REMOVED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_REMOVED;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.event.Event;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.tetopology.management.api.Network;
+import org.onosproject.tetopology.management.api.TeTopology;
+import org.onosproject.tetopology.management.api.TeTopologyEvent;
+import org.onosproject.tetopology.management.api.TeTopologyListener;
+import org.onosproject.tetopology.management.api.TeTopologyProvider;
+import org.onosproject.tetopology.management.api.TeTopologyProviderRegistry;
+import org.onosproject.tetopology.management.api.TeTopologyProviderService;
+import org.onosproject.tetopology.management.api.TeTopologyService;
+import org.onosproject.tetopology.management.api.link.TeLink;
+import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
+import org.onosproject.tetopology.management.api.node.TeNode;
+import org.onosproject.tetopology.management.api.node.TeNodeKey;
+import org.onosproject.tetopology.management.impl.TeMgrUtil;
+import org.onosproject.tetopology.management.impl.TeTopologyManager;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Test TeTopology service and TeTopologyProvider service.
+ */
+public class TeTopologyManagerTest {
+    private static final ProviderId PID = new ProviderId("test", "TeTopologyManagerTest");
+
+    private TeTopologyManager mgr;
+    protected TeTopologyService service;
+    protected TeTopologyProviderRegistry registry;
+    protected TeTopologyProviderService providerService;
+    protected TestProvider provider;
+    protected TestListener listener = new TestListener();
+
+    @Before
+    public void setUp() {
+        mgr = new TeTopologyManager();
+        service = mgr;
+        registry = mgr;
+        mgr.store = new SimpleTeTopologyStore();
+
+        injectEventDispatcher(mgr, new TestEventDispatcher());
+
+        mgr.activateBasics();
+        service.addListener(listener);
+
+        provider = new TestProvider();
+        providerService = registry.register(provider);
+        assertTrue("providerService should not be null", providerService != null);
+        assertTrue("Provider should be registered",
+                   registry.getProviders().contains(provider.id()));
+    }
+
+    @After
+    public void tearDown() {
+        registry.unregister(provider);
+        assertFalse("provider should not be registered",
+                    registry.getProviders().contains(provider.id()));
+        service.removeListener(listener);
+        mgr.deactivateBasics();
+    }
+
+    private void createNetwork() {
+        Network originNetwork = DefaultBuilder.buildSampleAbstractNetwork();
+        providerService.networkUpdated(originNetwork);
+        Network network = service
+                .network(TeMgrUtil.toNetworkId(DefaultBuilder.teTopologyKey()));
+        assertNotNull("Network should be found", network);
+    }
+
+    /**
+     * Checks the right events are received when a network with TE topology is
+     * added.
+     */
+    @Test
+    public void networkAdded() {
+        createNetwork();
+        validateEvents(TE_TOPOLOGY_ADDED, NETWORK_ADDED);
+    }
+
+    /**
+     * Checks the TE topology components are set properly in Manager and Store
+     * when a network is added.
+     */
+    @Test
+    public void teTopologyVerify() {
+        createNetwork();
+        TeTopology teTopology = service
+                .teTopology(DefaultBuilder.teTopologyKey());
+        assertNotNull("TeTopology should be found", teTopology);
+        assertTrue("Number of TE nodes should be 1",
+                   teTopology.teNodes().size() == 1);
+        assertTrue("Number of TE links should be 1",
+                   teTopology.teLinks().size() == 1);
+        TeNode teNode = service
+                .teNode(new TeNodeKey(DefaultBuilder.teTopologyKey(),
+                                      DefaultBuilder.teNode().teNodeId()));
+        assertNotNull("TeNode should be found", teNode);
+        assertTrue("Number of TTPs should be 1",
+                   teNode.tunnelTerminationPoints().size() == 1);
+        TeLink teLink = service
+                .teLink(new TeLinkTpGlobalKey(DefaultBuilder
+                        .teTopologyKey(), DefaultBuilder.teLink().teLinkKey()));
+        assertNotNull("TeLink should be found", teLink);
+    }
+
+    /**
+     * Checks the right events are received when a network with TE topology is
+     * added and then removed.
+     */
+    @Test
+    public void networkRemoved() {
+        createNetwork();
+        providerService.networkRemoved(TeMgrUtil
+                .toNetworkId(DefaultBuilder.teTopologyKey()));
+        validateEvents(TE_TOPOLOGY_ADDED, NETWORK_ADDED, NETWORK_REMOVED,
+                       TE_TOPOLOGY_REMOVED);
+    }
+
+    /**
+     * Validates whether the manager receives the right events.
+     *
+     * @param types a set of types of control message event
+     */
+    protected void validateEvents(Enum... types) {
+        int i = 0;
+        assertEquals("wrong events received", types.length, listener.events.size());
+        for (Event event : listener.events) {
+            assertEquals("incorrect event type", types[i], event.type());
+            i++;
+        }
+        listener.events.clear();
+    }
+
+    private class TestProvider extends AbstractProvider implements TeTopologyProvider {
+        protected TestProvider() {
+            super(PID);
+        }
+    }
+
+    private static class TestListener implements TeTopologyListener {
+        final List<TeTopologyEvent> events = Lists.newArrayList();
+
+        @Override
+        public void event(TeTopologyEvent event) {
+            events.add(event);
+        }
+    }
+
+}
diff --git a/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/package-info.java b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/package-info.java
new file mode 100644
index 0000000..071f1d2
--- /dev/null
+++ b/apps/tetopology/app/src/test/java/org/onosproject/tetopology/management/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * The TE topology implementation test functions.
+ */
+package org.onosproject.tetopology.management;