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.genius.infra.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.infra.Datastore.Operational;
24 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
25 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
26 import org.opendaylight.genius.infra.TypedWriteTransaction;
27 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
28 import org.opendaylight.genius.itm.cache.DpnTepStateCache;
29 import org.opendaylight.genius.itm.cache.TunnelStateCache;
30 import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorCache;
31 import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorEndPointCache;
32 import org.opendaylight.genius.itm.globals.ITMConstants;
33 import org.opendaylight.genius.itm.impl.ItmUtils;
34 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
35 import org.opendaylight.genius.itm.itmdirecttunnels.workers.TunnelStateAddWorker;
36 import org.opendaylight.genius.itm.itmdirecttunnels.workers.TunnelStateAddWorkerForNodeConnector;
37 import org.opendaylight.genius.itm.utils.DpnTepInterfaceInfo;
38 import org.opendaylight.genius.itm.utils.NodeConnectorInfo;
39 import org.opendaylight.genius.itm.utils.NodeConnectorInfoBuilder;
40 import org.opendaylight.genius.itm.utils.TunnelEndPointInfo;
41 import org.opendaylight.genius.itm.utils.TunnelStateInfo;
42 import org.opendaylight.genius.itm.utils.TunnelStateInfoBuilder;
43 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
44 import org.opendaylight.infrautils.utils.concurrent.NamedSimpleReentrantLock.Acquired;
45 import org.opendaylight.mdsal.binding.api.DataBroker;
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);
162 if (fcNodeConnectorNew.getReason() == PortReason.Delete || !directTunnelUtils.isEntityOwner()) {
165 LOG.debug("Received NodeConnector Update Event: {}, {}, {}", key, fcNodeConnectorOld, fcNodeConnectorNew);
167 TunnelInterfaceStateUpdateWorker portStateUpdateWorker =
168 new TunnelInterfaceStateUpdateWorker(key, fcNodeConnectorOld, fcNodeConnectorNew, portName);
169 EVENT_LOGGER.debug("ITM-TunnelInventoryState Entity Owner, UPDATE {} {} Reason {}",
170 fcNodeConnectorNew.getName(), portName, fcNodeConnectorNew.getReason());
171 coordinator.enqueueJob(portName, portStateUpdateWorker, ITMConstants.JOB_MAX_RETRIES);
175 public void add(@NonNull InstanceIdentifier<FlowCapableNodeConnector> key,
176 @NonNull FlowCapableNodeConnector fcNodeConnectorNew) {
177 LOG.info("Received NodeConnector Add Event: {}, {}", key, fcNodeConnectorNew);
178 EVENT_LOGGER.debug("ITM-TunnelInventoryState,ADD DTCN received for {}", fcNodeConnectorNew.getName());
179 String portName = fcNodeConnectorNew.getName();
180 // Return if its not tunnel port and if its not Internal
181 if (!DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName) && !portName.startsWith("of")) {
182 LOG.debug("Node Connector Add {} Interface is not a tunnel I/f, so no-op", portName);
186 NodeConnectorInfo nodeConnectorInfo =
187 new NodeConnectorInfoBuilder().setNodeConnectorId(key).setNodeConnector(fcNodeConnectorNew).build();
189 if (portName.startsWith("of")) {
190 NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class))
192 String srcDpn = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId).toString();
194 if (meshedMap.isEmpty()) {
195 meshedMap.put(srcDpn, nodeConnectorInfo);
198 for (Map.Entry<String, NodeConnectorInfo> entry : meshedMap.entrySet()) {
199 DpnTepInterfaceInfo infInfoForward = dpnTepStateCache.getDpnTepInterface(Uint64.valueOf(srcDpn),
200 Uint64.valueOf(entry.getKey()));
201 if (infInfoForward == null) {
202 unprocessedNCCache.add(srcDpn + ":" + entry.getKey(),
203 new TunnelStateInfoBuilder().setNodeConnectorInfo(nodeConnectorInfo).build());
205 addTunnelState(nodeConnectorInfo, infInfoForward.getTunnelName());
208 DpnTepInterfaceInfo infInfoReverse = dpnTepStateCache.getDpnTepInterface(
209 Uint64.valueOf(entry.getKey()), Uint64.valueOf(srcDpn));
211 if (infInfoReverse == null) {
212 unprocessedNCCache.add(entry.getKey() + ":" + srcDpn,
213 new TunnelStateInfoBuilder().setNodeConnectorInfo(entry.getValue()).build());
215 addTunnelState(entry.getValue(), infInfoReverse.getTunnelName());
219 meshedMap.put(srcDpn, nodeConnectorInfo);
221 addTunnelState(nodeConnectorInfo, portName);
226 private void addTunnelState(NodeConnectorInfo nodeConnectorInfo, String portName) {
228 TunnelStateInfo tunnelStateInfo = null;
229 TunnelEndPointInfo tunnelEndPtInfo = null;
230 try (Acquired lock = directTunnelUtils.lockTunnel(portName)) {
231 if (!dpnTepStateCache.isConfigAvailable(portName)) {
232 // Park the notification
233 LOG.debug("Unable to process the NodeConnector ADD event for {} as Config not available."
234 + "Hence parking it", portName);
235 unprocessedNCCache.add(portName,
236 new TunnelStateInfoBuilder().setNodeConnectorInfo(nodeConnectorInfo).build());
238 } else if (!dpnTepStateCache.isInternal(portName)) {
239 LOG.debug("{} Interface is not a internal tunnel I/f, so no-op", portName);
244 if (DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName) && dpnTepStateCache.isInternal(portName)) {
245 tunnelEndPtInfo = dpnTepStateCache.getTunnelEndPointInfoFromCache(portName);
246 TunnelStateInfoBuilder builder = new TunnelStateInfoBuilder().setNodeConnectorInfo(nodeConnectorInfo);
247 dpntePsInfoCache.getDPNTepFromDPNId(Uint64.valueOf(tunnelEndPtInfo.getSrcEndPointInfo()))
248 .ifPresent(builder::setSrcDpnTepsInfo);
249 dpntePsInfoCache.getDPNTepFromDPNId(Uint64.valueOf(tunnelEndPtInfo.getDstEndPointInfo()))
250 .ifPresent(builder::setDstDpnTepsInfo);
251 tunnelStateInfo = builder.setTunnelEndPointInfo(tunnelEndPtInfo)
252 .setDpnTepInterfaceInfo(dpnTepStateCache.getTunnelFromCache(portName)).build();
254 if (tunnelStateInfo.getSrcDpnTepsInfo() == null) {
255 try (Acquired lock = directTunnelUtils.lockTunnel(tunnelEndPtInfo.getSrcEndPointInfo())) {
256 LOG.debug("Source DPNTepsInfo is null for tunnel {}. Hence Parking with key {}",
257 portName, tunnelEndPtInfo.getSrcEndPointInfo());
258 unprocessedNodeConnectorEndPointCache.add(tunnelEndPtInfo.getSrcEndPointInfo(), tunnelStateInfo);
261 if (tunnelStateInfo.getDstDpnTepsInfo() == null) {
262 try (Acquired lock = directTunnelUtils.lockTunnel(tunnelEndPtInfo.getDstEndPointInfo())) {
263 LOG.debug("Destination DPNTepsInfo is null for tunnel {}. Hence Parking with key {}",
264 portName, tunnelEndPtInfo.getDstEndPointInfo());
265 unprocessedNodeConnectorEndPointCache.add(tunnelEndPtInfo.getDstEndPointInfo(), tunnelStateInfo);
270 if (tunnelEndPtInfo != null && tunnelStateInfo.getSrcDpnTepsInfo() != null
271 && tunnelStateInfo.getDstDpnTepsInfo() != null && directTunnelUtils.isEntityOwner()) {
272 EVENT_LOGGER.debug("ITM-TunnelInventoryState Entity Owner,ADD {}", portName);
273 coordinator.enqueueJob(portName,
274 new TunnelStateAddWorkerForNodeConnector(new TunnelStateAddWorker(directTunnelUtils, txRunner),
275 tunnelStateInfo), ITMConstants.JOB_MAX_RETRIES);
279 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
280 justification = "https://github.com/spotbugs/spotbugs/issues/811")
281 private List<ListenableFuture<Void>> updateState(String interfaceName,
282 FlowCapableNodeConnector flowCapableNodeConnectorNew,
283 FlowCapableNodeConnector flowCapableNodeConnectorOld) {
284 LOG.debug("Updating interface state for port: {}", interfaceName);
286 // Hardware updates can be ignored
287 Interface.OperStatus operStatusNew = getOpState(flowCapableNodeConnectorNew);
288 MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress();
290 Interface.OperStatus operStatusOld = getOpState(flowCapableNodeConnectorOld);
291 MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress();
293 boolean opstateModified = false;
294 boolean hardwareAddressModified = false;
295 if (!operStatusNew.equals(operStatusOld)) {
296 opstateModified = true;
298 if (!Objects.equals(macAddressNew, macAddressOld)) {
299 hardwareAddressModified = true;
302 if (!opstateModified && !hardwareAddressModified) {
303 LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
304 return Collections.emptyList();
307 DpnTepInterfaceInfo dpnTepInfo = dpnTepStateCache.getTunnelFromCache(interfaceName);
309 // For monitoring enabled tunnels, skip opstate updation
310 if (!modifyTunnelOpState(dpnTepInfo, opstateModified)) {
311 LOG.debug("skipping Tunnel-state update for monitoring enabled tunnel interface {}", interfaceName);
312 opstateModified = false;
315 if (!opstateModified && !hardwareAddressModified) {
316 LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
317 return Collections.emptyList();
319 if (opstateModified) {
320 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
321 // modify the attributes in interface operational DS
322 handleInterfaceStateUpdates(tx, dpnTepInfo, true, interfaceName, flowCapableNodeConnectorNew.getName(),
324 EVENT_LOGGER.debug("ITM-TunnelInventoryState, UPDATE {} CHGED {} completed", interfaceName,
325 operStatusNew.getName());
328 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
329 // modify the attributes in interface operational DS
330 handleInterfaceStateUpdates(tx, dpnTepInfo, false, interfaceName,
331 flowCapableNodeConnectorNew.getName(), operStatusNew);
332 EVENT_LOGGER.debug("ITM-TunnelInventoryState, UPDATE {} completed", interfaceName);
337 private void updateInterfaceStateOnNodeRemove(TypedWriteTransaction<Operational> tx, String interfaceName,
338 FlowCapableNodeConnector flowCapableNodeConnector) {
339 LOG.debug("Updating interface oper-status to UNKNOWN for : {}", interfaceName);
340 DpnTepInterfaceInfo dpnTepInfo = dpnTepStateCache.getTunnelFromCache(interfaceName);
342 handleInterfaceStateUpdates(tx, dpnTepInfo, true, interfaceName, flowCapableNodeConnector.getName(),
343 Interface.OperStatus.Unknown);
346 private Interface.OperStatus getOpState(FlowCapableNodeConnector flowCapableNodeConnector) {
347 return flowCapableNodeConnector.getState().isLive()
348 && !flowCapableNodeConnector.getConfiguration().isPORTDOWN()
349 ? Interface.OperStatus.Up : Interface.OperStatus.Down;
352 private void handleInterfaceStateUpdates(TypedWriteTransaction<Operational> tx,
353 DpnTepInterfaceInfo dpnTepInfo,
354 boolean opStateModified, String interfaceName, String portName,
355 Interface.OperStatus opState) {
356 if (dpnTepInfo == null && !portName.startsWith("of") && !interfaceName.equals(portName)) {
359 LOG.debug("updating interface state entry for {}", interfaceName);
360 InstanceIdentifier<StateTunnelList> tnlStateId = ItmUtils.buildStateTunnelListId(
361 new StateTunnelListKey(interfaceName));
362 StateTunnelListBuilder stateTnlBuilder = new StateTunnelListBuilder();
363 stateTnlBuilder.withKey(new StateTunnelListKey(interfaceName));
364 if (modifyOpState(dpnTepInfo, opStateModified)) {
365 LOG.debug("updating interface oper status as {} for {}", opState.name(), interfaceName);
366 boolean tunnelState = opState.equals(Interface.OperStatus.Up);
367 stateTnlBuilder.setTunnelState(tunnelState);
368 stateTnlBuilder.setOperState(DirectTunnelUtils.convertInterfaceToTunnelOperState(opState));
370 tx.merge(tnlStateId, stateTnlBuilder.build());
373 private boolean modifyOpState(DpnTepInterfaceInfo dpnTepInterfaceInfo, boolean opStateModified) {
374 return opStateModified && dpnTepInterfaceInfo != null;
377 private boolean modifyTunnelOpState(DpnTepInterfaceInfo dpnTepInterfaceInfo, boolean opStateModified) {
378 return !dpnTepInterfaceInfo.isMonitoringEnabled() && modifyOpState(dpnTepInterfaceInfo, opStateModified);
381 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
382 justification = "https://github.com/spotbugs/spotbugs/issues/811")
383 private List<ListenableFuture<Void>> removeInterfaceStateConfiguration(NodeConnectorId nodeConnectorId,
384 String interfaceName,
385 FlowCapableNodeConnector
386 flowCapableNodeConnector) {
389 List<ListenableFuture<Void>> futures = new ArrayList<>();
390 Uint64 dpId = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId);
391 // In a genuine port delete scenario, the reason will be there in the incoming event, for all remaining
392 // cases treat the event as DPN disconnect, if old and new ports are same. Else, this is a VM migration
393 // scenario, and should be treated as port removal.
394 if (flowCapableNodeConnector.getReason() != PortReason.Delete) {
395 //Remove event is because of connection lost between controller and switch, or switch shutdown.
396 // Hence, dont remove the interface but set the status as "unknown"
398 if (interfaceName.startsWith("of")) {
399 LOG.debug("Received remove state for dpid {}", dpId.intValue());
400 for (Map.Entry<String, NodeConnectorInfo> entry : meshedMap.entrySet()) {
401 if (!dpId.toString().equals(entry.getKey())) {
402 String fwdTunnel = dpnTepStateCache.getDpnTepInterface(dpId, Uint64.valueOf(entry.getKey()))
404 LOG.debug("Fwd Tunnel name for {} : {} is {}", dpId.intValue(), entry.getKey(), fwdTunnel);
405 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
406 tx -> updateInterfaceStateOnNodeRemove(tx, fwdTunnel, flowCapableNodeConnector)));
407 String bwdTunnel = dpnTepStateCache.getDpnTepInterface(Uint64.valueOf(entry.getKey()), dpId)
409 LOG.debug("Bwd Tunnel name for {} : {} is {}", entry.getKey(), dpId.intValue(), bwdTunnel);
410 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
411 tx -> updateInterfaceStateOnNodeRemove(tx, bwdTunnel,
412 entry.getValue().getNodeConnector())));
416 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
417 tx -> updateInterfaceStateOnNodeRemove(tx, interfaceName, flowCapableNodeConnector)));
420 LOG.debug("removing interface state for interface: {}", interfaceName);
421 EVENT_LOGGER.debug("ITM-TunnelInventoryState,REMOVE Table 0 flow for {} completed", interfaceName);
422 // removing interfaces are already done in delete worker
423 meshedMap.remove(dpId.toString());
428 private class TunnelInterfaceStateUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
429 private final InstanceIdentifier<FlowCapableNodeConnector> key;
430 private final FlowCapableNodeConnector fcNodeConnectorOld;
431 private final FlowCapableNodeConnector fcNodeConnectorNew;
432 private final String interfaceName;
434 TunnelInterfaceStateUpdateWorker(InstanceIdentifier<FlowCapableNodeConnector> key,
435 FlowCapableNodeConnector fcNodeConnectorOld,
436 FlowCapableNodeConnector fcNodeConnectorNew, String portName) {
438 this.fcNodeConnectorOld = fcNodeConnectorOld;
439 this.fcNodeConnectorNew = fcNodeConnectorNew;
440 this.interfaceName = portName;
444 public List<ListenableFuture<Void>> call() {
445 // If another renderer(for eg : OVS) needs to be supported, check can be performed here
446 // to call the respective helpers.
447 return updateState(interfaceName, fcNodeConnectorNew, fcNodeConnectorOld);
451 public String toString() {
452 return "TunnelInterfaceStateUpdateWorker{key=" + key + ", fcNodeConnectorOld=" + fcNodeConnectorOld
453 + ", fcNodeConnectorNew=" + fcNodeConnectorNew + ", interfaceName='" + interfaceName + '\'' + '}';
457 private class TunnelInterfaceStateRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
458 private final NodeConnectorId nodeConnectorId;
459 private final FlowCapableNodeConnector flowCapableNodeConnector;
460 private final String interfaceName;
462 TunnelInterfaceStateRemoveWorker(NodeConnectorId nodeConnectorId,
463 FlowCapableNodeConnector flowCapableNodeConnector,
464 String interfaceName) {
465 this.nodeConnectorId = nodeConnectorId;
466 this.flowCapableNodeConnector = flowCapableNodeConnector;
467 this.interfaceName = interfaceName;
471 public List<ListenableFuture<Void>> call() {
472 // If another renderer(for eg : OVS) needs to be supported, check can be performed here
473 // to call the respective helpers.
474 return removeInterfaceStateConfiguration(nodeConnectorId, interfaceName, flowCapableNodeConnector);
478 public String toString() {
479 return "TunnelInterfaceStateRemoveWorker{nodeConnectorId=" + nodeConnectorId + ", fcNodeConnector"
480 + flowCapableNodeConnector + ", interfaceName='" + interfaceName + '\'' + '}';