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