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 java.util.Objects;
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.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
16 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
17 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
18 import org.opendaylight.genius.interfacemanager.IfmConstants;
19 import org.opendaylight.genius.interfacemanager.IfmUtil;
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.infrautils.jobcoordinator.JobCoordinator;
24 import org.opendaylight.mdsal.binding.api.DataBroker;
25 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
26 import org.opendaylight.serviceutils.tools.listener.AbstractSyncDataTreeChangeListener;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
36 public class VlanMemberConfigListener extends AbstractSyncDataTreeChangeListener<Interface> {
38 private static final Logger LOG = LoggerFactory.getLogger(VlanMemberConfigListener.class);
40 private final JobCoordinator coordinator;
41 private final OvsVlanMemberConfigAddHelper ovsVlanMemberConfigAddHelper;
42 private final OvsVlanMemberConfigRemoveHelper ovsVlanMemberConfigRemoveHelper;
43 private final OvsVlanMemberConfigUpdateHelper ovsVlanMemberConfigUpdateHelper;
44 private final DataTreeEventCallbackRegistrar eventCallbacks;
45 private final ManagedNewTransactionRunner txRunner;
48 public VlanMemberConfigListener(@Reference final DataBroker dataBroker,
49 @Reference final JobCoordinator coordinator,
50 final OvsVlanMemberConfigAddHelper ovsVlanMemberConfigAddHelper,
51 final OvsVlanMemberConfigRemoveHelper ovsVlanMemberConfigRemoveHelper,
52 final OvsVlanMemberConfigUpdateHelper ovsVlanMemberConfigUpdateHelper,
53 @Reference final DataTreeEventCallbackRegistrar eventCallbacks) {
54 super(dataBroker, LogicalDatastoreType.CONFIGURATION,
55 InstanceIdentifier.create(Interfaces.class).child(Interface.class));
56 this.coordinator = coordinator;
57 this.ovsVlanMemberConfigAddHelper = ovsVlanMemberConfigAddHelper;
58 this.ovsVlanMemberConfigRemoveHelper = ovsVlanMemberConfigRemoveHelper;
59 this.ovsVlanMemberConfigUpdateHelper = ovsVlanMemberConfigUpdateHelper;
60 this.eventCallbacks = eventCallbacks;
61 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
65 public void remove(@NonNull InstanceIdentifier<Interface> instanceIdentifier, @NonNull Interface removedInterface) {
66 IfL2vlan ifL2vlan = removedInterface.augmentation(IfL2vlan.class);
67 if (ifL2vlan == null || IfL2vlan.L2vlanMode.TrunkMember != ifL2vlan.getL2vlanMode()) {
70 removeVlanMember(removedInterface);
73 private void removeVlanMember(Interface removedInterface) {
74 ParentRefs parentRefs = removedInterface.augmentation(ParentRefs.class);
75 if (parentRefs == null) {
76 LOG.error("Attempt to remove Vlan Trunk-Member {} without a parent interface", removedInterface);
80 String lowerLayerIf = parentRefs.getParentInterface();
81 if (Objects.equals(lowerLayerIf, removedInterface.getName())) {
82 LOG.error("Attempt to remove Vlan Trunk-Member {} with same parent interface name.", removedInterface);
85 coordinator.enqueueJob(lowerLayerIf,
86 () -> ovsVlanMemberConfigRemoveHelper.removeConfiguration(parentRefs, removedInterface),
87 IfmConstants.JOB_MAX_RETRIES);
91 public void update(@NonNull InstanceIdentifier<Interface> instanceIdentifier,
92 @NonNull Interface originalInterface, @NonNull Interface updatedInterface) {
93 IfL2vlan ifL2vlanNew = updatedInterface.augmentation(IfL2vlan.class);
94 if (ifL2vlanNew == null) {
97 IfL2vlan ifL2vlanOld = originalInterface.augmentation(IfL2vlan.class);
98 if (IfL2vlan.L2vlanMode.TrunkMember == ifL2vlanNew.getL2vlanMode()
99 && IfL2vlan.L2vlanMode.Trunk == ifL2vlanOld.getL2vlanMode()) {
100 // Trunk subport add use case
101 addVlanMember(updatedInterface);
103 } else if (IfL2vlan.L2vlanMode.Trunk == ifL2vlanNew.getL2vlanMode()
104 && IfL2vlan.L2vlanMode.TrunkMember == ifL2vlanOld.getL2vlanMode()) {
105 // Trunk subport remove use case
106 removeVlanMember(originalInterface);
108 } else if (IfL2vlan.L2vlanMode.TrunkMember != ifL2vlanNew.getL2vlanMode()) {
112 ParentRefs parentRefsNew = updatedInterface.augmentation(ParentRefs.class);
113 if (parentRefsNew == null) {
114 LOG.error("Configuration Error. Attempt to update Vlan Trunk-Member {} without a " + "parent interface",
119 String lowerLayerIf = parentRefsNew.getParentInterface();
120 if (Objects.equals(lowerLayerIf, updatedInterface.getName())) {
122 "Configuration Error. Attempt to update Vlan Trunk-Member {} with same parent " + "interface name.",
126 coordinator.enqueueJob(lowerLayerIf, () -> ovsVlanMemberConfigUpdateHelper
127 .updateConfiguration(parentRefsNew, originalInterface, ifL2vlanNew,
129 IfmConstants.JOB_MAX_RETRIES);
133 public void add(@NonNull InstanceIdentifier<Interface> instanceIdentifier,
134 @NonNull Interface newInterface) {
135 IfL2vlan ifL2vlan = newInterface.augmentation(IfL2vlan.class);
136 if (ifL2vlan == null || IfL2vlan.L2vlanMode.TrunkMember != ifL2vlan.getL2vlanMode()) {
139 addVlanMember(newInterface);
142 private void addVlanMember(Interface added) {
143 ParentRefs parentRefs = added.augmentation(ParentRefs.class);
144 if (parentRefs == null) {
148 String lowerLayerIf = parentRefs.getParentInterface();
149 if (Objects.equals(lowerLayerIf, added.getName())) {
150 LOG.error("Attempt to add Vlan Trunk-Member {} with same parent interface name.", added);
154 LOG.info("registering callback on interface-state for {} for proceeding with "
155 + "vlan member configuration for interface {}", lowerLayerIf, added.getName());
156 eventCallbacks.onAddOrUpdate(LogicalDatastoreType.OPERATIONAL,
157 IfmUtil.buildStateInterfaceId(parentRefs.getParentInterface()), (unused, alsoUnused) -> {
158 LOG.info("parent interface configuration {} detected for l2vlan-member {},"
159 + "proceeding with state creation", parentRefs.getParentInterface(), added.getName());
160 ovsVlanMemberConfigAddHelper.addConfiguration(parentRefs, added);
161 return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;