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
9 package org.opendaylight.genius.interfacemanager.listeners;
11 import javax.inject.Inject;
12 import javax.inject.Singleton;
13 import org.apache.aries.blueprint.annotation.service.Reference;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.opendaylight.genius.interfacemanager.IfmConstants;
16 import org.opendaylight.genius.interfacemanager.InterfacemgrProvider;
17 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
18 import org.opendaylight.genius.interfacemanager.recovery.impl.InterfaceServiceRecoveryHandler;
19 import org.opendaylight.genius.interfacemanager.renderer.ovs.confighelpers.OvsInterfaceConfigAddHelper;
20 import org.opendaylight.genius.interfacemanager.renderer.ovs.confighelpers.OvsInterfaceConfigRemoveHelper;
21 import org.opendaylight.genius.interfacemanager.renderer.ovs.confighelpers.OvsInterfaceConfigUpdateHelper;
22 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
23 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
24 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
25 import org.opendaylight.mdsal.binding.api.DataBroker;
26 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
27 import org.opendaylight.serviceutils.srm.RecoverableListener;
28 import org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry;
29 import org.opendaylight.serviceutils.tools.listener.AbstractClusteredSyncDataTreeChangeListener;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
39 * This class listens for interface creation/removal/update in Configuration DS.
40 * This is used to handle interfaces for base of-ports.
43 public class InterfaceConfigListener
44 extends AbstractClusteredSyncDataTreeChangeListener<Interface>
45 implements RecoverableListener {
47 private static final Logger LOG = LoggerFactory.getLogger(InterfaceConfigListener.class);
49 private final InterfacemgrProvider interfaceMgrProvider;
50 private final EntityOwnershipUtils entityOwnershipUtils;
51 private final JobCoordinator coordinator;
52 private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
53 private final OvsInterfaceConfigRemoveHelper ovsInterfaceConfigRemoveHelper;
54 private final OvsInterfaceConfigAddHelper ovsInterfaceConfigAddHelper;
55 private final OvsInterfaceConfigUpdateHelper ovsInterfaceConfigUpdateHelper;
58 public InterfaceConfigListener(@Reference DataBroker dataBroker,
59 InterfacemgrProvider interfaceMgrProvider,
60 EntityOwnershipUtils entityOwnershipUtils,
61 @Reference JobCoordinator coordinator,
62 InterfaceManagerCommonUtils interfaceManagerCommonUtils,
63 OvsInterfaceConfigRemoveHelper ovsInterfaceConfigRemoveHelper,
64 OvsInterfaceConfigAddHelper ovsInterfaceConfigAddHelper,
65 OvsInterfaceConfigUpdateHelper ovsInterfaceConfigUpdateHelper,
66 InterfaceServiceRecoveryHandler interfaceServiceRecoveryHandler,
67 @Reference ServiceRecoveryRegistry serviceRecoveryRegistry) {
68 super(dataBroker, LogicalDatastoreType.CONFIGURATION,
69 InstanceIdentifier.create(Interfaces.class).child(Interface.class));
70 this.interfaceMgrProvider = interfaceMgrProvider;
71 this.entityOwnershipUtils = entityOwnershipUtils;
72 this.coordinator = coordinator;
73 this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
74 this.ovsInterfaceConfigRemoveHelper = ovsInterfaceConfigRemoveHelper;
75 this.ovsInterfaceConfigAddHelper = ovsInterfaceConfigAddHelper;
76 this.ovsInterfaceConfigUpdateHelper = ovsInterfaceConfigUpdateHelper;
77 serviceRecoveryRegistry.addRecoverableListener(interfaceServiceRecoveryHandler.buildServiceRegistryKey(),
82 public void registerListener() {
87 public void deregisterListener() {
92 public void remove(@NonNull InstanceIdentifier<Interface> instanceIdentifier, @NonNull Interface removedInterface) {
93 interfaceManagerCommonUtils.removeFromInterfaceCache(removedInterface);
95 if (!entityOwnershipUtils.isEntityOwner(IfmConstants.INTERFACE_CONFIG_ENTITY,
96 IfmConstants.INTERFACE_CONFIG_ENTITY)) {
99 LOG.debug("Received Interface Remove Event: {}, {}", instanceIdentifier, removedInterface);
100 ParentRefs parentRefs = removedInterface.augmentation(ParentRefs.class);
101 if (parentRefs == null
102 || parentRefs.getDatapathNodeIdentifier() == null && parentRefs.getParentInterface() == null) {
103 LOG.debug("parent refs not specified for {}", removedInterface.getName());
106 String synchronizationKey = InterfaceManagerCommonUtils.isTunnelInterface(removedInterface)
107 ? removedInterface.getName() : parentRefs.getParentInterface();
108 coordinator.enqueueJob(synchronizationKey,
109 () -> ovsInterfaceConfigRemoveHelper.removeConfiguration(removedInterface, parentRefs),
110 IfmConstants.JOB_MAX_RETRIES);
114 public void update(@NonNull InstanceIdentifier<Interface> instanceIdentifier, @NonNull Interface originalInterface,
115 @NonNull Interface updatedInterface) {
116 interfaceManagerCommonUtils.addInterfaceToCache(updatedInterface);
118 if (!entityOwnershipUtils.isEntityOwner(IfmConstants.INTERFACE_CONFIG_ENTITY,
119 IfmConstants.INTERFACE_CONFIG_ENTITY)) {
122 LOG.debug("Received Interface Update Event: {}, {}, {}", instanceIdentifier, originalInterface,
124 ParentRefs parentRefs = updatedInterface.augmentation(ParentRefs.class);
125 if (parentRefs == null || parentRefs.getParentInterface() == null) {
126 // If parentRefs are missing, try to find a matching parent and
127 // update - this will trigger another DCN
128 updateInterfaceParentRefs(updatedInterface);
131 if (parentRefs == null
132 || parentRefs.getDatapathNodeIdentifier() == null && parentRefs.getParentInterface() == null) {
133 LOG.debug("parent refs not specified for {}, or parentRefs {} missing DPN/parentInterface",
134 updatedInterface.getName(), parentRefs);
137 String synchronizationKey = getSynchronizationKey(updatedInterface, parentRefs);
138 coordinator.enqueueJob(synchronizationKey, () -> ovsInterfaceConfigUpdateHelper
139 .updateConfiguration(updatedInterface, originalInterface), IfmConstants.JOB_MAX_RETRIES);
143 public void add(@NonNull InstanceIdentifier<Interface> instanceIdentifier, @NonNull Interface newInterface) {
144 interfaceManagerCommonUtils.addInterfaceToCache(newInterface);
146 if (!entityOwnershipUtils.isEntityOwner(IfmConstants.INTERFACE_CONFIG_ENTITY,
147 IfmConstants.INTERFACE_CONFIG_ENTITY)) {
150 LOG.debug("Received Interface Add Event: {}, {}", instanceIdentifier, newInterface);
151 ParentRefs parentRefs = newInterface.augmentation(ParentRefs.class);
152 if (parentRefs == null || parentRefs.getParentInterface() == null) {
153 // If parentRefs are missing, try to find a matching parent and
154 // update - this will trigger another DCN
155 updateInterfaceParentRefs(newInterface);
158 if (parentRefs == null
159 || parentRefs.getDatapathNodeIdentifier() == null && parentRefs.getParentInterface() == null) {
160 LOG.debug("parent refs not specified for {}", newInterface.getName());
163 String synchronizationKey = getSynchronizationKey(newInterface, parentRefs);
164 coordinator.enqueueJob(synchronizationKey,
165 () -> ovsInterfaceConfigAddHelper.addConfiguration(parentRefs, newInterface),
166 IfmConstants.JOB_MAX_RETRIES);
169 private void updateInterfaceParentRefs(Interface iface) {
170 if (InterfaceManagerCommonUtils.isTunnelInterface(iface)) {
171 return; // update of parent refs is needed only for vm ports, and not tunnels
173 String ifName = iface.getName();
174 // try to acquire the parent interface name from Southbound
175 String parentRefName = interfaceMgrProvider.getParentRefNameForInterface(ifName);
176 if (parentRefName == null) {
177 LOG.debug("parent refs not specified for {}, failed acquiring it from southbound", ifName);
180 LOG.debug("retrieved parent ref {} for interface {} from southbound, updating parentRef in datastore",
181 parentRefName, ifName);
182 interfaceMgrProvider.updateInterfaceParentRef(ifName, parentRefName, false);
185 private String getSynchronizationKey(Interface theInterface, ParentRefs theParentRefs) {
186 if (InterfaceManagerCommonUtils.isOfTunnelInterface(theInterface)) {
187 return SouthboundUtils.generateOfTunnelName(
188 theParentRefs.getDatapathNodeIdentifier(),
189 theInterface.augmentation(IfTunnel.class));
190 } else if (InterfaceManagerCommonUtils.isTunnelInterface(theInterface)) {
191 return theInterface.getName();
193 return theParentRefs.getParentInterface();