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
8 package org.opendaylight.netvirt.elan.internal;
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
14 import java.util.concurrent.Callable;
15 import javax.annotation.PostConstruct;
16 import javax.inject.Inject;
17 import javax.inject.Singleton;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
22 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
23 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
24 import org.opendaylight.netvirt.elan.utils.ElanConstants;
25 import org.opendaylight.netvirt.elan.utils.ElanUtils;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
34 public class ElanLearntVpnVipToPortListener extends
35 AsyncDataTreeChangeListenerBase<LearntVpnVipToPort, ElanLearntVpnVipToPortListener> {
36 private static final Logger LOG = LoggerFactory.getLogger(ElanLearntVpnVipToPortListener.class);
37 private final DataBroker broker;
38 private final IInterfaceManager interfaceManager;
39 private final ElanUtils elanUtils;
40 private final JobCoordinator jobCoordinator;
43 public ElanLearntVpnVipToPortListener(DataBroker broker, IInterfaceManager interfaceManager, ElanUtils elanUtils,
44 JobCoordinator jobCoordinator) {
45 super(LearntVpnVipToPort.class, ElanLearntVpnVipToPortListener.class);
47 this.interfaceManager = interfaceManager;
48 this.elanUtils = elanUtils;
49 this.jobCoordinator = jobCoordinator;
55 registerListener(LogicalDatastoreType.OPERATIONAL, broker);
59 protected InstanceIdentifier<LearntVpnVipToPort> getWildCardPath() {
60 return InstanceIdentifier.create(LearntVpnVipToPortData.class).child(LearntVpnVipToPort.class);
64 protected void remove(InstanceIdentifier<LearntVpnVipToPort> key, LearntVpnVipToPort dataObjectModification) {
65 String macAddress = dataObjectModification.getMacAddress();
66 String interfaceName = dataObjectModification.getPortName();
67 LOG.trace("Removing mac address {} from interface {} ", macAddress, interfaceName);
68 jobCoordinator.enqueueJob(buildJobKey(macAddress, interfaceName),
69 new StaticMacRemoveWorker(macAddress, interfaceName));
73 protected void update(InstanceIdentifier<LearntVpnVipToPort> key, LearntVpnVipToPort dataObjectModificationBefore,
74 LearntVpnVipToPort dataObjectModificationAfter) {
78 protected void add(InstanceIdentifier<LearntVpnVipToPort> key, LearntVpnVipToPort dataObjectModification) {
79 String macAddress = dataObjectModification.getMacAddress();
80 String interfaceName = dataObjectModification.getPortName();
81 LOG.trace("Adding mac address {} to interface {} ", macAddress, interfaceName);
82 jobCoordinator.enqueueJob(buildJobKey(macAddress, interfaceName),
83 new StaticMacAddWorker(macAddress, interfaceName));
87 protected ElanLearntVpnVipToPortListener getDataTreeChangeListener() {
91 private class StaticMacAddWorker implements Callable<List<ListenableFuture<Void>>> {
95 StaticMacAddWorker(String macAddress, String interfaceName) {
96 this.macAddress = macAddress;
97 this.interfaceName = interfaceName;
101 public List<ListenableFuture<Void>> call() throws Exception {
102 ElanInterface elanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
103 if (elanInterface == null) {
104 LOG.debug("ElanInterface Not present for interfaceName {} for add event", interfaceName);
105 return Collections.emptyList();
107 WriteTransaction interfaceTx = broker.newWriteOnlyTransaction();
108 WriteTransaction flowTx = broker.newWriteOnlyTransaction();
109 elanUtils.addMacEntryToDsAndSetupFlows(interfaceName, macAddress,
110 elanInterface.getElanInstanceName(), interfaceTx, flowTx, ElanConstants.STATIC_MAC_TIMEOUT);
111 List<ListenableFuture<Void>> futures = new ArrayList<>();
112 futures.add(interfaceTx.submit());
113 futures.add(flowTx.submit());
118 private class StaticMacRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
120 String interfaceName;
122 StaticMacRemoveWorker(String macAddress, String interfaceName) {
123 this.macAddress = macAddress;
124 this.interfaceName = interfaceName;
128 public List<ListenableFuture<Void>> call() throws Exception {
129 ElanInterface elanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
130 if (elanInterface == null) {
131 LOG.debug("ElanInterface Not present for interfaceName {} for delete event", interfaceName);
132 return Collections.emptyList();
134 WriteTransaction interfaceTx = broker.newWriteOnlyTransaction();
135 WriteTransaction flowTx = broker.newWriteOnlyTransaction();
136 elanUtils.deleteMacEntryFromDsAndRemoveFlows(interfaceName, macAddress,
137 elanInterface.getElanInstanceName(), interfaceTx, flowTx);
138 List<ListenableFuture<Void>> futures = new ArrayList<>();
139 futures.add(interfaceTx.submit());
140 futures.add(flowTx.submit());
145 private String buildJobKey(String mac, String interfaceName) {
146 return "ENTERPRISEMACJOB" + mac + interfaceName;