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