9835ce66426ed4bd6dfe51d2f85ef75c6993695e
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / internal / NatInterfaceStateChangeListener.java
1 /*
2  * Copyright (c) 2016 - 2018 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.netvirt.natservice.internal;
9
10 import java.util.Optional;
11 import javax.annotation.PreDestroy;
12 import javax.inject.Inject;
13 import javax.inject.Singleton;
14 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
15 import org.opendaylight.infrautils.utils.concurrent.Executors;
16 import org.opendaylight.mdsal.binding.api.DataBroker;
17 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
18 import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterface;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.vpn._interface.VpnInstanceNames;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.opendaylight.yangtools.yang.common.Uint64;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 @Singleton
32 public class NatInterfaceStateChangeListener
33     extends AbstractAsyncDataTreeChangeListener<Interface> {
34
35     private static final Logger LOG = LoggerFactory.getLogger(NatInterfaceStateChangeListener.class);
36     private final DataBroker dataBroker;
37     private final NatSouthboundEventHandlers southboundEventHandlers;
38
39     @Inject
40     public NatInterfaceStateChangeListener(final DataBroker dataBroker,
41                                            final NatSouthboundEventHandlers southboundEventHandlers) {
42         super(dataBroker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(InterfacesState.class)
43                 .child(Interface.class),
44                 Executors.newListeningSingleThreadExecutor("NatInterfaceStateChangeListener", LOG));
45         this.dataBroker = dataBroker;
46         this.southboundEventHandlers = southboundEventHandlers;
47     }
48
49     public void init() {
50         LOG.info("{} init", getClass().getSimpleName());
51     }
52
53     @Override
54     @PreDestroy
55     public void close() {
56         super.close();
57         Executors.shutdownAndAwaitTermination(getExecutorService());
58     }
59
60     @Override
61     // TODO Clean up the exception handling
62     @SuppressWarnings("checkstyle:IllegalCatch")
63     public void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
64         LOG.trace("add : Interface {} up event received", intrf);
65         if (!L2vlan.class.equals(intrf.getType())) {
66             LOG.debug("add : Interface {} is not Vlan Interface.Ignoring", intrf.getName());
67             return;
68         }
69         String interfaceName = intrf.getName();
70         Uint64 intfDpnId;
71         try {
72             intfDpnId = NatUtil.getDpIdFromInterface(intrf);
73         } catch (Exception e) {
74             LOG.error("add : Exception occured while retriving dpnid for interface {}", intrf.getName(), e);
75             return;
76         }
77         if (Uint64.ZERO.equals(intfDpnId)) {
78             LOG.warn("add : Could not retrieve dp id for interface {} ", interfaceName);
79             return;
80         }
81         // We service only VM interfaces. We do not service Tunnel Interfaces here.
82         // Tunnel events are directly serviced by TunnelInterfacesStateListener present as part of
83         // VpnInterfaceManager
84         RouterInterface routerInterface = NatUtil.getConfiguredRouterInterface(dataBroker, interfaceName);
85         if (routerInterface != null) {
86             this.southboundEventHandlers.handleAdd(interfaceName, intfDpnId, routerInterface);
87         } else {
88             LOG.info("add : Router-Interface Mapping not found for Interface : {}", interfaceName);
89         }
90     }
91
92     @Override
93     // TODO Clean up the exception handling
94     @SuppressWarnings("checkstyle:IllegalCatch")
95     public void remove(InstanceIdentifier<Interface> identifier, Interface intrf) {
96         LOG.trace("remove : Interface {} removed event received", intrf);
97         if (!L2vlan.class.equals(intrf.getType())) {
98             LOG.debug("remove : Interface {} is not Vlan Interface.Ignoring", intrf.getName());
99             return;
100         }
101         String interfaceName = intrf.getName();
102         Uint64 intfDpnId = Uint64.ZERO;
103         try {
104             intfDpnId = NatUtil.getDpIdFromInterface(intrf);
105         } catch (Exception e) {
106             LOG.error("remove : Exception occured while retriving dpnid for interface {}",  intrf.getName(), e);
107             InstanceIdentifier<VpnInterface> id = NatUtil.getVpnInterfaceIdentifier(interfaceName);
108             Optional<VpnInterface> cfgVpnInterface =
109                     SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
110                             dataBroker, LogicalDatastoreType.CONFIGURATION, id);
111             if (!cfgVpnInterface.isPresent()) {
112                 LOG.warn("remove : Interface {} is not a VPN Interface, ignoring.", interfaceName);
113                 return;
114             }
115             for (VpnInstanceNames vpnInterfaceVpnInstance : cfgVpnInterface.get().nonnullVpnInstanceNames()) {
116                 String vpnName  = vpnInterfaceVpnInstance.getVpnName();
117                 InstanceIdentifier<VpnInterfaceOpDataEntry> idOper = NatUtil
118                       .getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
119                 Optional<VpnInterfaceOpDataEntry> optVpnInterface =
120                       SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
121                             dataBroker, LogicalDatastoreType.OPERATIONAL, idOper);
122                 if (optVpnInterface.isPresent()) {
123                     intfDpnId = optVpnInterface.get().getDpnId();
124                     break;
125                 }
126             }
127         }
128         if (Uint64.ZERO.equals(intfDpnId)) {
129             LOG.warn("remove : Could not retrieve dpnid for interface {} ", interfaceName);
130             return;
131         }
132         RouterInterface routerInterface = NatUtil.getConfiguredRouterInterface(dataBroker, interfaceName);
133         if (routerInterface != null) {
134             this.southboundEventHandlers.handleRemove(intrf.getName(), intfDpnId, routerInterface);
135         } else {
136             LOG.info("remove : Router-Interface Mapping not found for Interface : {}", interfaceName);
137         }
138     }
139
140     @Override
141     // TODO Clean up the exception handling
142     @SuppressWarnings("checkstyle:IllegalCatch")
143     public void update(InstanceIdentifier<Interface> identifier, Interface original, Interface update) {
144         LOG.trace("update : Operation Interface update event - Old: {}, New: {}", original, update);
145         if (!L2vlan.class.equals(update.getType())) {
146             LOG.debug("update : Interface {} is not Vlan Interface.Ignoring", update.getName());
147             return;
148         }
149         Uint64 intfDpnId = Uint64.ZERO;
150         String interfaceName = update.getName();
151         try {
152             intfDpnId = NatUtil.getDpIdFromInterface(update);
153         } catch (Exception e) {
154             LOG.error("update : Exception occured while retriving dpnid for interface {}",  update.getName(), e);
155             InstanceIdentifier<VpnInterface> id = NatUtil.getVpnInterfaceIdentifier(interfaceName);
156             Optional<VpnInterface> cfgVpnInterface =
157                     SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
158                             dataBroker, LogicalDatastoreType.CONFIGURATION, id);
159             if (!cfgVpnInterface.isPresent()) {
160                 LOG.warn("update : Interface {} is not a VPN Interface, ignoring.", interfaceName);
161                 return;
162             }
163             for (VpnInstanceNames vpnInterfaceVpnInstance : cfgVpnInterface.get().nonnullVpnInstanceNames()) {
164                 String vpnName  = vpnInterfaceVpnInstance.getVpnName();
165                 InstanceIdentifier<VpnInterfaceOpDataEntry> idOper = NatUtil
166                       .getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
167                 Optional<VpnInterfaceOpDataEntry> optVpnInterface =
168                       SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
169                             dataBroker, LogicalDatastoreType.OPERATIONAL, idOper);
170                 if (optVpnInterface.isPresent()) {
171                     intfDpnId = optVpnInterface.get().getDpnId();
172                     break;
173                 }
174             }
175         }
176         if (Uint64.ZERO.equals(intfDpnId)) {
177             LOG.warn("remove : Could not retrieve dpnid for interface {} ", interfaceName);
178             return;
179         }
180         RouterInterface routerInterface = NatUtil.getConfiguredRouterInterface(dataBroker, interfaceName);
181         if (routerInterface != null) {
182             this.southboundEventHandlers.handleUpdate(original, update, intfDpnId, routerInterface);
183         } else {
184             LOG.info("update : Router-Interface Mapping not found for Interface : {}", interfaceName);
185         }
186     }
187 }