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 static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
12 import com.google.common.base.Optional;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.List;
17 import javax.annotation.PostConstruct;
18 import javax.inject.Inject;
19 import javax.inject.Singleton;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
23 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
24 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
25 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
26 import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils;
27 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
37 public class InterfaceStateChangeListener
38 extends AsyncDataTreeChangeListenerBase<Interface, InterfaceStateChangeListener> {
40 private static final Logger LOG = LoggerFactory.getLogger(InterfaceStateChangeListener.class);
42 private final DataBroker dataBroker;
43 private final ManagedNewTransactionRunner txRunner;
44 private final VpnInterfaceManager vpnInterfaceManager;
45 private final JobCoordinator jobCoordinator;
48 public InterfaceStateChangeListener(final DataBroker dataBroker, final VpnInterfaceManager vpnInterfaceManager,
49 final JobCoordinator jobCoordinator) {
50 super(Interface.class, InterfaceStateChangeListener.class);
51 this.dataBroker = dataBroker;
52 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
53 this.vpnInterfaceManager = vpnInterfaceManager;
54 this.jobCoordinator = jobCoordinator;
59 LOG.info("{} start", getClass().getSimpleName());
60 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
65 protected InstanceIdentifier<Interface> getWildCardPath() {
66 return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
70 protected InterfaceStateChangeListener getDataTreeChangeListener() {
71 return InterfaceStateChangeListener.this;
76 // TODO Clean up the exception handling
77 @SuppressWarnings("checkstyle:IllegalCatch")
78 protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
80 if (L2vlan.class.equals(intrf.getType())) {
81 LOG.info("VPN Interface add event - intfName {} from InterfaceStateChangeListener",
83 jobCoordinator.enqueueJob("VPNINTERFACE-" + intrf.getName(), () -> {
84 List<ListenableFuture<Void>> futures = new ArrayList<>(3);
85 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeOperTxn -> {
86 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeConfigTxn -> {
87 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeInvTxn -> {
89 final String interfaceName = intrf.getName();
90 LOG.info("Detected interface add event for interface {}", interfaceName);
92 final VpnInterface vpnIf =
93 VpnUtil.getConfiguredVpnInterface(dataBroker, interfaceName);
95 String primaryRd = VpnUtil.getPrimaryRd(dataBroker,
96 vpnIf.getVpnInstanceName());
97 if (!VpnUtil.isVpnPendingDelete(dataBroker, primaryRd)) {
98 LOG.debug("VPN Interface Name {}", vpnIf);
99 BigInteger intfDpnId = BigInteger.ZERO;
101 intfDpnId = InterfaceUtils.getDpIdFromInterface(intrf);
102 } catch (Exception e) {
103 LOG.error("Unable to retrieve dpnId for interface {}. "
104 + "Process vpn interface add failed",intrf.getName(), e);
107 final BigInteger dpnId = intfDpnId;
108 final int ifIndex = intrf.getIfIndex();
109 if (!vpnInterfaceManager.isVpnInstanceReady(vpnIf.getVpnInstanceName())) {
110 LOG.error("VPN Interface add event - intfName {} onto vpnName {} "
111 + "running oper-driven, VpnInstance not ready, holding on",
112 vpnIf.getName(), vpnIf.getVpnInstanceName());
115 LOG.info("VPN Interface add event - intfName {} onto vpnName {} running "
116 + "oper-driven", vpnIf.getName(), vpnIf.getVpnInstanceName());
117 vpnInterfaceManager.processVpnInterfaceUp(dpnId, vpnIf, primaryRd, ifIndex,
118 false, writeConfigTxn, writeOperTxn, writeInvTxn, intrf);
120 LOG.error("add: Ignoring addition of vpnInterface {}, as vpnInstance {}"
121 + " with primaryRd {} is already marked for deletion", interfaceName,
122 vpnIf.getVpnInstanceName(), primaryRd);
131 } catch (Exception e) {
132 LOG.error("Exception caught in Interface {} Operational State Up event", intrf.getName(), e);
137 // TODO Clean up the exception handling
138 @SuppressWarnings("checkstyle:IllegalCatch")
139 protected void remove(InstanceIdentifier<Interface> identifier, Interface intrf) {
140 final String ifName = intrf.getName();
141 BigInteger dpId = BigInteger.ZERO;
143 if (L2vlan.class.equals(intrf.getType())) {
144 LOG.info("VPN Interface remove event - intfName {} from InterfaceStateChangeListener",
147 dpId = InterfaceUtils.getDpIdFromInterface(intrf);
148 } catch (Exception e) {
149 LOG.error("Unable to retrieve dpnId from interface operational data store for interface"
150 + " {}. Fetching from vpn interface op data store. ", ifName, e);
152 final BigInteger inputDpId = dpId;
153 jobCoordinator.enqueueJob("VPNINTERFACE-" + ifName, () -> {
154 List<ListenableFuture<Void>> futures = new ArrayList<>(3);
155 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeOperTxn -> {
156 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeConfigTxn -> {
157 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeInvTxn -> {
158 InstanceIdentifier<VpnInterface> id = VpnUtil.getVpnInterfaceIdentifier(ifName);
159 Optional<VpnInterface> optVpnInterface = VpnUtil.read(dataBroker, OPERATIONAL, id);
160 if (optVpnInterface.isPresent()) {
161 final VpnInterface vpnInterface = optVpnInterface.get();
162 BigInteger dpnId = inputDpId;
163 if (dpnId == null || dpnId.equals(BigInteger.ZERO)) {
164 dpnId = vpnInterface.getDpnId();
166 final int ifIndex = intrf.getIfIndex();
167 LOG.info("VPN Interface remove event - intfName {} onto vpnName {} "
168 + "running oper-driven", vpnInterface.getName(),
169 vpnInterface.getVpnInstanceName());
170 vpnInterfaceManager.processVpnInterfaceDown(dpnId, ifName, ifIndex, intrf,
171 vpnInterface, false, writeConfigTxn, writeOperTxn, writeInvTxn);
173 LOG.debug("Interface {} is not a vpninterface, ignoring.", ifName);
181 } catch (Exception e) {
182 LOG.error("Exception observed in handling deletion of VPN Interface {}. ", ifName, e);
186 // TODO Clean up the exception handling
187 @SuppressWarnings("checkstyle:IllegalCatch")
189 protected void update(InstanceIdentifier<Interface> identifier,
190 Interface original, Interface update) {
191 final String ifName = update.getName();
193 OperStatus originalOperStatus = original.getOperStatus();
194 OperStatus updateOperStatus = update.getOperStatus();
195 if (originalOperStatus.equals(Interface.OperStatus.Unknown)
196 || updateOperStatus.equals(Interface.OperStatus.Unknown)) {
197 LOG.debug("Interface {} state change is from/to null/UNKNOWN. Ignoring the update event.",
202 if (update.getIfIndex() == null) {
205 if (L2vlan.class.equals(update.getType())) {
206 LOG.info("VPN Interface update event - intfName {} from InterfaceStateChangeListener",
208 jobCoordinator.enqueueJob("VPNINTERFACE-" + ifName, () -> {
209 List<ListenableFuture<Void>> futures = new ArrayList<>(3);
210 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeOperTxn -> {
211 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeConfigTxn -> {
212 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeInvTxn -> {
214 final VpnInterface vpnIf =
215 VpnUtil.getConfiguredVpnInterface(dataBroker, ifName);
217 final int ifIndex = update.getIfIndex();
218 final BigInteger dpnId = InterfaceUtils.getDpIdFromInterface(update);
219 if (update.getOperStatus().equals(Interface.OperStatus.Up)) {
220 String primaryRd = VpnUtil.getPrimaryRd(dataBroker,
221 vpnIf.getVpnInstanceName());
222 if (!VpnUtil.isVpnPendingDelete(dataBroker, primaryRd)) {
223 LOG.info("VPN Interface update event - intfName {} onto vpnName {} running "
224 + " oper-driven UP", vpnIf.getName(),
225 vpnIf.getVpnInstanceName());
226 if (!vpnInterfaceManager.isVpnInstanceReady(vpnIf.getVpnInstanceName())) {
227 LOG.error("VPN Interface update event - intfName {} onto vpnName {} "
228 + "running oper-driven UP, VpnInstance not ready, holding on",
229 vpnIf.getName(), vpnIf.getVpnInstanceName());
232 vpnInterfaceManager.processVpnInterfaceUp(dpnId, vpnIf, primaryRd, ifIndex,
233 true, writeConfigTxn, writeOperTxn, writeInvTxn, update);
235 LOG.error("update: Ignoring UP event for vpnInterface {}, as vpnInstance {}"
236 + " with primaryRd {} is already marked for deletion",
237 ifName, vpnIf.getVpnInstanceName(), primaryRd);
239 } else if (update.getOperStatus().equals(Interface.OperStatus.Down)) {
240 LOG.info("VPN Interface update event - intfName {} onto vpnName {} running "
241 + "oper-driven DOWN", vpnIf.getName(), vpnIf.getVpnInstanceName());
242 InstanceIdentifier<VpnInterface> id = VpnUtil.getVpnInterfaceIdentifier(ifName);
243 Optional<VpnInterface> optVpnInterface =
244 VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
245 if (optVpnInterface.isPresent()) {
246 VpnInterface vpnOpInterface = optVpnInterface.get();
247 vpnInterfaceManager.processVpnInterfaceDown(dpnId, ifName, ifIndex, update,
248 vpnOpInterface, true, writeConfigTxn, writeOperTxn,
251 LOG.error("InterfaceStateChangeListener Update DOWN - vpnInterface {}"
252 + " not available, ignoring event", vpnIf.getName());
257 LOG.debug("Interface {} is not a vpninterface, ignoring.", ifName);
265 } catch (Exception e) {
266 LOG.error("Exception observed in handling updation of VPN Interface {}. ", update.getName(), e);