2 * Copyright (c) 2016, 2017 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.interfacemanager.listeners;
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.util.List;
12 import java.util.concurrent.Callable;
13 import javax.inject.Inject;
14 import javax.inject.Singleton;
15 import org.apache.aries.blueprint.annotation.service.Reference;
16 import org.opendaylight.genius.interfacemanager.IfmConstants;
17 import org.opendaylight.genius.interfacemanager.InterfacemgrProvider;
18 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
19 import org.opendaylight.genius.interfacemanager.recovery.impl.InterfaceServiceRecoveryHandler;
20 import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateUpdateHelper;
21 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
22 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
23 import org.opendaylight.infrautils.utils.concurrent.Executors;
24 import org.opendaylight.mdsal.binding.api.DataBroker;
25 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
26 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
27 import org.opendaylight.serviceutils.srm.RecoverableListener;
28 import org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry;
29 import org.opendaylight.serviceutils.tools.listener.AbstractClusteredAsyncDataTreeChangeListener;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 public class TerminationPointStateListener extends
41 AbstractClusteredAsyncDataTreeChangeListener<OvsdbTerminationPointAugmentation>
42 implements RecoverableListener {
43 private static final Logger LOG = LoggerFactory.getLogger(TerminationPointStateListener.class);
44 private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
46 private final InterfacemgrProvider interfaceMgrProvider;
47 private final DataBroker dataBroker;
48 private final EntityOwnershipUtils entityOwnershipUtils;
49 private final JobCoordinator coordinator;
50 private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
51 private final OvsInterfaceTopologyStateUpdateHelper ovsInterfaceTopologyStateUpdateHelper;
54 public TerminationPointStateListener(@Reference final DataBroker dataBroker,
55 final InterfacemgrProvider interfaceMgrProvider,
56 final EntityOwnershipUtils entityOwnershipUtils,
57 @Reference final JobCoordinator coordinator,
58 final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
59 final OvsInterfaceTopologyStateUpdateHelper
60 ovsInterfaceTopologyStateUpdateHelper,
61 final InterfaceServiceRecoveryHandler interfaceServiceRecoveryHandler,
62 @Reference final ServiceRecoveryRegistry serviceRecoveryRegistry) {
63 super(dataBroker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(NetworkTopology.class)
64 .child(Topology.class).child(Node.class)
65 .child(TerminationPoint.class).augmentation(OvsdbTerminationPointAugmentation.class).build(),
66 Executors.newSingleThreadExecutor("TerminationPointStateListener", LOG));
67 this.interfaceMgrProvider = interfaceMgrProvider;
68 this.entityOwnershipUtils = entityOwnershipUtils;
69 this.coordinator = coordinator;
70 this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
71 this.ovsInterfaceTopologyStateUpdateHelper = ovsInterfaceTopologyStateUpdateHelper;
72 this.dataBroker = dataBroker;
73 serviceRecoveryRegistry.addRecoverableListener(interfaceServiceRecoveryHandler.buildServiceRegistryKey(),
78 public void registerListener() {
83 public void deregisterListener() {
88 public void remove(InstanceIdentifier<OvsdbTerminationPointAugmentation> identifier,
89 OvsdbTerminationPointAugmentation tpOld) {
90 // No ItmDirectTunnels or Internal Tunnel checking is done here as this DTCN only results in removal
91 // of interface entry from BFD internal cache. For internal tunnels when ItmDirectTunnel is enabled,
92 // the entry won't be in cache, but ConcurrentHashMap will just ignore when key is not present.
94 LOG.debug("Received remove DataChange Notification for ovsdb termination point {}", tpOld.getName());
96 String oldInterfaceName = SouthboundUtils.getExternalInterfaceIdValue(tpOld);
97 if (oldInterfaceName == null && InterfaceManagerCommonUtils.isTunnelPort(tpOld.getName())) {
98 interfaceMgrProvider.removeTerminationPointForInterface(tpOld.getName());
99 interfaceMgrProvider.removeNodeIidForInterface(tpOld.getName());
101 interfaceMgrProvider.removeTerminationPointForInterface(oldInterfaceName);
102 interfaceMgrProvider.removeNodeIidForInterface(oldInterfaceName);
104 if (tpOld.getInterfaceBfdStatus() != null) {
105 LOG.debug("Received termination point removed notification with bfd status values {}", tpOld.getName());
106 EVENT_LOGGER.debug("IFM-TerminationPointState,REMOVE {}", tpOld.getName());
107 RendererStateRemoveWorker rendererStateRemoveWorker = new RendererStateRemoveWorker(tpOld);
108 coordinator.enqueueJob(tpOld.getName(), rendererStateRemoveWorker);
113 public void update(InstanceIdentifier<OvsdbTerminationPointAugmentation> identifier,
114 OvsdbTerminationPointAugmentation tpOld,
115 OvsdbTerminationPointAugmentation tpNew) {
116 if (interfaceMgrProvider.isItmDirectTunnelsEnabled()
117 && InterfaceManagerCommonUtils.isTunnelPort(tpNew.getName())
118 && interfaceManagerCommonUtils.getInterfaceFromConfigDS(tpNew.getName()) == null) {
119 LOG.debug("ITM Direct Tunnels is enabled, hence ignoring termination point update - "
120 + "old {}, new {} internal tunnel", tpOld.getName(), tpNew.getName());
125 LOG.debug("Received Update DataChange Notification for ovsdb termination point {}", tpNew.getName());
126 EVENT_LOGGER.debug("IFM-TerminationPointState,UPDATE {}", tpNew.getName());
127 if (org.opendaylight.genius.interfacemanager.renderer.ovs.utilities
128 .SouthboundUtils.changeInBfdMonitoringDetected(tpOld, tpNew)
129 || org.opendaylight.genius.interfacemanager.renderer.ovs.utilities
130 .SouthboundUtils.ifBfdStatusNotEqual(tpOld, tpNew)) {
131 LOG.info("Bfd Status changed for ovsdb termination point {}", tpNew.getName());
132 LOG.debug("Bfd Status changed for ovsdb termination point identifier: {}, old: {}, new: {}",
133 identifier, tpOld, tpNew);
134 RendererStateUpdateWorker rendererStateAddWorker = new RendererStateUpdateWorker(tpNew);
135 coordinator.enqueueJob(tpNew.getName(), rendererStateAddWorker, IfmConstants.JOB_MAX_RETRIES);
138 InstanceIdentifier<Node> nodeIid = identifier.firstIdentifierOf(Node.class);
139 String newInterfaceName = SouthboundUtils.getExternalInterfaceIdValue(tpNew);
140 if (newInterfaceName == null && InterfaceManagerCommonUtils.isTunnelPort(tpNew.getName())) {
141 interfaceMgrProvider.addTerminationPointForInterface(tpNew.getName(), tpNew);
142 interfaceMgrProvider.addNodeIidForInterface(tpNew.getName(), nodeIid);
144 interfaceMgrProvider.addTerminationPointForInterface(newInterfaceName, tpNew);
145 interfaceMgrProvider.addNodeIidForInterface(newInterfaceName, nodeIid);
148 // skip parent-refs updation for interfaces with external-id for tunnels
149 if (!org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils.isInterfaceTypeTunnel(
150 tpNew.getInterfaceType())) {
151 if (!entityOwnershipUtils.isEntityOwner(IfmConstants.INTERFACE_CONFIG_ENTITY,
152 IfmConstants.INTERFACE_CONFIG_ENTITY)) {
155 String dpnId = interfaceMgrProvider.getDpidForInterface(newInterfaceName, nodeIid);
156 String oldInterfaceName = SouthboundUtils.getExternalInterfaceIdValue(tpOld);
157 if (dpnId != null && newInterfaceName != null && (oldInterfaceName == null
158 || !oldInterfaceName.equals(newInterfaceName))) {
159 String parentRefName =
160 InterfaceManagerCommonUtils.getPortNameForInterface(dpnId, tpNew.getName());
161 LOG.debug("Detected update to termination point {} with external ID {}, updating parent ref "
162 + "of that interface ID to this termination point's interface-state name {}", tpNew.getName(),
163 newInterfaceName, parentRefName);
164 interfaceMgrProvider.updateInterfaceParentRef(newInterfaceName, parentRefName);
170 public void add(InstanceIdentifier<OvsdbTerminationPointAugmentation> identifier,
171 OvsdbTerminationPointAugmentation tpNew) {
172 if (interfaceMgrProvider.isItmDirectTunnelsEnabled()
173 && InterfaceManagerCommonUtils.isTunnelPort(tpNew.getName())
174 && interfaceManagerCommonUtils.getInterfaceFromConfigDS(tpNew.getName()) == null) {
175 LOG.debug("ITM Direct Tunnels is enabled, hence ignoring termination point add for"
176 + " internal tunnel {}", tpNew.getName());
179 update(identifier, null, tpNew);
182 private class RendererStateUpdateWorker implements Callable<List<? extends ListenableFuture<?>>> {
183 OvsdbTerminationPointAugmentation terminationPointNew;
185 RendererStateUpdateWorker(OvsdbTerminationPointAugmentation tpNew) {
186 this.terminationPointNew = tpNew;
190 public List<ListenableFuture<Void>> call() {
191 return ovsInterfaceTopologyStateUpdateHelper.updateTunnelState(terminationPointNew);
195 private class RendererStateRemoveWorker implements Callable<List<? extends ListenableFuture<?>>> {
196 OvsdbTerminationPointAugmentation terminationPointOld;
198 RendererStateRemoveWorker(OvsdbTerminationPointAugmentation tpNew) {
199 this.terminationPointOld = tpNew;
203 public List<ListenableFuture<Void>> call() {
204 LOG.debug("Removing bfd state from cache, if any, for {}", terminationPointOld.getName());
205 interfaceManagerCommonUtils.removeBfdStateFromCache(terminationPointOld.getName());