2 * Copyright (c) 2016 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 com.google.common.util.concurrent.ListenableFuture;
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
14 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
15 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
16 import org.opendaylight.genius.interfacemanager.IfmConstants;
17 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
18 import org.opendaylight.genius.interfacemanager.renderer.ovs.confighelpers.OvsInterfaceConfigAddHelper;
19 import org.opendaylight.genius.interfacemanager.renderer.ovs.confighelpers.OvsInterfaceConfigRemoveHelper;
20 import org.opendaylight.genius.interfacemanager.renderer.ovs.confighelpers.OvsInterfaceConfigUpdateHelper;
21 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.IfmClusterUtils;
22 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
33 import java.util.List;
34 import java.util.concurrent.Callable;
37 * This class listens for interface creation/removal/update in Configuration DS.
38 * This is used to handle interfaces for base of-ports.
40 public class InterfaceConfigListener extends AsyncClusteredDataTreeChangeListenerBase<Interface, InterfaceConfigListener> {
41 private static final Logger LOG = LoggerFactory.getLogger(InterfaceConfigListener.class);
42 private DataBroker dataBroker;
43 private IdManagerService idManager;
44 private AlivenessMonitorService alivenessMonitorService;
45 private IMdsalApiManager mdsalApiManager;
47 public InterfaceConfigListener(final DataBroker dataBroker, final IdManagerService idManager,
48 final AlivenessMonitorService alivenessMonitorService,
49 final IMdsalApiManager mdsalApiManager) {
50 super(Interface.class, InterfaceConfigListener.class);
51 this.dataBroker = dataBroker;
52 this.idManager = idManager;
53 this.alivenessMonitorService = alivenessMonitorService;
54 this.mdsalApiManager = mdsalApiManager;
58 protected InstanceIdentifier<Interface> getWildCardPath() {
59 return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
63 protected InterfaceConfigListener getDataTreeChangeListener() {
64 return InterfaceConfigListener.this;
68 protected void remove(InstanceIdentifier<Interface> key, Interface interfaceOld) {
69 IfmClusterUtils.runOnlyInLeaderNode(new Runnable() {
72 LOG.debug("Received Interface Remove Event: {}, {}", key, interfaceOld);
73 String ifName = interfaceOld.getName();
74 ParentRefs parentRefs = interfaceOld.getAugmentation(ParentRefs.class);
75 if (parentRefs == null || parentRefs.getDatapathNodeIdentifier() == null && parentRefs.getParentInterface() == null) {
76 LOG.warn("parent refs not specified for {}", interfaceOld.getName());
79 boolean isTunnelInterface = InterfaceManagerCommonUtils.isTunnelInterface(interfaceOld);
80 parentRefs = updateParentInterface(isTunnelInterface, parentRefs);
81 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
82 RendererConfigRemoveWorker configWorker = new RendererConfigRemoveWorker(key, interfaceOld, ifName, parentRefs);
83 String synchronizationKey = isTunnelInterface ?
84 parentRefs.getDatapathNodeIdentifier().toString() : parentRefs.getParentInterface();
85 coordinator.enqueueJob(synchronizationKey, configWorker, IfmConstants.JOB_MAX_RETRIES);
91 protected void update(InstanceIdentifier<Interface> key, Interface interfaceOld, Interface interfaceNew) {
92 IfmClusterUtils.runOnlyInLeaderNode(new Runnable() {
95 LOG.debug("Received Interface Update Event: {}, {}, {}", key, interfaceOld, interfaceNew);
96 String ifNameNew = interfaceNew.getName();
97 ParentRefs parentRefs = interfaceNew.getAugmentation(ParentRefs.class);
98 if (parentRefs == null || parentRefs.getDatapathNodeIdentifier() == null && parentRefs.getParentInterface() == null) {
99 LOG.warn("parent refs not specified for {}", interfaceNew.getName());
102 boolean isTunnelInterface = InterfaceManagerCommonUtils.isTunnelInterface(interfaceOld);
103 parentRefs = updateParentInterface(isTunnelInterface, parentRefs);
104 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
105 RendererConfigUpdateWorker worker = new RendererConfigUpdateWorker(key, interfaceOld, interfaceNew, ifNameNew);
106 String synchronizationKey = isTunnelInterface ?
107 interfaceOld.getName() : parentRefs.getParentInterface();
108 coordinator.enqueueJob(synchronizationKey, worker, IfmConstants.JOB_MAX_RETRIES);
114 protected void add(InstanceIdentifier<Interface> key, Interface interfaceNew) {
115 IfmClusterUtils.runOnlyInLeaderNode(new Runnable() {
118 LOG.debug("Received Interface Add Event: {}, {}", key, interfaceNew);
119 String ifName = interfaceNew.getName();
120 ParentRefs parentRefs = interfaceNew.getAugmentation(ParentRefs.class);
121 if (parentRefs == null || parentRefs.getDatapathNodeIdentifier() == null && parentRefs.getParentInterface() == null) {
122 LOG.warn("parent refs not specified for {}", interfaceNew.getName());
125 boolean isTunnelInterface = InterfaceManagerCommonUtils.isTunnelInterface(interfaceNew);
126 parentRefs = updateParentInterface(isTunnelInterface, parentRefs);
127 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
128 RendererConfigAddWorker configWorker = new RendererConfigAddWorker(key, interfaceNew, parentRefs, ifName);
129 String synchronizationKey = isTunnelInterface ?
130 interfaceNew.getName() : parentRefs.getParentInterface();
131 coordinator.enqueueJob(synchronizationKey, configWorker, IfmConstants.JOB_MAX_RETRIES);
136 private static ParentRefs updateParentInterface(boolean isTunnelInterface, ParentRefs parentRefs) {
137 if (!isTunnelInterface && parentRefs.getDatapathNodeIdentifier() != null) {
138 String parentInterface = parentRefs.getDatapathNodeIdentifier().toString() + IfmConstants.OF_URI_SEPARATOR +
139 parentRefs.getParentInterface();
140 parentRefs = new ParentRefsBuilder(parentRefs).setParentInterface(parentInterface).build();
145 private class RendererConfigAddWorker implements Callable<List<ListenableFuture<Void>>> {
146 InstanceIdentifier<Interface> key;
147 Interface interfaceNew;
149 ParentRefs parentRefs;
151 public RendererConfigAddWorker(InstanceIdentifier<Interface> key, Interface interfaceNew,
152 ParentRefs parentRefs, String portName) {
154 this.interfaceNew = interfaceNew;
155 this.portName = portName;
156 this.parentRefs = parentRefs;
160 public List<ListenableFuture<Void>> call() throws Exception {
161 // If another renderer(for eg : CSS) needs to be supported, check can be performed here
162 // to call the respective helpers.
163 return OvsInterfaceConfigAddHelper.addConfiguration(dataBroker, parentRefs, interfaceNew,
164 idManager, alivenessMonitorService, mdsalApiManager);
168 public String toString() {
169 return "RendererConfigAddWorker{" +
171 ", interfaceNew=" + interfaceNew +
172 ", portName='" + portName + '\'' +
180 private class RendererConfigUpdateWorker implements Callable {
181 InstanceIdentifier<Interface> key;
182 Interface interfaceOld;
183 Interface interfaceNew;
186 public RendererConfigUpdateWorker(InstanceIdentifier<Interface> key, Interface interfaceOld,
187 Interface interfaceNew, String portNameNew) {
189 this.interfaceOld = interfaceOld;
190 this.interfaceNew = interfaceNew;
191 this.portNameNew = portNameNew;
195 public List<ListenableFuture<Void>> call() throws Exception {
196 // If another renderer(for eg : CSS) needs to be supported, check can be performed here
197 // to call the respective helpers.
198 return OvsInterfaceConfigUpdateHelper.updateConfiguration(dataBroker, alivenessMonitorService, idManager,
199 mdsalApiManager, interfaceNew, interfaceOld);
203 public String toString() {
204 return "RendererConfigUpdateWorker{" +
206 ", interfaceOld=" + interfaceOld +
207 ", interfaceNew=" + interfaceNew +
208 ", portNameNew='" + portNameNew + '\'' +
216 private class RendererConfigRemoveWorker implements Callable {
217 InstanceIdentifier<Interface> key;
218 Interface interfaceOld;
220 ParentRefs parentRefs;
222 public RendererConfigRemoveWorker(InstanceIdentifier<Interface> key, Interface interfaceOld, String portName,
223 ParentRefs parentRefs) {
225 this.interfaceOld = interfaceOld;
226 this.portName = portName;
227 this.parentRefs = parentRefs;
231 public List<ListenableFuture<Void>> call() throws Exception {
232 // If another renderer(for eg : CSS) needs to be supported, check can be performed here
233 // to call the respective helpers.
234 return OvsInterfaceConfigRemoveHelper.removeConfiguration(dataBroker, alivenessMonitorService,
235 interfaceOld, idManager, mdsalApiManager, parentRefs);
239 public String toString() {
240 return "RendererConfigRemoveWorker{" +
242 ", interfaceOld=" + interfaceOld +
243 ", portName='" + portName + '\'' +