blob: 4b3785758d9c4b6c0258b733c128ef1a6ad3d81b [file] [log] [blame]
/*
* Copyright 2016-present Open Networking Foundation
*
* 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 com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
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.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.slf4j.Logger;
import java.util.BitSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import static org.onosproject.tetopology.management.api.OptimizationType.NOT_OPTIMIZED;
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;
/**
* Implementation of the TE network store.
*/
@Component(immediate = true, service = TeTopologyStore.class)
public class DistributedTeTopologyStore
extends AbstractStore<TeTopologyEvent, TeTopologyStoreDelegate>
implements TeTopologyStore {
private static final String STORE_NAME = "TE_NETWORK_TOPOLOGY_STORE";
private static final String COUNTER_NAME = "TeTopology-TeTopologyId";
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)
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);
Thread.currentThread().interrupt();
}
}
}
}
/**
* 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);
Thread.currentThread().interrupt();
}
}
}
}
/**
* 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);
Thread.currentThread().interrupt();
}
}
}
}
/**
* 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);
Thread.currentThread().interrupt();
}
}
}
}
/**
* 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);
Thread.currentThread().interrupt();
}
}
}
}
/**
* 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);
Thread.currentThread().interrupt();
}
}
}
}
@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;
OptimizationType opt = NOT_OPTIMIZED;
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();
opt = teTopologyMap.get(curNetwork.teTopologyKey()).topologyData().optimization();
}
return new DefaultNetwork(networkId, supportingNetworkIds, nodes, links,
topologyId, curNetwork.serverProvided(), ownerId, opt);
}
@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(),
network.optimization(),
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);
}
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);
}
// 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);
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);
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;
}
}