2 * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.genius.itm.itmdirecttunnels.listeners;
10 import static org.opendaylight.mdsal.binding.util.Datastore.OPERATIONAL;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.List;
18 import java.util.Objects;
19 import java.util.concurrent.Callable;
20 import java.util.concurrent.ConcurrentHashMap;
21 import java.util.concurrent.ConcurrentMap;
22 import org.eclipse.jdt.annotation.NonNull;
23 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
24 import org.opendaylight.genius.itm.cache.DpnTepStateCache;
25 import org.opendaylight.genius.itm.cache.TunnelStateCache;
26 import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorCache;
27 import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorEndPointCache;
28 import org.opendaylight.genius.itm.globals.ITMConstants;
29 import org.opendaylight.genius.itm.impl.ItmUtils;
30 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
31 import org.opendaylight.genius.itm.itmdirecttunnels.workers.TunnelStateAddWorker;
32 import org.opendaylight.genius.itm.itmdirecttunnels.workers.TunnelStateAddWorkerForNodeConnector;
33 import org.opendaylight.genius.itm.utils.DpnTepInterfaceInfo;
34 import org.opendaylight.genius.itm.utils.NodeConnectorInfo;
35 import org.opendaylight.genius.itm.utils.NodeConnectorInfoBuilder;
36 import org.opendaylight.genius.itm.utils.TunnelEndPointInfo;
37 import org.opendaylight.genius.itm.utils.TunnelStateInfo;
38 import org.opendaylight.genius.itm.utils.TunnelStateInfoBuilder;
39 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
40 import org.opendaylight.infrautils.utils.concurrent.NamedSimpleReentrantLock.Acquired;
41 import org.opendaylight.mdsal.binding.api.DataBroker;
42 import org.opendaylight.mdsal.binding.util.Datastore.Operational;
43 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
44 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
45 import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
46 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
47 import org.opendaylight.mdsal.common.api.ReadFailedException;
48 import org.opendaylight.serviceutils.tools.listener.AbstractClusteredSyncDataTreeChangeListener;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortReason;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
60 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
61 import org.opendaylight.yangtools.yang.common.Uint64;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
66 * This Class is a Data Change Listener for FlowCapableNodeConnector updates.
67 * This creates an entry in the tunnels-state OperDS for every node-connector used.
69 public class TunnelInventoryStateListener extends
70 AbstractClusteredSyncDataTreeChangeListener<FlowCapableNodeConnector> {
72 private static final Logger LOG = LoggerFactory.getLogger(TunnelInventoryStateListener.class);
73 private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
75 private final JobCoordinator coordinator;
76 private final ManagedNewTransactionRunner txRunner;
77 private final TunnelStateCache tunnelStateCache;
78 private final DpnTepStateCache dpnTepStateCache;
79 private final DPNTEPsInfoCache dpntePsInfoCache;
80 private final UnprocessedNodeConnectorCache unprocessedNCCache;
81 private final UnprocessedNodeConnectorEndPointCache unprocessedNodeConnectorEndPointCache;
82 private final DirectTunnelUtils directTunnelUtils;
83 private final ConcurrentMap<String, NodeConnectorInfo> meshedMap = new ConcurrentHashMap<>();
85 public TunnelInventoryStateListener(final DataBroker dataBroker,
86 final JobCoordinator coordinator,
87 final TunnelStateCache tunnelStateCache,
88 final DpnTepStateCache dpnTepStateCache,
89 final DPNTEPsInfoCache dpntePsInfoCache,
90 final UnprocessedNodeConnectorCache unprocessedNCCache,
91 final UnprocessedNodeConnectorEndPointCache
92 unprocessedNodeConnectorEndPointCache,
93 final DirectTunnelUtils directTunnelUtils) {
94 super(dataBroker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class).child(Node.class)
95 .child(NodeConnector.class).augmentation(FlowCapableNodeConnector.class));
96 this.coordinator = coordinator;
97 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
98 this.tunnelStateCache = tunnelStateCache;
99 this.dpnTepStateCache = dpnTepStateCache;
100 this.dpntePsInfoCache = dpntePsInfoCache;
101 this.unprocessedNCCache = unprocessedNCCache;
102 this.unprocessedNodeConnectorEndPointCache = unprocessedNodeConnectorEndPointCache;
103 this.directTunnelUtils = directTunnelUtils;
108 public void remove(@NonNull InstanceIdentifier<FlowCapableNodeConnector> key,
109 @NonNull FlowCapableNodeConnector flowCapableNodeConnector) {
110 String portName = flowCapableNodeConnector.getName();
111 LOG.debug("InterfaceInventoryState Remove for {}", portName);
112 EVENT_LOGGER.debug("ITM-TunnelInventoryState,REMOVE DTCN received for {}",
113 flowCapableNodeConnector.getName());
114 // ITM Direct Tunnels Return if its not tunnel port and if its not Internal
115 if (!DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName) && !portName.startsWith("of")) {
116 LOG.debug("Node Connector Remove - {} Interface is not a tunnel I/f, so no-op", portName);
120 if (DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName)
121 && !tunnelStateCache.isInternalBasedOnState(portName)) {
122 LOG.debug("Node Connector Remove {} Interface is not a internal tunnel I/f, so no-op", portName);
125 } catch (ReadFailedException e) {
126 LOG.error("Tunnel {} is not present in operational DS ", portName);
130 if (!directTunnelUtils.isEntityOwner()) {
133 LOG.debug("Received NodeConnector Remove Event: {}, {}", key, flowCapableNodeConnector);
134 NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
135 remove(nodeConnectorId, flowCapableNodeConnector, portName);
138 private void remove(NodeConnectorId nodeConnectorId,
139 FlowCapableNodeConnector fcNodeConnectorNew, String portName) {
140 LOG.debug("TunnelInventoryState REMOVE for {}", portName);
141 LOG.debug("InterfaceInventoryState REMOVE for {}", portName);
142 EVENT_LOGGER.debug("ITM-TunnelInventoryState Entity Owner, REMOVE {} {}", nodeConnectorId.getValue(),
144 TunnelInterfaceStateRemoveWorker portStateRemoveWorker = new TunnelInterfaceStateRemoveWorker(nodeConnectorId,
145 fcNodeConnectorNew, portName);
146 coordinator.enqueueJob(portName, portStateRemoveWorker, ITMConstants.JOB_MAX_RETRIES);
150 public void update(@NonNull InstanceIdentifier<FlowCapableNodeConnector> key,
151 @NonNull FlowCapableNodeConnector fcNodeConnectorOld,
152 @NonNull FlowCapableNodeConnector fcNodeConnectorNew) {
153 EVENT_LOGGER.debug("ITM-TunnelInventoryState,UPDATE DTCN received for {}", fcNodeConnectorOld.getName());
154 String portName = fcNodeConnectorNew.getName();
155 if (!DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName)) {
156 LOG.debug("Node Connector Update - {} Interface is not a tunnel I/f, so no-op", portName);
158 } else if (!dpnTepStateCache.isInternal(portName)) {
159 LOG.debug("Node Connector Update {} Interface is not a internal tunnel I/f, so no-op", portName);
163 if (fcNodeConnectorNew.getReason() == PortReason.Delete || !directTunnelUtils.isEntityOwner()) {
166 LOG.debug("Received NodeConnector Update Event: {}, {}, {}", key, fcNodeConnectorOld, fcNodeConnectorNew);
168 TunnelInterfaceStateUpdateWorker portStateUpdateWorker =
169 new TunnelInterfaceStateUpdateWorker(key, fcNodeConnectorOld, fcNodeConnectorNew, portName);
170 EVENT_LOGGER.debug("ITM-TunnelInventoryState Entity Owner, UPDATE {} {} Reason {}",
171 fcNodeConnectorNew.getName(), portName, fcNodeConnectorNew.getReason());
172 coordinator.enqueueJob(portName, portStateUpdateWorker, ITMConstants.JOB_MAX_RETRIES);
176 public void add(@NonNull InstanceIdentifier<FlowCapableNodeConnector> key,
177 @NonNull FlowCapableNodeConnector fcNodeConnectorNew) {
178 LOG.info("Received NodeConnector Add Event: {}, {}", key, fcNodeConnectorNew);
179 EVENT_LOGGER.debug("ITM-TunnelInventoryState,ADD DTCN received for {}", fcNodeConnectorNew.getName());
180 String portName = fcNodeConnectorNew.getName();
182 // Return if its not tunnel port and if its not Internal
183 if (!DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName) && !portName.startsWith("of")) {
184 LOG.debug("Node Connector Add {} Interface is not a tunnel I/f, so no-op", portName);
188 if (!directTunnelUtils.isEntityOwner()) {
189 LOG.debug("Not an entity owner.");
193 NodeConnectorInfo nodeConnectorInfo =
194 new NodeConnectorInfoBuilder().setNodeConnectorId(key).setNodeConnector(fcNodeConnectorNew).build();
196 if (portName.startsWith("of")) {
197 NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class))
199 String srcDpn = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId).toString();
201 if (meshedMap.isEmpty()) {
202 meshedMap.put(srcDpn, nodeConnectorInfo);
205 for (Map.Entry<String, NodeConnectorInfo> entry : meshedMap.entrySet()) {
206 DpnTepInterfaceInfo infInfoForward = dpnTepStateCache.getDpnTepInterface(Uint64.valueOf(srcDpn),
207 Uint64.valueOf(entry.getKey()));
208 if (infInfoForward == null) {
209 unprocessedNCCache.add(srcDpn + ":" + entry.getKey(),
210 new TunnelStateInfoBuilder().setNodeConnectorInfo(nodeConnectorInfo).build());
212 addTunnelState(nodeConnectorInfo, infInfoForward.getTunnelName());
215 DpnTepInterfaceInfo infInfoReverse = dpnTepStateCache.getDpnTepInterface(
216 Uint64.valueOf(entry.getKey()), Uint64.valueOf(srcDpn));
218 if (infInfoReverse == null) {
219 unprocessedNCCache.add(entry.getKey() + ":" + srcDpn,
220 new TunnelStateInfoBuilder().setNodeConnectorInfo(entry.getValue()).build());
222 addTunnelState(entry.getValue(), infInfoReverse.getTunnelName());
226 meshedMap.put(srcDpn, nodeConnectorInfo);
228 addTunnelState(nodeConnectorInfo, portName);
232 private void addTunnelState(NodeConnectorInfo nodeConnectorInfo, String portName) {
234 TunnelStateInfo tunnelStateInfo = null;
235 TunnelEndPointInfo tunnelEndPtInfo = null;
236 try (Acquired lock = directTunnelUtils.lockTunnel(portName)) {
237 if (!dpnTepStateCache.isConfigAvailable(portName)) {
238 // Park the notification
239 LOG.debug("Unable to process the NodeConnector ADD event for {} as Config not available."
240 + "Hence parking it", portName);
241 unprocessedNCCache.add(portName,
242 new TunnelStateInfoBuilder().setNodeConnectorInfo(nodeConnectorInfo).build());
244 } else if (!dpnTepStateCache.isInternal(portName)) {
245 LOG.debug("{} Interface is not a internal tunnel I/f, so no-op", portName);
250 // Check if tunnels State has an entry for this interface.
251 // If so, then this Inventory Add is due to compute re-connection. Then, ONLY update the state
252 // to UP as previously the compute would have disconnected and so the state will be UNKNOWN.
254 long portNo = tunnelStateCache.getNodeConnectorIdFromInterface(portName);
255 if (portNo != ITMConstants.INVALID_PORT_NO) {
256 coordinator.enqueueJob(portName,
257 new TunnelInterfaceNodeReconnectWorker(portName), ITMConstants.JOB_MAX_RETRIES);
260 } catch (ReadFailedException e) {
261 LOG.error("Exception occurred in reconnect for portName {}, reason: {}.",
262 portName, e.getMessage());
265 if (DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName) && dpnTepStateCache.isInternal(portName)) {
266 tunnelEndPtInfo = dpnTepStateCache.getTunnelEndPointInfoFromCache(portName);
267 TunnelStateInfoBuilder builder = new TunnelStateInfoBuilder().setNodeConnectorInfo(nodeConnectorInfo);
268 dpntePsInfoCache.getDPNTepFromDPNId(Uint64.valueOf(tunnelEndPtInfo.getSrcEndPointInfo()))
269 .ifPresent(builder::setSrcDpnTepsInfo);
270 dpntePsInfoCache.getDPNTepFromDPNId(Uint64.valueOf(tunnelEndPtInfo.getDstEndPointInfo()))
271 .ifPresent(builder::setDstDpnTepsInfo);
272 tunnelStateInfo = builder.setTunnelEndPointInfo(tunnelEndPtInfo)
273 .setDpnTepInterfaceInfo(dpnTepStateCache.getTunnelFromCache(portName)).build();
275 if (tunnelStateInfo.getSrcDpnTepsInfo() == null) {
276 try (Acquired lock = directTunnelUtils.lockTunnel(tunnelEndPtInfo.getSrcEndPointInfo())) {
277 LOG.debug("Source DPNTepsInfo is null for tunnel {}. Hence Parking with key {}",
278 portName, tunnelEndPtInfo.getSrcEndPointInfo());
279 unprocessedNodeConnectorEndPointCache.add(tunnelEndPtInfo.getSrcEndPointInfo(), tunnelStateInfo);
282 if (tunnelStateInfo.getDstDpnTepsInfo() == null) {
283 try (Acquired lock = directTunnelUtils.lockTunnel(tunnelEndPtInfo.getDstEndPointInfo())) {
284 LOG.debug("Destination DPNTepsInfo is null for tunnel {}. Hence Parking with key {}",
285 portName, tunnelEndPtInfo.getDstEndPointInfo());
286 unprocessedNodeConnectorEndPointCache.add(tunnelEndPtInfo.getDstEndPointInfo(), tunnelStateInfo);
291 if (tunnelEndPtInfo != null && tunnelStateInfo.getSrcDpnTepsInfo() != null
292 && tunnelStateInfo.getDstDpnTepsInfo() != null && directTunnelUtils.isEntityOwner()) {
293 EVENT_LOGGER.debug("ITM-TunnelInventoryState Entity Owner,ADD {}", portName);
294 coordinator.enqueueJob(portName,
295 new TunnelStateAddWorkerForNodeConnector(new TunnelStateAddWorker(directTunnelUtils, txRunner),
296 tunnelStateInfo), ITMConstants.JOB_MAX_RETRIES);
300 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
301 justification = "https://github.com/spotbugs/spotbugs/issues/811")
302 private List<? extends ListenableFuture<?>> updateState(String interfaceName,
303 FlowCapableNodeConnector flowCapableNodeConnectorNew,
304 FlowCapableNodeConnector flowCapableNodeConnectorOld) {
305 LOG.debug("Updating interface state for port: {}", interfaceName);
307 // Hardware updates can be ignored
308 Interface.OperStatus operStatusNew = getOpState(flowCapableNodeConnectorNew);
309 MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress();
311 Interface.OperStatus operStatusOld = getOpState(flowCapableNodeConnectorOld);
312 MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress();
314 boolean opstateModified = false;
315 boolean hardwareAddressModified = false;
316 if (!operStatusNew.equals(operStatusOld)) {
317 opstateModified = true;
319 if (!Objects.equals(macAddressNew, macAddressOld)) {
320 hardwareAddressModified = true;
323 if (!opstateModified && !hardwareAddressModified) {
324 LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
325 return Collections.emptyList();
328 DpnTepInterfaceInfo dpnTepInfo = dpnTepStateCache.getTunnelFromCache(interfaceName);
330 // For monitoring enabled tunnels, skip opstate updation
331 if (!modifyTunnelOpState(dpnTepInfo, opstateModified)) {
332 LOG.debug("skipping Tunnel-state update for monitoring enabled tunnel interface {}", interfaceName);
333 opstateModified = false;
336 if (!opstateModified && !hardwareAddressModified) {
337 LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
338 return Collections.emptyList();
340 if (opstateModified) {
341 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
342 // modify the attributes in interface operational DS
343 handleInterfaceStateUpdates(tx, dpnTepInfo, true, interfaceName, flowCapableNodeConnectorNew.getName(),
345 EVENT_LOGGER.debug("ITM-TunnelInventoryState, UPDATE {} CHGED {} completed", interfaceName,
346 operStatusNew.getName());
349 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
350 // modify the attributes in interface operational DS
351 handleInterfaceStateUpdates(tx, dpnTepInfo, false, interfaceName,
352 flowCapableNodeConnectorNew.getName(), operStatusNew);
353 EVENT_LOGGER.debug("ITM-TunnelInventoryState, UPDATE {} completed", interfaceName);
358 private void updateInterfaceStateOnNodeRemove(TypedWriteTransaction<Operational> tx, String interfaceName,
359 FlowCapableNodeConnector flowCapableNodeConnector) {
360 LOG.debug("Updating interface oper-status to UNKNOWN for : {}", interfaceName);
361 DpnTepInterfaceInfo dpnTepInfo = dpnTepStateCache.getTunnelFromCache(interfaceName);
363 handleInterfaceStateUpdates(tx, dpnTepInfo, true, interfaceName, flowCapableNodeConnector.getName(),
364 Interface.OperStatus.Unknown);
367 private Interface.OperStatus getOpState(FlowCapableNodeConnector flowCapableNodeConnector) {
368 return flowCapableNodeConnector.getState().isLive()
369 && !flowCapableNodeConnector.getConfiguration().isPORTDOWN()
370 ? Interface.OperStatus.Up : Interface.OperStatus.Down;
373 private void handleInterfaceStateUpdates(TypedWriteTransaction<Operational> tx,
374 DpnTepInterfaceInfo dpnTepInfo,
375 boolean opStateModified, String interfaceName, String portName,
376 Interface.OperStatus opState) {
377 if (dpnTepInfo == null && !portName.startsWith("of") && !interfaceName.equals(portName)) {
380 LOG.debug("updating interface state entry for {}", interfaceName);
381 InstanceIdentifier<StateTunnelList> tnlStateId = ItmUtils.buildStateTunnelListId(
382 new StateTunnelListKey(interfaceName));
383 StateTunnelListBuilder stateTnlBuilder = new StateTunnelListBuilder();
384 stateTnlBuilder.withKey(new StateTunnelListKey(interfaceName));
385 if (modifyOpState(dpnTepInfo, opStateModified)) {
386 LOG.debug("updating interface oper status as {} for {}", opState.name(), interfaceName);
387 boolean tunnelState = opState.equals(Interface.OperStatus.Up);
388 stateTnlBuilder.setTunnelState(tunnelState);
389 stateTnlBuilder.setOperState(DirectTunnelUtils.convertInterfaceToTunnelOperState(opState));
391 tx.merge(tnlStateId, stateTnlBuilder.build());
394 private boolean modifyOpState(DpnTepInterfaceInfo dpnTepInterfaceInfo, boolean opStateModified) {
395 return opStateModified && dpnTepInterfaceInfo != null;
398 private boolean modifyTunnelOpState(DpnTepInterfaceInfo dpnTepInterfaceInfo, boolean opStateModified) {
399 return !dpnTepInterfaceInfo.isMonitoringEnabled() && modifyOpState(dpnTepInterfaceInfo, opStateModified);
402 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
403 justification = "https://github.com/spotbugs/spotbugs/issues/811")
404 private List<? extends ListenableFuture<?>> removeInterfaceStateConfiguration(NodeConnectorId nodeConnectorId,
405 String interfaceName,
406 FlowCapableNodeConnector
407 flowCapableNodeConnector) {
410 List<ListenableFuture<?>> futures = new ArrayList<>();
411 Uint64 dpId = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId);
412 // In a genuine port delete scenario, the reason will be there in the incoming event, for all remaining
413 // cases treat the event as DPN disconnect, if old and new ports are same. Else, this is a VM migration
414 // scenario, and should be treated as port removal.
415 if (flowCapableNodeConnector.getReason() != PortReason.Delete) {
416 //Remove event is because of connection lost between controller and switch, or switch shutdown.
417 // Hence, dont remove the interface but set the status as "unknown"
419 if (interfaceName.startsWith("of")) {
420 LOG.debug("Received remove state for dpid {}", dpId.intValue());
421 for (Map.Entry<String, NodeConnectorInfo> entry : meshedMap.entrySet()) {
422 if (!dpId.toString().equals(entry.getKey())) {
423 String fwdTunnel = dpnTepStateCache.getDpnTepInterface(dpId, Uint64.valueOf(entry.getKey()))
425 LOG.debug("Fwd Tunnel name for {} : {} is {}", dpId.intValue(), entry.getKey(), fwdTunnel);
426 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
427 tx -> updateInterfaceStateOnNodeRemove(tx, fwdTunnel, flowCapableNodeConnector)));
428 String bwdTunnel = dpnTepStateCache.getDpnTepInterface(Uint64.valueOf(entry.getKey()), dpId)
430 LOG.debug("Bwd Tunnel name for {} : {} is {}", entry.getKey(), dpId.intValue(), bwdTunnel);
431 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
432 tx -> updateInterfaceStateOnNodeRemove(tx, bwdTunnel,
433 entry.getValue().getNodeConnector())));
437 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
438 tx -> updateInterfaceStateOnNodeRemove(tx, interfaceName, flowCapableNodeConnector)));
441 LOG.debug("removing interface state for interface: {}", interfaceName);
442 EVENT_LOGGER.debug("ITM-TunnelInventoryState,REMOVE Table 0 flow for {} completed", interfaceName);
443 // removing interfaces are already done in delete worker
444 meshedMap.remove(dpId.toString());
449 private class TunnelInterfaceStateUpdateWorker implements Callable<List<? extends ListenableFuture<?>>> {
450 private final InstanceIdentifier<FlowCapableNodeConnector> key;
451 private final FlowCapableNodeConnector fcNodeConnectorOld;
452 private final FlowCapableNodeConnector fcNodeConnectorNew;
453 private final String interfaceName;
455 TunnelInterfaceStateUpdateWorker(InstanceIdentifier<FlowCapableNodeConnector> key,
456 FlowCapableNodeConnector fcNodeConnectorOld,
457 FlowCapableNodeConnector fcNodeConnectorNew, String portName) {
459 this.fcNodeConnectorOld = fcNodeConnectorOld;
460 this.fcNodeConnectorNew = fcNodeConnectorNew;
461 this.interfaceName = portName;
465 public List<? extends ListenableFuture<?>> call() {
466 // If another renderer(for eg : OVS) needs to be supported, check can be performed here
467 // to call the respective helpers.
468 return updateState(interfaceName, fcNodeConnectorNew, fcNodeConnectorOld);
472 public String toString() {
473 return "TunnelInterfaceStateUpdateWorker{key=" + key + ", fcNodeConnectorOld=" + fcNodeConnectorOld
474 + ", fcNodeConnectorNew=" + fcNodeConnectorNew + ", interfaceName='" + interfaceName + '\'' + '}';
478 private class TunnelInterfaceStateRemoveWorker implements Callable<List<? extends ListenableFuture<?>>> {
479 private final NodeConnectorId nodeConnectorId;
480 private final FlowCapableNodeConnector flowCapableNodeConnector;
481 private final String interfaceName;
483 TunnelInterfaceStateRemoveWorker(NodeConnectorId nodeConnectorId,
484 FlowCapableNodeConnector flowCapableNodeConnector,
485 String interfaceName) {
486 this.nodeConnectorId = nodeConnectorId;
487 this.flowCapableNodeConnector = flowCapableNodeConnector;
488 this.interfaceName = interfaceName;
492 public List<? extends ListenableFuture<?>> call() {
493 // If another renderer(for eg : OVS) needs to be supported, check can be performed here
494 // to call the respective helpers.
495 return removeInterfaceStateConfiguration(nodeConnectorId, interfaceName, flowCapableNodeConnector);
499 public String toString() {
500 return "TunnelInterfaceStateRemoveWorker{nodeConnectorId=" + nodeConnectorId + ", fcNodeConnector"
501 + flowCapableNodeConnector + ", interfaceName='" + interfaceName + '\'' + '}';
505 private class TunnelInterfaceNodeReconnectWorker implements Callable<List<? extends ListenableFuture<?>>> {
506 private final String tunnelName;
508 TunnelInterfaceNodeReconnectWorker(String tunnelName) {
509 this.tunnelName = tunnelName;
513 public List<? extends ListenableFuture<?>> call() throws Exception {
514 // If another renderer(for eg : OVS) needs to be supported, check can be performed here
515 // to call the respective helpers.
516 EVENT_LOGGER.debug("ITM-TunnelInventoryState, Compute Re-connected, ADD received for {} ", tunnelName);
518 return handleInterfaceStateOnReconnect(tunnelName);
522 public String toString() {
523 return "TunnelInterfaceNodeReconnectWorker{tunnelName=" + tunnelName + '\'' + '}';
527 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
528 justification = "https://github.com/spotbugs/spotbugs/issues/811")
529 private List<? extends ListenableFuture<?>> handleInterfaceStateOnReconnect(String interfaceName) {
530 List<ListenableFuture<?>> futures = new ArrayList<>();
532 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
533 DpnTepInterfaceInfo dpnTepInfo = dpnTepStateCache.getTunnelFromCache(interfaceName);
535 handleInterfaceStateUpdates(tx, dpnTepInfo, true, interfaceName, interfaceName,
536 Interface.OperStatus.Up);