/* * 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 java.util.concurrent.LinkedBlockingQueue; 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.ConnectivityMatrixId; 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.TeLinkId; 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-InternalNetwork"; 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 final BlockingQueue<TeTopologyMapEvent> mapEventQueue = new LinkedBlockingQueue<>(); private long providerId; 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(TeLinkId.class) .register(ConnectivityMatrixId.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(); mapEventQueue.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) { 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) { 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) { 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) { 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) { log.debug("updateNetwork {}", 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() == providerId) { // 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); if (node == null) { log.error("No node found for nodeKey {}", nodeKey); return; } 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) == null || teTopologyMap.get(teTopologyKey).topologyData() == null ? null : teTopologyMap.get(teTopologyKey).topologyData().networkId(); } @Override public NetworkNodeKey nodeKey(TeNodeKey teNodeKey) { return teNodeMap.get(teNodeKey) == null ? null : teNodeMap.get(teNodeKey).networkNodeKey(); } @Override public NetworkLinkKey linkKey(TeLinkTpGlobalKey teLinkKey) { return teLinkMap.get(teLinkKey) == null ? null : teLinkMap.get(teLinkKey).networkLinkKey(); } @Override public TerminationPointKey terminationPointKey(TeLinkTpGlobalKey teTpKey) { return tpKeyMap.get(teTpKey); } @Override public BlockingQueue<TeTopologyMapEvent> mapEventQueue() { return mapEventQueue; } @Override public void setProviderId(long providerId) { this.providerId = providerId; } }