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