2 * Copyright (c) 2015 - 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.vpnmanager;
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.concurrent.Callable;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
20 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
21 import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils;
22 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
30 public class InterfaceStateChangeListener
31 extends AsyncDataTreeChangeListenerBase<Interface, InterfaceStateChangeListener> implements AutoCloseable {
32 private static final Logger LOG = LoggerFactory.getLogger(InterfaceStateChangeListener.class);
33 private final DataBroker dataBroker;
34 private final VpnInterfaceManager vpnInterfaceManager;
36 public InterfaceStateChangeListener(final DataBroker dataBroker, final VpnInterfaceManager vpnInterfaceManager) {
37 super(Interface.class, InterfaceStateChangeListener.class);
38 this.dataBroker = dataBroker;
39 this.vpnInterfaceManager = vpnInterfaceManager;
43 LOG.info("{} start", getClass().getSimpleName());
44 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
49 protected InstanceIdentifier<Interface> getWildCardPath() {
50 return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
54 protected InterfaceStateChangeListener getDataTreeChangeListener() {
55 return InterfaceStateChangeListener.this;
60 // TODO Clean up the exception handling
61 @SuppressWarnings("checkstyle:IllegalCatch")
62 protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
63 LOG.trace("Received interface {} add event", intrf);
64 LOG.info("Received interface {} add event", intrf.getName());
66 final String interfaceName = intrf.getName();
67 LOG.info("Received interface add event for interface {} ", interfaceName);
68 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
69 configInterface = InterfaceUtils.getInterface(dataBroker, interfaceName);
70 if (configInterface != null) {
71 if (!configInterface.getType().equals(Tunnel.class)) {
72 // We service only VM interfaces and Router interfaces here.
73 // We donot service Tunnel Interfaces here.
74 // Tunnel events are directly serviced
75 // by TunnelInterfacesStateListener present as part of VpnInterfaceManager
76 LOG.debug("Config Interface Name {}", configInterface.getName());
77 final VpnInterface vpnInterface = VpnUtil.getConfiguredVpnInterface(dataBroker, interfaceName);
78 if (vpnInterface != null) {
79 LOG.debug("VPN Interface Name {}", vpnInterface);
80 BigInteger intfDpnId = BigInteger.ZERO;
82 intfDpnId = InterfaceUtils.getDpIdFromInterface(intrf);
83 } catch (Exception e) {
85 "Unable to retrieve dpnId for interface {}. Process vpn interface add failed",
89 final BigInteger dpnId = intfDpnId;
90 final int ifIndex = intrf.getIfIndex();
91 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
92 dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + intrf.getName(),
93 new Callable<List<ListenableFuture<Void>>>() {
95 public List<ListenableFuture<Void>> call() throws Exception {
96 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
97 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
98 WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction();
99 vpnInterfaceManager.processVpnInterfaceUp(dpnId, vpnInterface, ifIndex, false,
100 writeConfigTxn, writeOperTxn, writeInvTxn);
101 List<ListenableFuture<Void>> futures = new ArrayList<>();
102 futures.add(writeOperTxn.submit());
103 futures.add(writeConfigTxn.submit());
104 futures.add(writeInvTxn.submit());
111 LOG.error("Unable to process add for interface {},"
112 + "since Interface ConfigDS entry absent for the same", interfaceName);
114 } catch (Exception e) {
115 LOG.error("Exception caught in Interface Operational State Up event", e);
120 // TODO Clean up the exception handling
121 @SuppressWarnings("checkstyle:IllegalCatch")
122 protected void remove(InstanceIdentifier<Interface> identifier, Interface intrf) {
123 final String interfaceName = intrf.getName();
124 LOG.trace("Received interface {} down event", intrf);
125 LOG.info("Received interface {} remove event", interfaceName);
127 LOG.info("Received port DOWN event for interface {} ", interfaceName);
128 if (intrf != null && intrf.getType() != null && !intrf.getType().equals(Tunnel.class)) {
130 InstanceIdentifier<VpnInterface> id = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
131 Optional<VpnInterface> optVpnInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
132 if (!optVpnInterface.isPresent()) {
133 LOG.debug("Interface {} is not a vpninterface, ignoring.", interfaceName);
136 final VpnInterface vpnInterface = optVpnInterface.get();
138 dpId = InterfaceUtils.getDpIdFromInterface(intrf);
139 } catch (Exception e) {
140 LOG.error("Unable to retrieve dpnId from interface operational data store for interface {}. "
141 + "Fetching from vpn interface op data store. ", interfaceName, e);
142 dpId = vpnInterface.getDpnId();
144 final BigInteger dpnId = dpId;
145 final int ifIndex = intrf.getIfIndex();
146 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
147 dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName,
148 new Callable<List<ListenableFuture<Void>>>() {
150 public List<ListenableFuture<Void>> call() throws Exception {
151 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
152 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
153 WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction();
154 vpnInterfaceManager.processVpnInterfaceDown(dpnId, interfaceName, ifIndex, false, false,
155 writeConfigTxn, writeOperTxn, writeInvTxn);
156 List<ListenableFuture<Void>> futures = new ArrayList<>();
157 futures.add(writeOperTxn.submit());
158 futures.add(writeConfigTxn.submit());
159 futures.add(writeInvTxn.submit());
164 } catch (Exception e) {
165 LOG.error("Exception observed in handling deletion of VPN Interface {}. ", interfaceName, e);
169 // TODO Clean up the exception handling
170 @SuppressWarnings("checkstyle:IllegalCatch")
172 protected void update(InstanceIdentifier<Interface> identifier,
173 Interface original, Interface update) {
174 LOG.trace("Operation Interface update event - Old: {}, New: {}", original, update);
176 final String interfaceName = update.getName();
177 if (original.getOperStatus().equals(Interface.OperStatus.Unknown)
178 || update.getOperStatus().equals(Interface.OperStatus.Unknown)) {
179 LOG.debug("Interface {} state change is from/to UNKNOWN. Ignoring the update event.", interfaceName);
182 final BigInteger dpnId = InterfaceUtils.getDpIdFromInterface(update);
184 if (update.getIfIndex() == null) {
187 if (update != null && (update.getType() != null)) {
188 if (!update.getType().equals(Tunnel.class)) {
189 final VpnInterface vpnInterface = VpnUtil.getConfiguredVpnInterface(dataBroker, interfaceName);
190 if (vpnInterface != null) {
191 final int ifIndex = update.getIfIndex();
192 if (update.getOperStatus().equals(Interface.OperStatus.Up)) {
193 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
194 dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName,
195 new Callable<List<ListenableFuture<Void>>>() {
197 public List<ListenableFuture<Void>> call() throws Exception {
198 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
199 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
200 WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction();
201 vpnInterfaceManager.processVpnInterfaceUp(dpnId, vpnInterface, ifIndex,
202 true, writeConfigTxn, writeOperTxn, writeInvTxn);
203 List<ListenableFuture<Void>> futures = new ArrayList<>();
204 futures.add(writeOperTxn.submit());
205 futures.add(writeConfigTxn.submit());
206 futures.add(writeInvTxn.submit());
210 } else if (update.getOperStatus().equals(Interface.OperStatus.Down)) {
211 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
212 dataStoreCoordinator.enqueueJob(interfaceName,
213 new Callable<List<ListenableFuture<Void>>>() {
215 public List<ListenableFuture<Void>> call() throws Exception {
216 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
217 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
218 WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction();
219 vpnInterfaceManager.processVpnInterfaceDown(dpnId, interfaceName, ifIndex, true,
220 false, writeConfigTxn, writeOperTxn, writeInvTxn);
221 List<ListenableFuture<Void>> futures = new ArrayList<>();
222 futures.add(writeOperTxn.submit());
223 futures.add(writeConfigTxn.submit());
224 futures.add(writeInvTxn.submit());
232 } catch (Exception e) {
233 LOG.error("Exception observed in handling updation of VPN Interface {}. ", update.getName(), e);