2 * Copyright (c) 2015, 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.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.ExecutionException;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
21 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
22 import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils;
23 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 public class InterfaceStateChangeListener
33 extends AsyncDataTreeChangeListenerBase<Interface, InterfaceStateChangeListener> implements AutoCloseable {
34 private static final Logger LOG = LoggerFactory.getLogger(InterfaceStateChangeListener.class);
35 private final DataBroker dataBroker;
36 private final VpnInterfaceManager vpnInterfaceManager;
38 public InterfaceStateChangeListener(final DataBroker dataBroker, final VpnInterfaceManager vpnInterfaceManager) {
39 super(Interface.class, InterfaceStateChangeListener.class);
40 this.dataBroker = dataBroker;
41 this.vpnInterfaceManager = vpnInterfaceManager;
45 LOG.info("{} start", getClass().getSimpleName());
46 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
51 protected InstanceIdentifier<Interface> getWildCardPath() {
52 return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
56 protected InterfaceStateChangeListener getDataTreeChangeListener() {
57 return InterfaceStateChangeListener.this;
62 // TODO Clean up the exception handling
63 @SuppressWarnings("checkstyle:IllegalCatch")
64 protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
66 if (L2vlan.class.equals(intrf.getType())) {
67 LOG.info("VPN Interface add event - intfName {} from InterfaceStateChangeListener",
69 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
70 dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + intrf.getName(),
72 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
73 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
74 WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction();
75 List<ListenableFuture<Void>> futures = new ArrayList<>();
77 final String interfaceName = intrf.getName();
78 LOG.info("Detected interface add event for interface {}", interfaceName);
80 final VpnInterface vpnInterface =
81 VpnUtil.getConfiguredVpnInterface(dataBroker, interfaceName);
82 if (vpnInterface != null) {
83 LOG.debug("VPN Interface Name {}", vpnInterface);
84 BigInteger intfDpnId = BigInteger.ZERO;
86 intfDpnId = InterfaceUtils.getDpIdFromInterface(intrf);
87 } catch (Exception e) {
88 LOG.error("Unable to retrieve dpnId for interface {}. "
89 + "Process vpn interface add failed",intrf.getName(), e);
92 final BigInteger dpnId = intfDpnId;
93 final int ifIndex = intrf.getIfIndex();
94 if (!vpnInterfaceManager.isVpnInstanceReady(vpnInterface.getVpnInstanceName())) {
95 LOG.info("VPN Interface add event - intfName {} onto vpnName {} "
96 + "running oper-driven, VpnInstance not ready, holding on",
97 vpnInterface.getName(), vpnInterface.getVpnInstanceName());
100 LOG.info("VPN Interface add event - intfName {} onto vpnName {} running oper-driven",
101 vpnInterface.getName(), vpnInterface.getVpnInstanceName());
102 vpnInterfaceManager.processVpnInterfaceUp(dpnId, vpnInterface, ifIndex, false,
103 writeConfigTxn, writeOperTxn, writeInvTxn, intrf);
104 ListenableFuture<Void> operFuture = writeOperTxn.submit();
107 } catch (ExecutionException e) {
108 LOG.error("InterfaceStateChange - Exception encountered while submitting"
109 + " operational future for addVpnInterface {} : {}",
110 vpnInterface.getName(), e);
113 futures.add(writeConfigTxn.submit());
114 futures.add(writeInvTxn.submit());
119 } catch (Exception e) {
120 LOG.error("Exception caught in Interface {} Operational State Up event", intrf.getName(), e);
125 // TODO Clean up the exception handling
126 @SuppressWarnings("checkstyle:IllegalCatch")
127 protected void remove(InstanceIdentifier<Interface> identifier, Interface intrf) {
128 final String interfaceName = intrf.getName();
129 BigInteger dpId = BigInteger.ZERO;
131 if (L2vlan.class.equals(intrf.getType())) {
132 LOG.info("VPN Interface remove event - intfName {} from InterfaceStateChangeListener",
135 dpId = InterfaceUtils.getDpIdFromInterface(intrf);
136 } catch (Exception e) {
137 LOG.error("Unable to retrieve dpnId from interface operational data store for interface"
138 + " {}. Fetching from vpn interface op data store. ", interfaceName, e);
140 final BigInteger inputDpId = dpId;
141 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
142 dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName,
144 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
145 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
146 WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction();
147 List<ListenableFuture<Void>> futures = new ArrayList<>();
149 InstanceIdentifier<VpnInterface> id = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
150 Optional<VpnInterface> optVpnInterface =
151 VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
152 if (optVpnInterface.isPresent()) {
153 final VpnInterface vpnInterface = optVpnInterface.get();
154 BigInteger dpnId = inputDpId;
155 if (dpnId == null || dpnId.equals(BigInteger.ZERO)) {
156 dpnId = vpnInterface.getDpnId();
158 final int ifIndex = intrf.getIfIndex();
159 LOG.info("VPN Interface remove event - intfName {} onto vpnName {} running oper-driven",
160 vpnInterface.getName(), vpnInterface.getVpnInstanceName());
161 vpnInterfaceManager.processVpnInterfaceDown(dpnId, interfaceName, ifIndex, intrf,
162 vpnInterface, false, writeConfigTxn, writeOperTxn, writeInvTxn);
163 ListenableFuture<Void> operFuture = writeOperTxn.submit();
166 } catch (ExecutionException e) {
167 LOG.error("InterfaceStateChange - Exception encountered while submitting operational"
168 + " future for removeVpnInterface {} : {}", vpnInterface.getName(), e);
171 futures.add(writeConfigTxn.submit());
172 futures.add(writeInvTxn.submit());
174 LOG.debug("Interface {} is not a vpninterface, ignoring.", interfaceName);
180 } catch (Exception e) {
181 LOG.error("Exception observed in handling deletion of VPN Interface {}. ", interfaceName, e);
185 // TODO Clean up the exception handling
186 @SuppressWarnings("checkstyle:IllegalCatch")
188 protected void update(InstanceIdentifier<Interface> identifier,
189 Interface original, Interface update) {
190 final String interfaceName = update.getName();
192 OperStatus originalOperStatus = original.getOperStatus();
193 OperStatus updateOperStatus = update.getOperStatus();
194 if (originalOperStatus.equals(Interface.OperStatus.Unknown)
195 || updateOperStatus.equals(Interface.OperStatus.Unknown)) {
196 LOG.debug("Interface {} state change is from/to null/UNKNOWN. Ignoring the update event.",
201 if (update.getIfIndex() == null) {
204 if (L2vlan.class.equals(update.getType())) {
205 LOG.info("VPN Interface update event - intfName {} from InterfaceStateChangeListener",
207 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
208 dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName,
210 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
211 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
212 WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction();
213 List<ListenableFuture<Void>> futures = new ArrayList<>();
214 final VpnInterface vpnInterface =
215 VpnUtil.getConfiguredVpnInterface(dataBroker, interfaceName);
216 if (vpnInterface != null) {
217 final int ifIndex = update.getIfIndex();
218 final BigInteger dpnId = InterfaceUtils.getDpIdFromInterface(update);
219 if (update.getOperStatus().equals(Interface.OperStatus.Up)) {
220 LOG.info("VPN Interface update event - intfName {} onto vpnName {} running "
221 + " oper-driven UP", vpnInterface.getName(),
222 vpnInterface.getVpnInstanceName());
223 if (!vpnInterfaceManager.isVpnInstanceReady(vpnInterface.getVpnInstanceName())) {
224 LOG.info("VPN Interface update event - intfName {} onto vpnName {} "
225 + "running oper-driven UP, VpnInstance not ready, holding on",
226 vpnInterface.getName(), vpnInterface.getVpnInstanceName());
229 vpnInterfaceManager.processVpnInterfaceUp(dpnId, vpnInterface, ifIndex,
230 true, writeConfigTxn, writeOperTxn, writeInvTxn, update);
231 } else if (update.getOperStatus().equals(Interface.OperStatus.Down)) {
232 LOG.info("VPN Interface update event - intfName {} onto vpnName {} running oper-driven"
233 + " DOWN", vpnInterface.getName(), vpnInterface.getVpnInstanceName());
234 InstanceIdentifier<VpnInterface> id = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
235 Optional<VpnInterface> optVpnInterface =
236 VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
237 if (optVpnInterface.isPresent()) {
238 VpnInterface vpnOpInterface = optVpnInterface.get();
239 vpnInterfaceManager.processVpnInterfaceDown(dpnId, interfaceName, ifIndex, update,
240 vpnOpInterface, true, writeConfigTxn, writeOperTxn,
243 LOG.error("InterfaceStateChangeListener Update DOWN - vpnInterface {}"
244 + " not available, ignoring event", vpnInterface.getName());
248 ListenableFuture<Void> operFuture = writeOperTxn.submit();
251 } catch (ExecutionException e) {
252 LOG.error("InterfaceStateChange - Exception encountered while submitting operational"
253 + " future for updateVpnInterface {} : {}", vpnInterface.getName(), e);
256 futures.add(writeConfigTxn.submit());
257 futures.add(writeInvTxn.submit());
259 LOG.debug("Interface {} is not a vpninterface, ignoring.", interfaceName);
265 } catch (Exception e) {
266 LOG.error("Exception observed in handling updation of VPN Interface {}. ", update.getName(), e);