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.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
18 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
19 import org.opendaylight.genius.interfacemanager.IfmConstants;
20 import org.opendaylight.genius.interfacemanager.renderer.ovs.confighelpers.OvsVlanMemberConfigAddHelper;
21 import org.opendaylight.genius.interfacemanager.renderer.ovs.confighelpers.OvsVlanMemberConfigRemoveHelper;
22 import org.opendaylight.genius.interfacemanager.renderer.ovs.confighelpers.OvsVlanMemberConfigUpdateHelper;
23 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 public class VlanMemberConfigListener extends AsyncDataTreeChangeListenerBase<Interface, VlanMemberConfigListener> {
36 private static final Logger LOG = LoggerFactory.getLogger(VlanMemberConfigListener.class);
37 private final DataBroker dataBroker;
38 private final IdManagerService idManager;
39 private final AlivenessMonitorService alivenessMonitorService;
40 private final IMdsalApiManager mdsalApiManager;
43 public VlanMemberConfigListener(final DataBroker dataBroker, final IdManagerService idManagerService,
44 final IMdsalApiManager iMdsalApiManager, final AlivenessMonitorService alivenessMonitorService) {
45 super(Interface.class, VlanMemberConfigListener.class);
46 this.dataBroker = dataBroker;
47 this.idManager = idManagerService;
48 this.mdsalApiManager = iMdsalApiManager;
49 this.alivenessMonitorService = alivenessMonitorService;
50 this.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
54 protected InstanceIdentifier<Interface> getWildCardPath() {
55 return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
59 protected void remove(InstanceIdentifier<Interface> key, Interface interfaceOld) {
60 IfL2vlan ifL2vlan = interfaceOld.getAugmentation(IfL2vlan.class);
61 if (ifL2vlan == null || IfL2vlan.L2vlanMode.TrunkMember != ifL2vlan.getL2vlanMode()) {
64 removeVlanMember(key, interfaceOld);
67 private void removeVlanMember(InstanceIdentifier<Interface> key, Interface deleted) {
68 IfL2vlan ifL2vlan = deleted.getAugmentation(IfL2vlan.class);
69 ParentRefs parentRefs = deleted.getAugmentation(ParentRefs.class);
70 if (parentRefs == null) {
71 LOG.error("Attempt to remove Vlan Trunk-Member {} without a parent interface", deleted);
75 String lowerLayerIf = parentRefs.getParentInterface();
76 if (lowerLayerIf.equals(deleted.getName())) {
77 LOG.error("Attempt to remove Vlan Trunk-Member {} with same parent interface name.", deleted);
81 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
82 RendererConfigRemoveWorker removeWorker = new RendererConfigRemoveWorker(key, deleted, parentRefs, ifL2vlan);
83 coordinator.enqueueJob(lowerLayerIf, removeWorker, IfmConstants.JOB_MAX_RETRIES);
87 protected void update(InstanceIdentifier<Interface> key, Interface interfaceOld, Interface interfaceNew) {
88 IfL2vlan ifL2vlanNew = interfaceNew.getAugmentation(IfL2vlan.class);
89 if (ifL2vlanNew == null) {
92 IfL2vlan ifL2vlanOld = interfaceOld.getAugmentation(IfL2vlan.class);
93 if (IfL2vlan.L2vlanMode.TrunkMember == ifL2vlanNew.getL2vlanMode()
94 && IfL2vlan.L2vlanMode.Trunk == ifL2vlanOld.getL2vlanMode()) {
95 // Trunk subport add use case
96 addVlanMember(key, interfaceNew);
98 } else if (IfL2vlan.L2vlanMode.Trunk == ifL2vlanNew.getL2vlanMode()
99 && IfL2vlan.L2vlanMode.TrunkMember == ifL2vlanOld.getL2vlanMode()) {
100 // Trunk subport remove use case
101 removeVlanMember(key, interfaceOld);
102 } else if (IfL2vlan.L2vlanMode.TrunkMember != ifL2vlanNew.getL2vlanMode()) {
106 ParentRefs parentRefsNew = interfaceNew.getAugmentation(ParentRefs.class);
107 if (parentRefsNew == null) {
108 LOG.error("Configuration Error. Attempt to update Vlan Trunk-Member {} without a " + "parent interface",
113 String lowerLayerIf = parentRefsNew.getParentInterface();
114 if (lowerLayerIf.equals(interfaceNew.getName())) {
116 "Configuration Error. Attempt to update Vlan Trunk-Member {} with same parent " + "interface name.",
121 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
122 RendererConfigUpdateWorker updateWorker = new RendererConfigUpdateWorker(key, interfaceNew, interfaceOld,
123 parentRefsNew, ifL2vlanNew);
124 coordinator.enqueueJob(lowerLayerIf, updateWorker, IfmConstants.JOB_MAX_RETRIES);
128 protected void add(InstanceIdentifier<Interface> key, Interface interfaceNew) {
129 IfL2vlan ifL2vlan = interfaceNew.getAugmentation(IfL2vlan.class);
130 if (ifL2vlan == null || IfL2vlan.L2vlanMode.TrunkMember != ifL2vlan.getL2vlanMode()) {
133 addVlanMember(key, interfaceNew);
136 private void addVlanMember(InstanceIdentifier<Interface> key, Interface added) {
137 IfL2vlan ifL2vlan = added.getAugmentation(IfL2vlan.class);
138 ParentRefs parentRefs = added.getAugmentation(ParentRefs.class);
139 if (parentRefs == null) {
143 String lowerLayerIf = parentRefs.getParentInterface();
144 if (lowerLayerIf.equals(added.getName())) {
145 LOG.error("Attempt to add Vlan Trunk-Member {} with same parent interface name.", added);
149 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
150 RendererConfigAddWorker configWorker = new RendererConfigAddWorker(key, added, parentRefs, ifL2vlan);
151 coordinator.enqueueJob(lowerLayerIf, configWorker, IfmConstants.JOB_MAX_RETRIES);
155 protected VlanMemberConfigListener getDataTreeChangeListener() {
156 return VlanMemberConfigListener.this;
159 private class RendererConfigAddWorker implements Callable<List<ListenableFuture<Void>>> {
160 InstanceIdentifier<Interface> key;
161 Interface interfaceNew;
163 ParentRefs parentRefs;
165 RendererConfigAddWorker(InstanceIdentifier<Interface> key, Interface interfaceNew, ParentRefs parentRefs,
168 this.interfaceNew = interfaceNew;
169 this.ifL2vlan = ifL2vlan;
170 this.parentRefs = parentRefs;
174 public List<ListenableFuture<Void>> call() {
175 // If another renderer(for eg : CSS) needs to be supported, check
176 // can be performed here
177 // to call the respective helpers.
178 return OvsVlanMemberConfigAddHelper.addConfiguration(dataBroker, parentRefs, interfaceNew, ifL2vlan,
183 private class RendererConfigUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
184 InstanceIdentifier<Interface> key;
185 Interface interfaceNew;
186 Interface interfaceOld;
187 IfL2vlan ifL2vlanNew;
188 ParentRefs parentRefsNew;
190 RendererConfigUpdateWorker(InstanceIdentifier<Interface> key, Interface interfaceNew, Interface interfaceOld,
191 ParentRefs parentRefsNew, IfL2vlan ifL2vlanNew) {
193 this.interfaceNew = interfaceNew;
194 this.interfaceOld = interfaceOld;
195 this.ifL2vlanNew = ifL2vlanNew;
196 this.parentRefsNew = parentRefsNew;
200 public List<ListenableFuture<Void>> call() {
201 // If another renderer(for eg : CSS) needs to be supported, check
202 // can be performed here
203 // to call the respective helpers.
204 return OvsVlanMemberConfigUpdateHelper.updateConfiguration(dataBroker, alivenessMonitorService,
205 parentRefsNew, interfaceOld, ifL2vlanNew, interfaceNew, idManager, mdsalApiManager);
209 private class RendererConfigRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
210 InstanceIdentifier<Interface> key;
211 Interface interfaceOld;
213 ParentRefs parentRefs;
215 RendererConfigRemoveWorker(InstanceIdentifier<Interface> key, Interface interfaceOld, ParentRefs parentRefs,
218 this.interfaceOld = interfaceOld;
219 this.ifL2vlan = ifL2vlan;
220 this.parentRefs = parentRefs;
224 public List<ListenableFuture<Void>> call() {
225 // If another renderer(for eg : CSS) needs to be supported, check
226 // can be performed here
227 // to call the respective helpers.
228 return OvsVlanMemberConfigRemoveHelper.removeConfiguration(dataBroker, parentRefs, interfaceOld, ifL2vlan,