| /* |
| * 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.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(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; |
| } |
| } |
| |