Enhancement of tetopology implementation
To support regualar network and TE topology
Change-Id: Ib8319212d775c78f49a86a7b7685759099189967
diff --git a/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/DistributedTeTopologyStore.java b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/DistributedTeTopologyStore.java
new file mode 100644
index 0000000..e3284b3
--- /dev/null
+++ b/apps/tetopology/app/src/main/java/org/onosproject/tetopology/management/impl/DistributedTeTopologyStore.java
@@ -0,0 +1,1413 @@
+/*
+ * 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.impl;
+
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.LINK_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.LINK_REMOVED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.LINK_UPDATED;
+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.NETWORK_UPDATED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NODE_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NODE_REMOVED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NODE_UPDATED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_LINK_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_LINK_REMOVED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_LINK_UPDATED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_NODE_ADDED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_NODE_REMOVED;
+import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_NODE_UPDATED;
+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.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_UPDATED;
+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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.net.DeviceId;
+import org.onosproject.store.AbstractStore;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.AtomicCounter;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.MapEventListener;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+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.EncodingType;
+import org.onosproject.tetopology.management.api.KeyId;
+import org.onosproject.tetopology.management.api.LongValue;
+import org.onosproject.tetopology.management.api.Network;
+import org.onosproject.tetopology.management.api.OptimizationType;
+import org.onosproject.tetopology.management.api.ProviderClientId;
+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.TeTopologies;
+import org.onosproject.tetopology.management.api.TeTopology;
+import org.onosproject.tetopology.management.api.TeTopologyEvent;
+import org.onosproject.tetopology.management.api.TeTopologyEvent.Type;
+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.AsNumber;
+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.ElementType;
+import org.onosproject.tetopology.management.api.link.ExternalLink;
+import org.onosproject.tetopology.management.api.link.Label;
+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.PathElement;
+import org.onosproject.tetopology.management.api.link.TeIpv4;
+import org.onosproject.tetopology.management.api.link.TeIpv6;
+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.TunnelProtectionType;
+import org.onosproject.tetopology.management.api.link.UnderlayAbstractPath;
+import org.onosproject.tetopology.management.api.link.UnderlayBackupPath;
+import org.onosproject.tetopology.management.api.link.UnderlayPath;
+import org.onosproject.tetopology.management.api.link.UnderlayPrimaryPath;
+import org.onosproject.tetopology.management.api.link.UnnumberedLink;
+import org.onosproject.tetopology.management.api.node.CommonNodeData;
+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.DefaultTunnelTerminationPoint;
+import org.onosproject.tetopology.management.api.node.LocalLinkConnectivity;
+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.slf4j.Logger;
+
+import com.esotericsoftware.kryo.serializers.JavaSerializer;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Implementation of the TE network store.
+ */
+@Component(immediate = true)
+@Service
+public class DistributedTeTopologyStore
+ extends AbstractStore<TeTopologyEvent, TeTopologyStoreDelegate>
+ implements TeTopologyStore {
+ private static final String STORE_NAME = "TE_NETWORK_TOPOLOGY_STORE";
+ private static final String TETOPOLOGYKEY_INTERNALTETOPOLOGY = "TeTopologyKey-InternalTeTopology";
+ private static final String NETWORKID_NETWORK = "NetworkId-Network";
+ private static final String TENODEKEY_INTERNALTENODE = "TeNodeKey-InternalTeNode";
+ private static final String CONNMATRIXKEY_CONNECTIVITYMATRIX = "ConnMatrixKey-ConnectivityMatrix";
+ private static final String NETWORKNODEKEY_INTERNALNETWORKNODE = "NetworkNodeKey-InternalNetworkNode";
+ private static final String TELINKGLOBALKEY_INTERNALTELINK = "TeLinkGlobalKey-InternalTeLink";
+ private static final String NETWORKLINKKEY_INTERNALNETWORKLINK = "NetworkLinkKey-InternalNetworkLink";
+ private static final String TPKEY_INTERNALTERMINATIONPOINT = "tpKey-InternalTerminationPoint";
+ private static final String TELINKTPGLOBALKEY_TERMINATIONPOINTKEY = "TeLinkGlobalKey-TerminationPointKey";
+ private static final String TTPKEY_TUNNELTERMINATIONPOINT = "TtpKey-TunnelTerminationPoint";
+ private final Logger log = getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected StorageService storageService;
+ // Track TE topologies by TE Topology key
+ private ConsistentMap<TeTopologyKey, InternalTeTopology> teTopologyConsistentMap;
+ private Map<TeTopologyKey, InternalTeTopology> teTopologyMap;
+ private AtomicCounter nextTeTopologyId;
+ // Listener for te topology events
+ private final MapEventListener<TeTopologyKey, InternalTeTopology> teTopologyListener =
+ new InternalTeTopologyListener();
+ // Track networks by network Id
+ private ConsistentMap<KeyId, InternalNetwork> networkConsistentMap;
+ private Map<KeyId, InternalNetwork> networkMap;
+ // Listener for network events
+ private final MapEventListener<KeyId, InternalNetwork> networkListener =
+ new InternalNetworkListener();
+ // Track TE nodes by TE node key
+ private ConsistentMap<TeNodeKey, InternalTeNode> teNodeConsistentMap;
+ private Map<TeNodeKey, InternalTeNode> teNodeMap;
+ // Track ConnectivityMatrix by its key
+ private ConsistentMap<ConnectivityMatrixKey, ConnectivityMatrix> connMatrixConsistentMap;
+ private Map<ConnectivityMatrixKey, ConnectivityMatrix> connMatrixMap;
+ // Track Tunnel Termination Points by its key
+ private ConsistentMap<TtpKey, TunnelTerminationPoint> ttpConsistentMap;
+ private Map<TtpKey, TunnelTerminationPoint> ttpMap;
+ // Listener for TE node events
+ private final MapEventListener<TeNodeKey, InternalTeNode> teNodeListener =
+ new InternalTeNodeListener();
+ // Track network nodes by network node key
+ private ConsistentMap<NetworkNodeKey, InternalNetworkNode> networkNodeConsistentMap;
+ private Map<NetworkNodeKey, InternalNetworkNode> networkNodeMap;
+ // Listener for network node events
+ private final MapEventListener<NetworkNodeKey, InternalNetworkNode> networkNodeListener =
+ new InternalNetworkNodeListener();
+ // Track TE links by its key
+ private ConsistentMap<TeLinkTpGlobalKey, InternalTeLink> teLinkConsistentMap;
+ private Map<TeLinkTpGlobalKey, InternalTeLink> teLinkMap;
+ // Listener for te link events
+ private final MapEventListener<TeLinkTpGlobalKey, InternalTeLink> teLinkListener =
+ new InternalTeLinkListener();
+ // Track network links by network link key
+ private ConsistentMap<NetworkLinkKey, InternalNetworkLink> networkLinkConsistentMap;
+ private Map<NetworkLinkKey, InternalNetworkLink> networkLinkMap;
+ // Listener for network link events
+ private final MapEventListener<NetworkLinkKey, InternalNetworkLink> networkLinkListener =
+ new InternalNetworkLinkListener();
+ // Track Termination points by termination point key
+ private ConsistentMap<TerminationPointKey, InternalTerminationPoint> tpConsistentMap;
+ private Map<TerminationPointKey, InternalTerminationPoint> tpMap;
+ // Track termination point keys by TE termination point Key
+ private ConsistentMap<TeLinkTpGlobalKey, TerminationPointKey> tpKeyConsistentMap;
+ private Map<TeLinkTpGlobalKey, TerminationPointKey> tpKeyMap;
+ private BlockingQueue<TeTopologyMapEvent> mapEventQueue;
+ private static final Serializer TETOPOLOGY_SERIALIZER = Serializer
+ .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
+ .register(TeTopologyKey.class)
+ .register(ProviderClientId.class)
+ .register(TeNodeKey.class)
+ .register(TeLinkTpGlobalKey.class)
+ .register(CommonTopologyData.class)
+ .register(KeyId.class)
+ .register(OptimizationType.class)
+ .register(new JavaSerializer(), BitSet.class)
+ .register(InternalTeTopology.class)
+ .register(InternalNetwork.class)
+ .register(InternalTerminationPoint.class)
+ .register(InternalTeNode.class)
+ .register(InternalNetworkNode.class)
+ .register(CommonNodeData.class)
+ .register(ConnectivityMatrixKey.class)
+ .register(ConnectivityMatrix.class)
+ .register(TtpKey.class)
+ .register(NetworkNodeKey.class)
+ .register(TeStatus.class)
+ .register(ElementType.class)
+ .register(TeIpv4.class)
+ .register(TeIpv6.class)
+ .register(AsNumber.class)
+ .register(Label.class)
+ .register(UnnumberedLink.class)
+ .register(InternalTeLink.class)
+ .register(InternalNetworkLink.class)
+ .register(TeLinkTpKey.class)
+ .register(NetworkLinkKey.class)
+ .register(NodeTpKey.class)
+ .register(CommonLinkData.class)
+ .register(SwitchingType.class)
+ .register(EncodingType.class)
+ .register(ExternalLink.class)
+ .register(UnderlayPath.class)
+ .register(LinkBandwidth.class)
+ .register(OduResource.class)
+ .register(PathElement.class)
+ .register(UnderlayAbstractPath.class)
+ .register(UnderlayBackupPath.class)
+ .register(UnderlayPrimaryPath.class)
+ .register(TePathAttributes.class)
+ .register(TerminationPoint.class)
+ .register(TunnelTerminationPoint.class)
+ .register(DefaultTunnelTerminationPoint.class)
+ .register(TerminationPointKey.class)
+ .register(TunnelProtectionType.class)
+ .register(LongValue.class)
+ .register(LocalLinkConnectivity.class)
+ .build());
+
+ /**
+ * Distributed network store service activate method.
+ */
+ @Activate
+ public void activate() {
+ teTopologyConsistentMap = storageService
+ .<TeTopologyKey, InternalTeTopology>consistentMapBuilder()
+ .withSerializer(TETOPOLOGY_SERIALIZER)
+ .withName(TETOPOLOGYKEY_INTERNALTETOPOLOGY)
+ .withRelaxedReadConsistency()
+ .build();
+ teTopologyConsistentMap.addListener(teTopologyListener);
+ teTopologyMap = teTopologyConsistentMap.asJavaMap();
+ networkConsistentMap = storageService
+ .<KeyId, InternalNetwork>consistentMapBuilder()
+ .withSerializer(TETOPOLOGY_SERIALIZER)
+ .withName(NETWORKID_NETWORK)
+ .withRelaxedReadConsistency()
+ .build();
+ networkConsistentMap.addListener(networkListener);
+ networkMap = networkConsistentMap.asJavaMap();
+ teNodeConsistentMap = storageService
+ .<TeNodeKey, InternalTeNode>consistentMapBuilder()
+ .withSerializer(TETOPOLOGY_SERIALIZER)
+ .withName(TENODEKEY_INTERNALTENODE)
+ .withRelaxedReadConsistency()
+ .build();
+ teNodeConsistentMap.addListener(teNodeListener);
+ teNodeMap = teNodeConsistentMap.asJavaMap();
+ connMatrixConsistentMap = storageService
+ .<ConnectivityMatrixKey, ConnectivityMatrix>consistentMapBuilder()
+ .withSerializer(TETOPOLOGY_SERIALIZER)
+ .withName(CONNMATRIXKEY_CONNECTIVITYMATRIX)
+ .withRelaxedReadConsistency()
+ .build();
+ connMatrixMap = connMatrixConsistentMap.asJavaMap();
+ networkNodeConsistentMap = storageService
+ .<NetworkNodeKey, InternalNetworkNode>consistentMapBuilder()
+ .withSerializer(TETOPOLOGY_SERIALIZER)
+ .withName(NETWORKNODEKEY_INTERNALNETWORKNODE)
+ .withRelaxedReadConsistency()
+ .build();
+ networkNodeConsistentMap.addListener(networkNodeListener);
+ networkNodeMap = networkNodeConsistentMap.asJavaMap();
+ teLinkConsistentMap = storageService
+ .<TeLinkTpGlobalKey, InternalTeLink>consistentMapBuilder()
+ .withSerializer(TETOPOLOGY_SERIALIZER)
+ .withName(TELINKGLOBALKEY_INTERNALTELINK)
+ .withRelaxedReadConsistency()
+ .build();
+ teLinkConsistentMap.addListener(teLinkListener);
+ teLinkMap = teLinkConsistentMap.asJavaMap();
+ networkLinkConsistentMap = storageService
+ .<NetworkLinkKey, InternalNetworkLink>consistentMapBuilder()
+ .withSerializer(TETOPOLOGY_SERIALIZER)
+ .withName(NETWORKLINKKEY_INTERNALNETWORKLINK)
+ .withRelaxedReadConsistency()
+ .build();
+ networkLinkConsistentMap.addListener(networkLinkListener);
+ networkLinkMap = networkLinkConsistentMap.asJavaMap();
+ tpConsistentMap = storageService
+ .<TerminationPointKey, InternalTerminationPoint>consistentMapBuilder()
+ .withSerializer(TETOPOLOGY_SERIALIZER)
+ .withName(TPKEY_INTERNALTERMINATIONPOINT)
+ .withRelaxedReadConsistency()
+ .build();
+ tpMap = tpConsistentMap.asJavaMap();
+ tpKeyConsistentMap = storageService
+ .<TeLinkTpGlobalKey, TerminationPointKey>consistentMapBuilder()
+ .withSerializer(TETOPOLOGY_SERIALIZER)
+ .withName(TELINKTPGLOBALKEY_TERMINATIONPOINTKEY)
+ .withRelaxedReadConsistency()
+ .build();
+ tpKeyMap = tpKeyConsistentMap.asJavaMap();
+ ttpConsistentMap = storageService
+ .<TtpKey, TunnelTerminationPoint>consistentMapBuilder()
+ .withSerializer(TETOPOLOGY_SERIALIZER)
+ .withName(TTPKEY_TUNNELTERMINATIONPOINT)
+ .withRelaxedReadConsistency()
+ .build();
+ ttpMap = ttpConsistentMap.asJavaMap();
+
+ nextTeTopologyId = storageService.getAtomicCounter("COUNTER_NAME");
+ log.info("Started");
+ }
+
+ /**
+ * Distributed network store service deactivate method.
+ */
+ @Deactivate
+ public void deactivate() {
+ teTopologyConsistentMap.removeListener(teTopologyListener);
+ teTopologyConsistentMap.destroy();
+ teTopologyMap.clear();
+ networkConsistentMap.removeListener(networkListener);
+ networkConsistentMap.destroy();
+ networkMap.clear();
+ teNodeConsistentMap.removeListener(teNodeListener);
+ teNodeConsistentMap.destroy();
+ teNodeMap.clear();
+ connMatrixConsistentMap.destroy();
+ connMatrixMap.clear();
+ networkNodeConsistentMap.destroy();
+ networkNodeConsistentMap.removeListener(networkNodeListener);
+ networkNodeMap.clear();
+ teLinkConsistentMap.removeListener(teLinkListener);
+ teLinkConsistentMap.destroy();
+ teLinkMap.clear();
+ networkLinkConsistentMap.destroy();
+ networkLinkConsistentMap.removeListener(networkLinkListener);
+ networkLinkMap.clear();
+ tpConsistentMap.destroy();
+ tpMap.clear();
+ tpKeyConsistentMap.destroy();
+ tpKeyMap.clear();
+ ttpConsistentMap.destroy();
+ ttpMap.clear();
+ log.info("Stopped");
+ }
+
+ /**
+ * Listener class to map listener map events to the TETOPOLOGY events.
+ */
+ private class InternalTeTopologyListener implements MapEventListener<TeTopologyKey, InternalTeTopology> {
+ @Override
+ public void event(MapEvent<TeTopologyKey, InternalTeTopology> event) {
+ Type type = null;
+ switch (event.type()) {
+ case INSERT:
+ type = TE_TOPOLOGY_ADDED;
+ break;
+ case UPDATE:
+ if (event.newValue().value().childUpdate()) {
+ // Masked by the child events (e.g. Removal)
+ break;
+ }
+ type = TE_TOPOLOGY_UPDATED;
+ break;
+ case REMOVE:
+ type = TE_TOPOLOGY_REMOVED;
+ break;
+ default:
+ log.error("Unsupported event type: {}", event.type());
+ }
+ if (type != null) {
+ TeTopologyMapEvent mapEvent = new TeTopologyMapEvent(type);
+ mapEvent.setTeTopologyKey(event.key());
+ try {
+ mapEventQueue.put(mapEvent);
+ } catch (InterruptedException e) {
+ log.warn("Unable to queue event {} ", mapEvent, e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Listener class to map listener map events to the network events.
+ */
+ private class InternalNetworkListener implements MapEventListener<KeyId, InternalNetwork> {
+ @Override
+ public void event(MapEvent<KeyId, InternalNetwork> event) {
+ Type type = null;
+ switch (event.type()) {
+ case INSERT:
+ type = NETWORK_ADDED;
+ break;
+ case UPDATE:
+ if (event.newValue().value().childUpdate()) {
+ // Masked by the child events (e.g. Removal)
+ break;
+ }
+ type = NETWORK_UPDATED;
+ break;
+ case REMOVE:
+ type = NETWORK_REMOVED;
+ break;
+ default:
+ log.error("Unsupported event type: {}", event.type());
+ }
+ if (type != null) {
+ TeTopologyMapEvent mapEvent = new TeTopologyMapEvent(type);
+ mapEvent.setNetworkKey(event.key());
+ try {
+ mapEventQueue.put(mapEvent);
+ } catch (InterruptedException e) {
+ log.warn("Unable to queue event {} ", mapEvent, e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Listener class to map listener map events to the TENODE events.
+ */
+ private class InternalTeNodeListener implements MapEventListener<TeNodeKey, InternalTeNode> {
+ @Override
+ public void event(MapEvent<TeNodeKey, InternalTeNode> event) {
+ // Event should be ignored when the topology is not there.
+ if (teTopologyMap.get(event.key().teTopologyKey()) == null) {
+ return;
+ }
+ Type type = null;
+ switch (event.type()) {
+ case INSERT:
+ if (event.newValue().value().parentUpdate()) {
+ // Masked by the parent event (e.g. Add)
+ break;
+ }
+ type = TE_NODE_ADDED;
+ break;
+ case UPDATE:
+ if (event.newValue().value().childUpdate() ||
+ event.newValue().value().parentUpdate()) {
+ // Masked by the child event (e.g. Removal) or parent event
+ break;
+ }
+ type = TE_NODE_UPDATED;
+ break;
+ case REMOVE:
+ type = TE_NODE_REMOVED;
+ break;
+ default:
+ log.error("Unsupported event type: {}", event.type());
+ }
+ if (type != null) {
+ TeTopologyMapEvent mapEvent = new TeTopologyMapEvent(type);
+ mapEvent.setTeNodeKey(event.key());
+ try {
+ mapEventQueue.put(mapEvent);
+ } catch (InterruptedException e) {
+ log.warn("Unable to queue event {} ", mapEvent, e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Listener class to map listener map events to the NETWORK NODE events.
+ */
+ private class InternalNetworkNodeListener implements MapEventListener<NetworkNodeKey, InternalNetworkNode> {
+ @Override
+ public void event(MapEvent<NetworkNodeKey, InternalNetworkNode> event) {
+ // Event should be ignored when the network is not there.
+ if (networkMap.get(event.key().networkId()) == null) {
+ return;
+ }
+ Type type = null;
+ switch (event.type()) {
+ case INSERT:
+ if (event.newValue().value().parentUpdate()) {
+ // Masked by the parent event (e.g. Add)
+ break;
+ }
+ type = NODE_ADDED;
+ break;
+ case UPDATE:
+ if (event.newValue().value().childUpdate() ||
+ event.newValue().value().parentUpdate()) {
+ // Masked by the child event (e.g. Removal) or parent event
+ break;
+ }
+ type = NODE_UPDATED;
+ break;
+ case REMOVE:
+ type = NODE_REMOVED;
+ break;
+ default:
+ log.error("Unsupported event type: {}", event.type());
+ }
+ if (type != null) {
+ TeTopologyMapEvent mapEvent = new TeTopologyMapEvent(type);
+ mapEvent.setNetworkNodeKey(event.key());
+ try {
+ mapEventQueue.put(mapEvent);
+ } catch (InterruptedException e) {
+ log.warn("Unable to queue event {} ", mapEvent, e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Listener class to map listener map events to the TELINK events.
+ */
+ private class InternalTeLinkListener implements MapEventListener<TeLinkTpGlobalKey, InternalTeLink> {
+ @Override
+ public void event(MapEvent<TeLinkTpGlobalKey, InternalTeLink> event) {
+ // Event should be ignored when the topology or locol node is not there.
+ if (teTopologyMap.get(event.key().teTopologyKey()) == null ||
+ teNodeMap.get(event.key().teNodeKey()) == null) {
+ return;
+ }
+ Type type = null;
+ switch (event.type()) {
+ case INSERT:
+ if (event.newValue().value().parentUpdate()) {
+ // Masked by the parent event (e.g. Add)
+ break;
+ }
+ type = TE_LINK_ADDED;
+ break;
+ case UPDATE:
+ if (event.newValue().value().parentUpdate()) {
+ // Masked by parent event
+ break;
+ }
+ type = TE_LINK_UPDATED;
+ break;
+ case REMOVE:
+ type = TE_LINK_REMOVED;
+ break;
+ default:
+ log.error("Unsupported event type: {}", event.type());
+ }
+ if (type != null) {
+ TeTopologyMapEvent mapEvent = new TeTopologyMapEvent(type);
+ mapEvent.setTeLinkKey(event.key());
+ try {
+ mapEventQueue.put(mapEvent);
+ } catch (InterruptedException e) {
+ log.warn("Unable to queue event {} ", mapEvent, e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Listener class to map listener map events to the NETWORK LINK events.
+ */
+ private class InternalNetworkLinkListener implements MapEventListener<NetworkLinkKey, InternalNetworkLink> {
+ @Override
+ public void event(MapEvent<NetworkLinkKey, InternalNetworkLink> event) {
+ // Event should be ignored when the network is not there.
+ if (networkMap.get(event.key().networkId()) == null) {
+ return;
+ }
+ Type type = null;
+ switch (event.type()) {
+ case INSERT:
+ if (event.newValue().value().parentUpdate()) {
+ // Masked by the parent event (e.g. Add)
+ break;
+ }
+ type = LINK_ADDED;
+ break;
+ case UPDATE:
+ if (event.newValue().value().parentUpdate()) {
+ // Masked by the child event (e.g. Removal) or parent event
+ break;
+ }
+ type = LINK_UPDATED;
+ break;
+ case REMOVE:
+ type = LINK_REMOVED;
+ break;
+ default:
+ log.error("Unsupported event type: {}", event.type());
+ }
+ if (type != null) {
+ TeTopologyMapEvent mapEvent = new TeTopologyMapEvent(type);
+ mapEvent.setNetworkLinkKey(event.key());
+ try {
+ mapEventQueue.put(mapEvent);
+ } catch (InterruptedException e) {
+ log.warn("Unable to queue event {} ", mapEvent, e);
+ }
+ }
+ }
+ }
+
+ @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());
+ // 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 &&
+ teTopologyMap.get(curNetwork.teTopologyKey()) != null) {
+ topologyId = new TeTopologyId(curNetwork.teTopologyKey().providerId(),
+ curNetwork.teTopologyKey().clientId(),
+ teTopologyMap
+ .get(curNetwork
+ .teTopologyKey())
+ .teTopologyId());
+ ownerId = teTopologyMap.get(curNetwork.teTopologyKey())
+ .topologyData().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());
+ 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);
+ }
+ // Finally Update networkMap
+ InternalNetwork newNetwork = new InternalNetwork(network);
+ newNetwork.setTeTopologyKey(topoKey);
+ networkMap.put(network.networkId(), newNetwork);
+ }
+
+ @Override
+ public void removeNetwork(KeyId networkId) {
+ // Remove it from networkMap
+ InternalNetwork network = networkMap.remove(networkId);
+ if (network != null && network.teTopologyKey() != null) {
+ removeNetworkMapEntrys(network, false);
+ teTopologyMap.remove(network.teTopologyKey());
+ }
+ }
+
+ 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 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 nextTeTopologyId.getAndIncrement();
+ }
+
+ @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) {
+ mapEventQueue = queue;
+ }
+}
+