| /** |
| * Copyright 2016-present Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.onosproject.tetopology.management; |
| |
| import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_ADDED; |
| import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_REMOVED; |
| import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_ADDED; |
| import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_REMOVED; |
| import static org.slf4j.LoggerFactory.getLogger; |
| |
| import java.util.BitSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.concurrent.BlockingQueue; |
| |
| import org.apache.commons.collections.CollectionUtils; |
| import org.apache.commons.collections.MapUtils; |
| import org.apache.felix.scr.annotations.Activate; |
| import org.apache.felix.scr.annotations.Component; |
| import org.apache.felix.scr.annotations.Deactivate; |
| import org.apache.felix.scr.annotations.Service; |
| import org.onosproject.net.DeviceId; |
| import org.onosproject.store.AbstractStore; |
| import org.onosproject.tetopology.management.api.CommonTopologyData; |
| import org.onosproject.tetopology.management.api.DefaultNetwork; |
| import org.onosproject.tetopology.management.api.DefaultTeTopologies; |
| import org.onosproject.tetopology.management.api.DefaultTeTopology; |
| import org.onosproject.tetopology.management.api.KeyId; |
| import org.onosproject.tetopology.management.api.Network; |
| import org.onosproject.tetopology.management.api.OptimizationType; |
| import org.onosproject.tetopology.management.api.TeConstants; |
| import org.onosproject.tetopology.management.api.TeTopologies; |
| import org.onosproject.tetopology.management.api.TeTopology; |
| import org.onosproject.tetopology.management.api.TeTopologyEvent; |
| import org.onosproject.tetopology.management.api.TeTopologyId; |
| import org.onosproject.tetopology.management.api.TeTopologyKey; |
| import org.onosproject.tetopology.management.api.TeUtils; |
| import org.onosproject.tetopology.management.api.link.DefaultNetworkLink; |
| import org.onosproject.tetopology.management.api.link.DefaultTeLink; |
| import org.onosproject.tetopology.management.api.link.NetworkLink; |
| import org.onosproject.tetopology.management.api.link.NetworkLinkKey; |
| import org.onosproject.tetopology.management.api.link.TeLink; |
| import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey; |
| import org.onosproject.tetopology.management.api.link.TeLinkTpKey; |
| import org.onosproject.tetopology.management.api.node.ConnectivityMatrix; |
| import org.onosproject.tetopology.management.api.node.ConnectivityMatrixKey; |
| import org.onosproject.tetopology.management.api.node.DefaultNetworkNode; |
| import org.onosproject.tetopology.management.api.node.DefaultTeNode; |
| import org.onosproject.tetopology.management.api.node.DefaultTerminationPoint; |
| import org.onosproject.tetopology.management.api.node.NetworkNode; |
| import org.onosproject.tetopology.management.api.node.NetworkNodeKey; |
| import org.onosproject.tetopology.management.api.node.NodeTpKey; |
| import org.onosproject.tetopology.management.api.node.TeNode; |
| import org.onosproject.tetopology.management.api.node.TeNodeKey; |
| import org.onosproject.tetopology.management.api.node.TerminationPoint; |
| import org.onosproject.tetopology.management.api.node.TerminationPointKey; |
| import org.onosproject.tetopology.management.api.node.TtpKey; |
| import org.onosproject.tetopology.management.api.node.TunnelTerminationPoint; |
| import org.onosproject.tetopology.management.impl.InternalNetwork; |
| import org.onosproject.tetopology.management.impl.InternalNetworkLink; |
| import org.onosproject.tetopology.management.impl.InternalNetworkNode; |
| import org.onosproject.tetopology.management.impl.InternalTeLink; |
| import org.onosproject.tetopology.management.impl.InternalTeNode; |
| import org.onosproject.tetopology.management.impl.InternalTeTopology; |
| import org.onosproject.tetopology.management.impl.InternalTerminationPoint; |
| import org.onosproject.tetopology.management.impl.TeMgrUtil; |
| import org.onosproject.tetopology.management.impl.TeTopologyMapEvent; |
| import org.onosproject.tetopology.management.impl.TeTopologyStore; |
| import org.onosproject.tetopology.management.impl.TeTopologyStoreDelegate; |
| import org.slf4j.Logger; |
| |
| import com.google.common.collect.Lists; |
| import com.google.common.collect.Maps; |
| |
| /** |
| * Implementation of the TE network store. |
| */ |
| @Component(immediate = true) |
| @Service |
| public class SimpleTeTopologyStore |
| extends AbstractStore<TeTopologyEvent, TeTopologyStoreDelegate> |
| implements TeTopologyStore { |
| private static final String STORE_NAME = "TE_NETWORK_TOPOLOGY_STORE"; |
| private final Logger log = getLogger(getClass()); |
| |
| // Track TE topologies by TE Topology key |
| private Map<TeTopologyKey, InternalTeTopology> teTopologyMap = Maps |
| .newConcurrentMap(); |
| // Track networks by network Id |
| private Map<KeyId, InternalNetwork> networkMap = Maps.newConcurrentMap(); |
| // Track TE nodes by TE node key |
| private Map<TeNodeKey, InternalTeNode> teNodeMap = Maps.newConcurrentMap(); |
| // Track ConnectivityMatrix by its key |
| private Map<ConnectivityMatrixKey, ConnectivityMatrix> connMatrixMap = Maps |
| .newConcurrentMap(); |
| // Track Tunnel Termination Points by its key |
| private Map<TtpKey, TunnelTerminationPoint> ttpMap = Maps |
| .newConcurrentMap(); |
| // Track network nodes by network node key |
| private Map<NetworkNodeKey, InternalNetworkNode> networkNodeMap = Maps |
| .newConcurrentMap(); |
| // Track TE links by its key |
| private Map<TeLinkTpGlobalKey, InternalTeLink> teLinkMap = Maps |
| .newConcurrentMap(); |
| // Track network links by network link key |
| private Map<NetworkLinkKey, InternalNetworkLink> networkLinkMap = Maps |
| .newConcurrentMap(); |
| // Track Termination points by termination point key |
| private Map<TerminationPointKey, InternalTerminationPoint> tpMap = Maps |
| .newConcurrentMap(); |
| // Track termination point keys by TE termination point Key |
| private Map<TeLinkTpGlobalKey, TerminationPointKey> tpKeyMap = Maps |
| .newConcurrentMap(); |
| private long providerId; |
| |
| @Activate |
| public void activate() { |
| log.info("Started"); |
| } |
| |
| @Deactivate |
| public void deactivate() { |
| teTopologyMap.clear(); |
| networkMap.clear(); |
| teNodeMap.clear(); |
| connMatrixMap.clear(); |
| networkNodeMap.clear(); |
| teLinkMap.clear(); |
| networkLinkMap.clear(); |
| tpMap.clear(); |
| tpKeyMap.clear(); |
| ttpMap.clear(); |
| log.info("Stopped"); |
| } |
| |
| @Override |
| public TeTopologies teTopologies() { |
| Map<TeTopologyKey, TeTopology> teTopologies = Maps.newHashMap(); |
| if (MapUtils.isNotEmpty(teTopologyMap)) { |
| for (TeTopologyKey key : teTopologyMap.keySet()) { |
| teTopologies.put(key, teTopology(key)); |
| } |
| } |
| return new DefaultTeTopologies(STORE_NAME, teTopologies); |
| } |
| |
| private TeTopology teTopology(TeTopologyKey topologyId, |
| InternalTeTopology intTopology) { |
| if (intTopology == null) { |
| return null; |
| } |
| Map<Long, TeNode> teNodes = null; |
| if (CollectionUtils.isNotEmpty(intTopology.teNodeKeys())) { |
| teNodes = Maps.newHashMap(); |
| for (TeNodeKey key : intTopology.teNodeKeys()) { |
| teNodes.put(key.teNodeId(), teNode(key)); |
| } |
| } |
| Map<TeLinkTpKey, TeLink> teLinks = null; |
| if (CollectionUtils.isNotEmpty(intTopology.teLinkKeys())) { |
| teLinks = Maps.newHashMap(); |
| for (TeLinkTpGlobalKey key : intTopology.teLinkKeys()) { |
| teLinks.put(key.teLinkTpKey(), teLink(key)); |
| } |
| } |
| return new DefaultTeTopology(topologyId, teNodes, teLinks, |
| intTopology.teTopologyId(), |
| intTopology.topologyData()); |
| } |
| |
| @Override |
| public TeTopology teTopology(TeTopologyKey topologyId) { |
| InternalTeTopology intTopology = teTopologyMap.get(topologyId); |
| return teTopology(topologyId, intTopology); |
| } |
| |
| private void removeTopologyeMapEntrys(InternalTeTopology curTopology) { |
| // Remove TE nodes |
| if (CollectionUtils.isNotEmpty(curTopology.teNodeKeys())) { |
| for (TeNodeKey key : curTopology.teNodeKeys()) { |
| removeTeNode(key, true); |
| } |
| } |
| // Remove TE Links |
| if (CollectionUtils.isNotEmpty(curTopology.teLinkKeys())) { |
| for (TeLinkTpGlobalKey key : curTopology.teLinkKeys()) { |
| removeTeLink(key, true); |
| } |
| } |
| } |
| |
| @Override |
| public void updateTeTopology(TeTopology teTopology) { |
| InternalTeTopology curTopology = teTopologyMap |
| .get(teTopology.teTopologyId()); |
| if (curTopology != null) { |
| // Existing topology update |
| // Remove existing map entries first, which should be removed by |
| // its own events |
| removeTopologyeMapEntrys(curTopology); |
| } |
| // Update TE nodes |
| List<NetworkNodeKey> nodeIds = null; |
| if (MapUtils.isNotEmpty(teTopology.teNodes())) { |
| nodeIds = Lists.newArrayList(); |
| for (Map.Entry<Long, TeNode> entry : teTopology.teNodes() |
| .entrySet()) { |
| TeNodeKey teNodeKey = new TeNodeKey(teTopology.teTopologyId(), |
| entry.getKey()); |
| NetworkNodeKey nodeKey = TeMgrUtil.networkNodeKey(teNodeKey); |
| updateTeNode(teNodeKey, entry.getValue(), true, true, nodeKey); |
| nodeIds.add(nodeKey); |
| } |
| } |
| // Update TE links |
| List<NetworkLinkKey> linkIds = null; |
| if (MapUtils.isNotEmpty(teTopology.teLinks())) { |
| linkIds = Lists.newArrayList(); |
| for (Map.Entry<TeLinkTpKey, TeLink> entry : teTopology.teLinks() |
| .entrySet()) { |
| TeLinkTpGlobalKey teLinkKey = new TeLinkTpGlobalKey(teTopology |
| .teTopologyId(), entry.getKey()); |
| NetworkLinkKey linkKey = TeMgrUtil.networkLinkKey(teLinkKey); |
| updateTeLink(teLinkKey, entry.getValue(), true, true, linkKey); |
| linkIds.add(linkKey); |
| } |
| } |
| // Finally Update teTopologyMap |
| InternalTeTopology newTopology = new InternalTeTopology(teTopology); |
| teTopologyMap.put(teTopology.teTopologyId(), newTopology); |
| |
| if (curTopology == null) { |
| // New topology, update networkMap |
| InternalNetwork intNetwork = new InternalNetwork(); |
| intNetwork.setServerProvided(false); |
| intNetwork.setTeTopologyKey(teTopology.teTopologyId()); |
| intNetwork.setNodeIds(nodeIds); |
| intNetwork.setLinkIds(linkIds); |
| networkMap.put(teTopology.networkId(), intNetwork); |
| } |
| } |
| |
| @Override |
| public void removeTeTopology(TeTopologyKey topologyId) { |
| // Remove it from teTopologyMap |
| InternalTeTopology topology = teTopologyMap.remove(topologyId); |
| if (topology != null) { |
| removeTopologyeMapEntrys(topology); |
| // Remove it from networkMap; |
| networkMap.remove(topology.topologyData().networkId()); |
| } |
| } |
| |
| @Override |
| public List<Network> networks() { |
| if (MapUtils.isEmpty(networkMap)) { |
| return null; |
| } |
| List<Network> networks = Lists.newArrayList(); |
| for (KeyId networkId : networkMap.keySet()) { |
| networks.add(network(networkId)); |
| } |
| return networks; |
| } |
| |
| private Network network(KeyId networkId, InternalNetwork curNetwork) { |
| if (curNetwork == null) { |
| return null; |
| } |
| List<KeyId> supportingNetworkIds = curNetwork.supportingNetworkIds(); |
| Map<KeyId, NetworkNode> nodes = null; |
| if (CollectionUtils.isNotEmpty(curNetwork.nodeIds())) { |
| nodes = Maps.newHashMap(); |
| for (NetworkNodeKey key : curNetwork.nodeIds()) { |
| nodes.put(key.nodeId(), networkNode(key)); |
| } |
| } |
| Map<KeyId, NetworkLink> links = null; |
| if (CollectionUtils.isNotEmpty(curNetwork.linkIds())) { |
| links = Maps.newHashMap(); |
| for (NetworkLinkKey key : curNetwork.linkIds()) { |
| links.put(key.linkId(), networkLink(key)); |
| } |
| } |
| TeTopologyId topologyId = null; |
| DeviceId ownerId = null; |
| if (curNetwork.teTopologyKey() != null |
| && teTopology(curNetwork.teTopologyKey()) != null) { |
| topologyId = new TeTopologyId(curNetwork.teTopologyKey() |
| .providerId(), curNetwork.teTopologyKey().clientId(), |
| teTopology(curNetwork.teTopologyKey()) |
| .teTopologyIdStringValue()); |
| ownerId = teTopology(curNetwork.teTopologyKey()).ownerId(); |
| |
| } |
| return new DefaultNetwork(networkId, supportingNetworkIds, nodes, links, |
| topologyId, curNetwork.serverProvided(), |
| ownerId); |
| } |
| |
| @Override |
| public Network network(KeyId networkId) { |
| InternalNetwork curNetwork = networkMap.get(networkId); |
| return network(networkId, curNetwork); |
| } |
| |
| private void removeNetworkMapEntrys(InternalNetwork curNetwork, |
| boolean teRemove) { |
| // Remove TE nodes |
| if (CollectionUtils.isNotEmpty(curNetwork.nodeIds())) { |
| for (NetworkNodeKey key : curNetwork.nodeIds()) { |
| removeNetworkNode(key, teRemove); |
| } |
| } |
| // Remove TE Links |
| if (CollectionUtils.isNotEmpty(curNetwork.linkIds())) { |
| for (NetworkLinkKey key : curNetwork.linkIds()) { |
| removeNetworkLink(key, teRemove); |
| } |
| } |
| } |
| |
| private TeTopologyKey newTeTopologyKey(TeTopologyId teTopologyId) { |
| long idValue; |
| try { |
| idValue = Long.parseLong(teTopologyId.topologyId()); |
| } catch (NumberFormatException e) { |
| // Can't get the long value from the string. |
| // Use an assigned id value from local id pool, |
| // Ideally id should be assigned per provider base. |
| idValue = nextTeTopologyId(); |
| } |
| return new TeTopologyKey(teTopologyId.providerId(), |
| teTopologyId.clientId(), idValue); |
| } |
| |
| @Override |
| public void updateNetwork(Network network) { |
| InternalNetwork curNetwork = networkMap.get(network.networkId()); |
| if (curNetwork != null) { |
| // Existing topology update |
| // Remove existing map entries first, |
| removeNetworkMapEntrys(curNetwork, false); |
| } |
| TeTopologyKey topoKey = null; |
| if (network.teTopologyId() != null) { |
| topoKey = newTeTopologyKey(network.teTopologyId()); |
| } |
| // Update TE nodes |
| List<TeNodeKey> teNodeKeys = null; |
| if (MapUtils.isNotEmpty(network.nodes())) { |
| teNodeKeys = Lists.newArrayList(); |
| for (Map.Entry<KeyId, NetworkNode> entry : network.nodes() |
| .entrySet()) { |
| NetworkNodeKey nodeKey = new NetworkNodeKey(network.networkId(), |
| entry.getKey()); |
| TeNodeKey teNodeKey = null; |
| if (topoKey != null && entry.getValue().teNode() != null) { |
| teNodeKey = new TeNodeKey(topoKey, entry.getValue().teNode() |
| .teNodeId()); |
| } |
| updateNetworkNode(nodeKey, entry.getValue(), true, false, |
| teNodeKey); |
| teNodeKeys.add(teNodeKey); |
| } |
| } |
| // Update TE links |
| List<TeLinkTpGlobalKey> teLinkKeys = null; |
| if (MapUtils.isNotEmpty(network.links())) { |
| teLinkKeys = Lists.newArrayList(); |
| for (Map.Entry<KeyId, NetworkLink> entry : network.links() |
| .entrySet()) { |
| NetworkLinkKey linkKey = new NetworkLinkKey(network.networkId(), |
| entry.getKey()); |
| TeLinkTpGlobalKey teLinkKey = null; |
| if (topoKey != null && entry.getValue().teLink() != null) { |
| teLinkKey = new TeLinkTpGlobalKey(topoKey, entry.getValue() |
| .teLink().teLinkKey()); |
| } |
| updateNetworkLink(linkKey, entry.getValue(), true, false, |
| teLinkKey); |
| teLinkKeys.add(teLinkKey); |
| } |
| } |
| |
| // New network, update TE Topology first |
| if (curNetwork == null) { |
| InternalTeTopology intTopo = new InternalTeTopology(network |
| .teTopologyId().topologyId()); |
| intTopo.setTeNodeKeys(teNodeKeys); |
| intTopo.setTeLinkKeys(teLinkKeys); |
| BitSet flags = new BitSet(TeConstants.FLAG_MAX_BITS); |
| flags.set(TeTopology.BIT_LEARNT); |
| if (network.teTopologyId().clientId() == 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); |
| // Assume new topology |
| TeTopologyEvent topologyEvent = new TeTopologyEvent(TE_TOPOLOGY_ADDED, |
| teTopology(topoKey)); |
| notifyDelegate(topologyEvent); |
| } |
| // Finally Update networkMap |
| InternalNetwork newNetwork = new InternalNetwork(network); |
| newNetwork.setTeTopologyKey(topoKey); |
| networkMap.put(network.networkId(), newNetwork); |
| // Assume new network |
| TeTopologyEvent topologyEvent = new TeTopologyEvent(NETWORK_ADDED, |
| network(network |
| .networkId())); |
| notifyDelegate(topologyEvent); |
| } |
| |
| @Override |
| public void removeNetwork(KeyId networkId) { |
| // Remove it from networkMap |
| InternalNetwork network = networkMap.remove(networkId); |
| TeTopologyEvent topologyEvent = new TeTopologyEvent(NETWORK_REMOVED, |
| new DefaultNetwork(networkId, |
| null, |
| null, |
| null, |
| null, |
| false, |
| null)); |
| notifyDelegate(topologyEvent); |
| if (network != null && network.teTopologyKey() != null) { |
| removeNetworkMapEntrys(network, false); |
| teTopologyMap.remove(network.teTopologyKey()); |
| topologyEvent = new TeTopologyEvent(TE_TOPOLOGY_REMOVED, |
| new DefaultTeTopology(network |
| .teTopologyKey(), null, null, null, null)); |
| notifyDelegate(topologyEvent); |
| } |
| } |
| |
| private TeNode teNode(TeNodeKey nodeKey, InternalTeNode intNode) { |
| if (intNode == null) { |
| return null; |
| } |
| Map<Long, ConnectivityMatrix> connMatrices = null; |
| if (CollectionUtils.isNotEmpty(intNode.connMatrixKeys())) { |
| connMatrices = Maps.newHashMap(); |
| for (ConnectivityMatrixKey key : intNode.connMatrixKeys()) { |
| connMatrices.put(key.entryId(), connMatrixMap.get(key)); |
| } |
| } |
| List<Long> teLinkIds = null; |
| if (CollectionUtils.isNotEmpty(intNode.teLinkTpKeys())) { |
| teLinkIds = Lists.newArrayList(); |
| for (TeLinkTpGlobalKey key : intNode.teLinkTpKeys()) { |
| teLinkIds = TeUtils.addListElement(teLinkIds, key.teLinkTpId()); |
| } |
| } |
| List<Long> tps = null; |
| if (CollectionUtils.isNotEmpty(intNode.teTpKeys())) { |
| tps = Lists.newArrayList(); |
| for (TeLinkTpGlobalKey key : intNode.teTpKeys()) { |
| tps = TeUtils.addListElement(tps, key.teLinkTpId()); |
| } |
| } |
| Map<Long, TunnelTerminationPoint> ttps = null; |
| if (CollectionUtils.isNotEmpty(intNode.ttpKeys())) { |
| ttps = Maps.newHashMap(); |
| for (TtpKey key : intNode.ttpKeys()) { |
| ttps.put(key.ttpId(), ttpMap.get(key)); |
| } |
| } |
| return new DefaultTeNode(nodeKey.teNodeId(), |
| intNode.underlayTopologyKey(), |
| intNode.supportNodeKey(), |
| intNode.sourceTeNodeKey(), intNode.teData(), |
| connMatrices, teLinkIds, ttps, tps); |
| } |
| |
| @Override |
| public TeNode teNode(TeNodeKey nodeKey) { |
| InternalTeNode intNode = teNodeMap.get(nodeKey); |
| return teNode(nodeKey, intNode); |
| } |
| |
| private void removeTeNodeMapEntrys(InternalTeNode intNode) { |
| // Remove connMatrixMap entries for the node |
| if (CollectionUtils.isNotEmpty(intNode.connMatrixKeys())) { |
| for (ConnectivityMatrixKey key : intNode.connMatrixKeys()) { |
| connMatrixMap.remove(key); |
| } |
| } |
| // Remove ttpMap entries for the node |
| if (CollectionUtils.isNotEmpty(intNode.ttpKeys())) { |
| for (TtpKey key : intNode.ttpKeys()) { |
| ttpMap.remove(key); |
| } |
| } |
| } |
| |
| private void updateTeNode(TeNodeKey nodeKey, TeNode node, |
| boolean parentUpdate, boolean teNodeUpdate, |
| NetworkNodeKey networkNodeKey) { |
| InternalTeTopology intTopo = teTopologyMap.get(nodeKey.teTopologyKey()); |
| if (intTopo == null && !parentUpdate) { |
| log.error("TE Topology is not in dataStore for nodeUpdate {}", |
| nodeKey); |
| return; |
| } |
| InternalTeNode curNode = teNodeMap.get(nodeKey); |
| // Update connMatrixMap |
| if (MapUtils.isNotEmpty(node.connectivityMatrices())) { |
| for (Map.Entry<Long, ConnectivityMatrix> entry : node |
| .connectivityMatrices().entrySet()) { |
| connMatrixMap |
| .put(new ConnectivityMatrixKey(nodeKey, entry.getKey()), |
| entry.getValue()); |
| } |
| } |
| // Update ttpMap |
| if (MapUtils.isNotEmpty(node.tunnelTerminationPoints())) { |
| for (Map.Entry<Long, TunnelTerminationPoint> entry : node |
| .tunnelTerminationPoints().entrySet()) { |
| ttpMap.put(new TtpKey(nodeKey, entry.getKey()), |
| entry.getValue()); |
| } |
| } |
| // Update TE Termination Points |
| |
| // Update teNodeMap |
| InternalTeNode intNode = new InternalTeNode(nodeKey, node, |
| networkNodeKey, |
| parentUpdate); |
| teNodeMap.put(nodeKey, intNode); |
| if (curNode == null && !parentUpdate && intTopo != null) { |
| // Update InternalTeTopology |
| intTopo.setChildUpdate(true); |
| TeUtils.addListElement(intTopo.teNodeKeys(), nodeKey); |
| } |
| // Update networkNodeMap |
| if (teNodeUpdate) { |
| updateNetworkNode(networkNodeKey, networkNode(node), parentUpdate, |
| teNodeUpdate, nodeKey); |
| } |
| } |
| |
| private NetworkNode networkNode(TeNode node) { |
| KeyId nodeId = KeyId.keyId(Long.toString(node.teNodeId())); |
| List<NetworkNodeKey> supportingNodeIds = null; |
| if (node.supportingTeNodeId() != null) { |
| supportingNodeIds = Lists.newArrayList(); |
| supportingNodeIds.add(new NetworkNodeKey(TeMgrUtil.toNetworkId((node |
| .supportingTeNodeId().teTopologyKey())), KeyId.keyId(Long |
| .toString(node.supportingTeNodeId().teNodeId())))); |
| } |
| Map<KeyId, TerminationPoint> tps = null; |
| if (node.teTerminationPointIds() != null) { |
| tps = Maps.newHashMap(); |
| for (Long teTpId : node.teTerminationPointIds()) { |
| tps.put(KeyId.keyId(Long.toString(teTpId)), |
| new DefaultTerminationPoint(KeyId |
| .keyId(Long.toString(teTpId)), null, teTpId)); |
| } |
| } |
| return new DefaultNetworkNode(nodeId, supportingNodeIds, node, tps); |
| } |
| |
| @Override |
| public void updateTeNode(TeNodeKey nodeKey, TeNode node) { |
| updateTeNode(nodeKey, node, false, true, |
| TeMgrUtil.networkNodeKey(nodeKey)); |
| } |
| |
| private void removeTeNode(TeNodeKey nodeKey, boolean teNodeRemove) { |
| // Remove it from InternalTeTopology first |
| InternalTeTopology intTopo = teTopologyMap.get(nodeKey.teTopologyKey()); |
| if (intTopo != null |
| && CollectionUtils.isNotEmpty(intTopo.teNodeKeys())) { |
| intTopo.setChildUpdate(true); |
| intTopo.teNodeKeys().remove(nodeKey); |
| } |
| // Then remove it from teNodeMap |
| InternalTeNode node = teNodeMap.remove(nodeKey); |
| removeTeNodeMapEntrys(node); |
| // Remove it from networkNodeMap |
| if (teNodeRemove && node != null) { |
| removeNetworkNode(node.networkNodeKey(), teNodeRemove); |
| } |
| } |
| |
| @Override |
| public void removeTeNode(TeNodeKey nodeKey) { |
| removeTeNode(nodeKey, true); |
| } |
| |
| private NetworkNode networkNode(NetworkNodeKey nodeKey, |
| InternalNetworkNode intNode) { |
| if (intNode == null) { |
| return null; |
| } |
| Map<KeyId, TerminationPoint> tps = Maps.newHashMap(); |
| for (KeyId tpId : intNode.tpIds()) { |
| tps.put(tpId, |
| terminationPoint(new TerminationPointKey(nodeKey, tpId))); |
| |
| } |
| return new DefaultNetworkNode(nodeKey.nodeId(), |
| intNode.supportingNodeIds(), |
| teNode(intNode.teNodeKey()), tps); |
| } |
| |
| @Override |
| public NetworkNode networkNode(NetworkNodeKey nodeKey) { |
| InternalNetworkNode intNode = networkNodeMap.get(nodeKey); |
| return networkNode(nodeKey, intNode); |
| } |
| |
| private void updateNetworkNode(NetworkNodeKey nodeKey, NetworkNode node, |
| boolean parentUpdate, boolean teNodeUpdate, |
| TeNodeKey teNodeKey) { |
| InternalNetwork intNework = null; |
| if (!parentUpdate) { |
| intNework = networkMap.get(nodeKey.networkId()); |
| if (intNework == null) { |
| log.error("Network is not in dataStore for nodeUpdate {}", |
| nodeKey); |
| return; |
| } |
| } |
| |
| InternalNetworkNode exNode = networkNodeMap.get(nodeKey); |
| if (exNode != null && CollectionUtils.isNotEmpty(exNode.tpIds())) { |
| // Remove the TerminationPoints first |
| for (KeyId tpId : exNode.tpIds()) { |
| removeTerminationPoint(new TerminationPointKey(nodeKey, tpId)); |
| } |
| } |
| |
| if (MapUtils.isNotEmpty(node.terminationPoints())) { |
| // Update with new TerminationPoints |
| for (Map.Entry<KeyId, TerminationPoint> entry : node |
| .terminationPoints().entrySet()) { |
| updateTerminationPoint(new TerminationPointKey(nodeKey, |
| entry.getKey()), |
| entry.getValue(), parentUpdate, |
| teNodeKey); |
| } |
| } |
| |
| // Update teNodeMap first |
| if (!teNodeUpdate && teNodeKey != null && node.teNode() != null) { |
| updateTeNode(teNodeKey, node.teNode(), parentUpdate, teNodeUpdate, |
| nodeKey); |
| } |
| // Update networkNodeMap |
| InternalNetworkNode intNode = new InternalNetworkNode(node, |
| parentUpdate); |
| intNode.setTeNodeKey(teNodeKey); |
| networkNodeMap.put(nodeKey, intNode); |
| if (exNode == null && !parentUpdate && intNework != null) { |
| // Update the InternalNetwork |
| intNework.setChildUpdate(true); |
| TeUtils.addListElement(intNework.nodeIds(), nodeKey); |
| } |
| } |
| |
| @Override |
| public void updateNetworkNode(NetworkNodeKey nodeKey, NetworkNode node) { |
| TeNodeKey teNodeKey = null; |
| if (node.teNode() != null) { |
| teNodeKey = new TeNodeKey(networkMap.get(nodeKey.networkId()) |
| .teTopologyKey(), node.teNode().teNodeId()); |
| } |
| updateNetworkNode(nodeKey, node, false, false, teNodeKey); |
| } |
| |
| private void removeNetworkNode(NetworkNodeKey nodeKey, |
| boolean teNodeRemove) { |
| // Update the InternalNetwork |
| InternalNetwork intNework = networkMap.get(nodeKey.networkId()); |
| if (intNework != null |
| && CollectionUtils.isNotEmpty(intNework.nodeIds())) { |
| intNework.setChildUpdate(true); |
| intNework.nodeIds().remove(nodeKey.nodeId()); |
| } |
| InternalNetworkNode intNode = networkNodeMap.remove(nodeKey); |
| if (intNode != null && CollectionUtils.isNotEmpty(intNode.tpIds())) { |
| // Remove the TerminationPoints first |
| for (KeyId tpId : intNode.tpIds()) { |
| removeTerminationPoint(new TerminationPointKey(nodeKey, tpId)); |
| } |
| } |
| if (!teNodeRemove && intNode != null) { |
| // Now remove it from teNodeMap |
| removeTeNode(intNode.teNodeKey(), teNodeRemove); |
| } |
| } |
| |
| @Override |
| public void removeNetworkNode(NetworkNodeKey nodeKey) { |
| removeNetworkNode(nodeKey, false); |
| } |
| |
| private TeLink teLink(TeLinkTpGlobalKey linkKey, InternalTeLink intLink) { |
| if (intLink == null) { |
| return null; |
| } |
| return new DefaultTeLink(linkKey.teLinkTpKey(), intLink.peerTeLinkKey(), |
| intLink.underlayTopologyKey(), |
| intLink.supportingLinkKey(), |
| intLink.sourceTeLinkKey(), intLink.teData()); |
| } |
| |
| @Override |
| public TeLink teLink(TeLinkTpGlobalKey linkKey) { |
| InternalTeLink intLink = teLinkMap.get(linkKey); |
| return teLink(linkKey, intLink); |
| } |
| |
| private void updateTeLink(TeLinkTpGlobalKey linkKey, TeLink link, |
| boolean parentUpdate, boolean teLinkUpdate, |
| NetworkLinkKey networkLinkKey) { |
| InternalTeTopology intTopo = teTopologyMap.get(linkKey.teTopologyKey()); |
| if (intTopo == null && !parentUpdate) { |
| log.error("TE Topology is not in dataStore for linkUpdate {}", |
| linkKey); |
| return; |
| } |
| InternalTeNode intNode = teNodeMap.get(linkKey.teNodeKey()); |
| if (intNode == null && !parentUpdate) { |
| log.error("TE node is not in dataStore for linkUpdate {}", linkKey); |
| return; |
| } |
| InternalTeLink exLink = teLinkMap.get(linkKey); |
| |
| // Update teLinkMap |
| InternalTeLink intLink = new InternalTeLink(link, parentUpdate); |
| intLink.setNetworkLinkKey(networkLinkKey); |
| teLinkMap.put(linkKey, intLink); |
| if (exLink == null && !parentUpdate) { |
| if (intTopo != null) { |
| // Update the InternalTeTopology |
| intTopo.setChildUpdate(true); |
| intTopo.setTeLinkKeys(TeUtils |
| .addListElement(intTopo.teLinkKeys(), linkKey)); |
| } |
| if (intNode != null) { |
| // Update the InternalNode |
| intNode.setChildUpdate(true); |
| intNode.setTeLinkTpKeys(TeUtils |
| .addListElement(intNode.teLinkTpKeys(), linkKey)); |
| } |
| } |
| |
| // Update networkLinkMap |
| if (teLinkUpdate) { |
| updateNetworkLink(networkLinkKey, networkLink(link), parentUpdate, |
| teLinkUpdate, linkKey); |
| } |
| } |
| |
| private NetworkLink networkLink(TeLink link) { |
| KeyId linkId = TeMgrUtil.toNetworkLinkId(link.teLinkKey()); |
| NodeTpKey source = null; |
| if (link.teLinkKey() != null) { |
| source = new NodeTpKey(KeyId |
| .keyId(Long.toString(link.teLinkKey().teNodeId())), KeyId |
| .keyId(Long |
| .toString(link.teLinkKey().teLinkTpId()))); |
| } |
| NodeTpKey dest = null; |
| if (link.peerTeLinkKey() != null) { |
| dest = new NodeTpKey(KeyId |
| .keyId(Long.toString(link.peerTeLinkKey().teNodeId())), |
| KeyId.keyId(Long.toString(link.peerTeLinkKey() |
| .teLinkTpId()))); |
| } |
| List<NetworkLinkKey> supportingLinkIds = null; |
| if (link.supportingTeLinkId() != null) { |
| supportingLinkIds = Lists.newArrayList(); |
| supportingLinkIds.add(new NetworkLinkKey(TeMgrUtil.toNetworkId(link |
| .supportingTeLinkId().teTopologyKey()), TeMgrUtil |
| .toNetworkLinkId(link.supportingTeLinkId() |
| .teLinkTpKey()))); |
| } |
| return new DefaultNetworkLink(linkId, source, dest, supportingLinkIds, |
| link); |
| } |
| |
| @Override |
| public void updateTeLink(TeLinkTpGlobalKey linkKey, TeLink link) { |
| updateTeLink(linkKey, link, false, true, |
| TeMgrUtil.networkLinkKey(linkKey)); |
| } |
| |
| private void removeTeLink(TeLinkTpGlobalKey linkKey, boolean teLinkRemove) { |
| // Remove it from InternalTeTopology first |
| InternalTeTopology intTopo = teTopologyMap.get(linkKey.teTopologyKey()); |
| if (intTopo != null |
| && CollectionUtils.isNotEmpty(intTopo.teLinkKeys())) { |
| intTopo.setChildUpdate(true); |
| intTopo.teLinkKeys().remove(linkKey); |
| } |
| // Remove it from InternalTeNode |
| InternalTeNode intNode = teNodeMap.get(linkKey.teNodeKey()); |
| if (intNode != null |
| && CollectionUtils.isNotEmpty(intNode.teLinkTpKeys())) { |
| intNode.setChildUpdate(true); |
| intNode.teLinkTpKeys().remove(linkKey); |
| } |
| // Then remove it from teLinkMap |
| InternalTeLink link = teLinkMap.remove(linkKey); |
| if (teLinkRemove && link != null) { |
| // Remove it from networkLinkMap |
| removeNetworkLink(link.networkLinkKey(), teLinkRemove); |
| } |
| } |
| |
| @Override |
| public void removeTeLink(TeLinkTpGlobalKey linkKey) { |
| removeTeLink(linkKey, true); |
| } |
| |
| private NetworkLink networkLink(NetworkLinkKey linkKey, |
| InternalNetworkLink intLink) { |
| if (intLink == null) { |
| return null; |
| } |
| return new DefaultNetworkLink(linkKey.linkId(), intLink.source(), |
| intLink.destination(), |
| intLink.supportingLinkIds(), |
| teLink(intLink.teLinkKey())); |
| } |
| |
| @Override |
| public NetworkLink networkLink(NetworkLinkKey linkKey) { |
| InternalNetworkLink intLink = networkLinkMap.get(linkKey); |
| return networkLink(linkKey, intLink); |
| } |
| |
| private void updateNetworkLink(NetworkLinkKey linkKey, NetworkLink link, |
| boolean parentUpdate, boolean teLinkUpdate, |
| TeLinkTpGlobalKey teLinkKey) { |
| InternalNetwork intNework = null; |
| if (!parentUpdate) { |
| intNework = networkMap.get(linkKey.networkId()); |
| if (intNework == null) { |
| log.error("Network is not in dataStore for linkUpdate {}", |
| linkKey); |
| return; |
| } |
| } |
| |
| InternalNetworkLink exLink = networkLinkMap.get(linkKey); |
| |
| // Now update teLinkMap first |
| if (!teLinkUpdate && teLinkKey != null) { |
| updateTeLink(teLinkKey, link.teLink(), parentUpdate, teLinkUpdate, |
| linkKey); |
| } |
| // Update networkLinkMap |
| InternalNetworkLink intLink = new InternalNetworkLink(link, |
| parentUpdate); |
| intLink.setTeLinkKey(teLinkKey); |
| networkLinkMap.put(linkKey, intLink); |
| if (exLink == null && !parentUpdate && intNework != null) { |
| // Update the InternalNetwork |
| intNework.setChildUpdate(true); |
| TeUtils.addListElement(intNework.linkIds(), linkKey); |
| } |
| } |
| |
| @Override |
| public void updateNetworkLink(NetworkLinkKey linkKey, NetworkLink link) { |
| TeLinkTpGlobalKey teLinkKey = null; |
| if (link.teLink() != null) { |
| teLinkKey = new TeLinkTpGlobalKey(networkMap |
| .get(linkKey.networkId()).teTopologyKey(), |
| link.teLink().teLinkKey()); |
| } |
| |
| updateNetworkLink(linkKey, link, false, false, teLinkKey); |
| } |
| |
| private void removeNetworkLink(NetworkLinkKey linkKey, |
| boolean teLinkRemove) { |
| // Update the InternalNetwork |
| InternalNetwork intNework = networkMap.get(linkKey.networkId()); |
| if (intNework != null |
| && CollectionUtils.isNotEmpty(intNework.linkIds())) { |
| intNework.setChildUpdate(true); |
| intNework.linkIds().remove(linkKey.linkId()); |
| } |
| // Remove it from networkLinkMap |
| InternalNetworkLink intLink = networkLinkMap.remove(linkKey); |
| if (!teLinkRemove && intLink != null && intLink.teLinkKey() != null) { |
| // Now remove it from teLinkMap |
| removeTeLink(intLink.teLinkKey(), teLinkRemove); |
| } |
| } |
| |
| @Override |
| public void removeNetworkLink(NetworkLinkKey linkKey) { |
| removeNetworkLink(linkKey, false); |
| } |
| |
| private TerminationPoint terminationPoint(TerminationPointKey tpKey) { |
| InternalTerminationPoint intTp = tpMap.get(tpKey); |
| if (intTp == null) { |
| return null; |
| } |
| return new DefaultTerminationPoint(tpKey.tpId(), |
| intTp.supportingTpIds(), |
| intTp.teTpKey().teLinkTpId()); |
| } |
| |
| private void updateTerminationPoint(TerminationPointKey tpKey, |
| TerminationPoint tp, |
| boolean parentUpdate, |
| TeNodeKey teNodeKey) { |
| TeNodeKey myTeNodeKey; |
| InternalNetworkNode intNode = null; |
| if (!parentUpdate) { |
| intNode = networkNodeMap.get(tpKey.nodeId()); |
| if (intNode == null) { |
| log.error(" node is not in dataStore for tp update {}", tpKey); |
| return; |
| } |
| myTeNodeKey = intNode.teNodeKey(); |
| } else { |
| myTeNodeKey = teNodeKey; |
| } |
| TeLinkTpGlobalKey teTpKey = new TeLinkTpGlobalKey(myTeNodeKey, |
| tp.teTpId()); |
| |
| boolean newTp = tpMap.get(tpKey) == null; |
| InternalTerminationPoint intTp = new InternalTerminationPoint(tp); |
| intTp.setTeTpKey(teTpKey); |
| tpMap.put(tpKey, intTp); |
| if (newTp) { |
| // Update tpKeyMap |
| tpKeyMap.put(teTpKey, tpKey); |
| if (!parentUpdate && intNode != null) { |
| // Update InternalNetworkNode |
| intNode.setChildUpdate(true); |
| intNode.setTpIds(TeUtils.addListElement(intNode.tpIds(), |
| tpKey.tpId())); |
| } |
| } |
| } |
| |
| @Override |
| public void updateTerminationPoint(TerminationPointKey tpKey, |
| TerminationPoint tp) { |
| updateTerminationPoint(tpKey, tp, false, null); |
| } |
| |
| @Override |
| public void removeTerminationPoint(TerminationPointKey tpKey) { |
| // Update InternalNetworkNode |
| InternalNetworkNode intNode = networkNodeMap.get(tpKey.nodeId()); |
| if (intNode != null && CollectionUtils.isNotEmpty(intNode.tpIds())) { |
| intNode.setChildUpdate(true); |
| intNode.tpIds().remove(tpKey.tpId()); |
| } |
| // Remove it from tpMap |
| InternalTerminationPoint tp = tpMap.remove(tpKey); |
| // Remove it from tpKeyMap |
| if (tp != null) { |
| tpKeyMap.remove(tp.teTpKey()); |
| } |
| } |
| |
| @Override |
| public TunnelTerminationPoint tunnelTerminationPoint(TtpKey ttpId) { |
| return ttpMap.get(ttpId); |
| } |
| |
| @Override |
| public long nextTeTopologyId() { |
| return 0; |
| } |
| |
| @Override |
| public long nextTeNodeId(TeTopologyKey topoKey) { |
| return teTopologyMap.get(topoKey).nextTeNodeId(); |
| } |
| |
| @Override |
| public void setNextTeNodeId(TeTopologyKey topoKey, long nextNodeId) { |
| teTopologyMap.get(topoKey).setNextTeNodeId(nextNodeId); |
| } |
| |
| @Override |
| public KeyId networkId(TeTopologyKey teTopologyKey) { |
| return teTopologyMap.get(teTopologyKey).topologyData().networkId(); |
| } |
| |
| @Override |
| public NetworkNodeKey nodeKey(TeNodeKey teNodeKey) { |
| return teNodeMap.get(teNodeKey).networkNodeKey(); |
| } |
| |
| @Override |
| public NetworkLinkKey linkKey(TeLinkTpGlobalKey teLinkKey) { |
| return teLinkMap.get(teLinkKey).networkLinkKey(); |
| } |
| |
| @Override |
| public TerminationPointKey terminationPointKey(TeLinkTpGlobalKey teTpKey) { |
| return tpKeyMap.get(teTpKey); |
| } |
| |
| @Override |
| public void setProviderId(long providerId) { |
| this.providerId = providerId; |
| } |
| |
| @Override |
| public BlockingQueue<TeTopologyMapEvent> mapEventQueue() { |
| return null; |
| } |
| } |
| |