natservice: drop nullToEmpty and reqNonNullOrElse
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / internal / NatVpnMapsChangeListener.java
1 /*
2  * Copyright (c) 2016 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.genius.infra.Datastore.CONFIGURATION;
11
12 import com.google.common.base.Optional;
13 import java.math.BigInteger;
14 import java.util.Objects;
15 import java.util.concurrent.ExecutionException;
16 import javax.inject.Inject;
17 import javax.inject.Singleton;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
21 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
22 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
23 import org.opendaylight.genius.mdsalutil.MDSALUtil;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 @Singleton
37 public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<VpnMap, NatVpnMapsChangeListener> {
38     private static final Logger LOG = LoggerFactory.getLogger(NatVpnMapsChangeListener.class);
39     private final DataBroker dataBroker;
40     private final ManagedNewTransactionRunner txRunner;
41     private final FloatingIPListener floatingIpListener;
42     private final OdlInterfaceRpcService interfaceManager;
43     private final ExternalRoutersListener externalRoutersListener;
44
45     @Inject
46     public NatVpnMapsChangeListener(final DataBroker dataBroker,
47                                final FloatingIPListener floatingIpListener,
48                                final OdlInterfaceRpcService interfaceManager,
49                                final ExternalRoutersListener externalRoutersListener) {
50         super(VpnMap.class, NatVpnMapsChangeListener.class);
51         this.dataBroker = dataBroker;
52         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
53         this.floatingIpListener = floatingIpListener;
54         this.interfaceManager = interfaceManager;
55         this.externalRoutersListener = externalRoutersListener;
56     }
57
58     public void init() {
59         LOG.info("{} init", getClass().getSimpleName());
60         registerListener(dataBroker);
61     }
62
63     @Override
64     protected InstanceIdentifier<VpnMap> getWildCardPath() {
65         return InstanceIdentifier.create(VpnMaps.class).child(VpnMap.class);
66     }
67
68     private void registerListener(final DataBroker db) {
69         registerListener(LogicalDatastoreType.CONFIGURATION, db);
70     }
71
72     @Override
73     protected void add(InstanceIdentifier<VpnMap> identifier, VpnMap vpnMap) {
74         Uuid vpnUuid = vpnMap.getVpnId();
75         String vpnName = vpnUuid.getValue();
76         vpnMap.getRouterIds().stream()
77                 .filter(router -> !(Objects.equals(router.getRouterId(), vpnUuid)))
78                 .forEach(router -> {
79                     String routerName = router.getRouterId().getValue();
80                     LOG.info("REMOVE: Router {} is disassociated from Vpn {}", routerName, vpnName);
81                     onRouterAssociatedToVpn(vpnName, routerName);
82                 });
83     }
84
85     @Override
86     protected void remove(InstanceIdentifier<VpnMap> identifier, VpnMap vpnMap) {
87         Uuid vpnUuid = vpnMap.getVpnId();
88         String vpnName = vpnUuid.getValue();
89         vpnMap.getRouterIds().stream()
90                 .filter(router -> !(Objects.equals(router.getRouterId(), vpnUuid)))
91                 .forEach(router -> {
92                     String routerName = router.getRouterId().getValue();
93                     LOG.info("REMOVE: Router {} is disassociated from Vpn {}", routerName, vpnName);
94                     onRouterDisassociatedFromVpn(vpnName, routerName);
95                 });
96     }
97
98     @Override
99     protected void update(InstanceIdentifier<VpnMap> identifier, VpnMap original, VpnMap updated) {
100         Uuid vpnUuid = updated.getVpnId();
101         String vpnName = vpnUuid.getValue();
102
103         updated.getRouterIds().stream()
104                 .filter(router -> ! original.getRouterIds().contains(router))
105                 .filter(router -> !(Objects.equals(router.getRouterId(), updated.getVpnId())))
106                 .forEach(router -> {
107                     String routerName = router.getRouterId().getValue();
108                     onRouterAssociatedToVpn(vpnName, routerName);
109                 });
110
111         original.getRouterIds().stream()
112                 .filter(router -> ! updated.getRouterIds().contains(router))
113                 .filter(router -> !(Objects.equals(router.getRouterId(), original.getVpnId())))
114                 .forEach(router -> {
115                     String routerName = router.getRouterId().getValue();
116                     onRouterDisassociatedFromVpn(vpnName, routerName);
117                 });
118     }
119
120     @Override
121     protected NatVpnMapsChangeListener getDataTreeChangeListener() {
122         return this;
123     }
124
125     public void onRouterAssociatedToVpn(String vpnName, String routerName) {
126
127         //check router is associated to external network
128         String extNetwork = NatUtil.getAssociatedExternalNetwork(dataBroker, routerName);
129         if (extNetwork != null) {
130             try {
131                 LOG.debug("onRouterAssociatedToVpn : Router {} is associated with ext nw {}", routerName, extNetwork);
132                 handleDNATConfigurationForRouterAssociation(routerName, vpnName, extNetwork);
133                 Uuid extNetworkUuid = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
134                 if (extNetworkUuid == null) {
135                     LOG.error("onRouterAssociatedToVpn : Unable to retrieve external network Uuid for router {}",
136                             routerName);
137                     return;
138                 }
139                 ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName,
140                         extNetworkUuid);
141                 if (extNwProvType == null) {
142                     LOG.error("onRouterAssociatedToVpn : External Network Provider Type missing");
143                     return;
144                 }
145                 long routerId = NatUtil.getVpnId(dataBroker, routerName);
146                 txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
147                     tx -> externalRoutersListener.changeLocalVpnIdToBgpVpnId(routerName, routerId, vpnName, tx,
148                                 extNwProvType)).get();
149             } catch (InterruptedException | ExecutionException e) {
150                 LOG.error("Error changling local VPN identifier to BGP VPN identifier", e);
151             }
152         } else {
153             LOG.debug("onRouterAssociatedToVpn : Ignoring the Router {} association with VPN {} "
154                     + "since it is not external router", routerName, vpnName);
155         }
156     }
157
158     /**
159      * router disassociation from vpn.
160      */
161
162     public void onRouterDisassociatedFromVpn(String vpnName, String routerName) {
163
164         //check router is associated to external network
165         String extNetwork = NatUtil.getAssociatedExternalNetwork(dataBroker, routerName);
166         if (extNetwork != null) {
167             try {
168                 LOG.debug("onRouterDisassociatedFromVpn : Router {} is associated with ext nw {}", routerName,
169                         extNetwork);
170                 handleDNATConfigurationForRouterDisassociation(routerName, vpnName, extNetwork);
171                 Uuid extNetworkUuid = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
172                 if (extNetworkUuid == null) {
173                     LOG.error("onRouterDisassociatedFromVpn : Unable to retrieve external network Uuid for router {}",
174                             routerName);
175                     return;
176                 }
177                 ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName,
178                         extNetworkUuid);
179                 if (extNwProvType == null) {
180                     LOG.error("onRouterDisassociatedFromVpn : External Network Provider Type missing");
181                     return;
182                 }
183                 long routerId = NatUtil.getVpnId(dataBroker, routerName);
184                 txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
185                     tx -> externalRoutersListener.changeBgpVpnIdToLocalVpnId(routerName, routerId, vpnName, tx,
186                                 extNwProvType)).get();
187             } catch (InterruptedException | ExecutionException e) {
188                 LOG.error("Error changing BGP VPN identifier to local VPN identifier", e);
189             }
190         } else {
191             LOG.debug("onRouterDisassociatedFromVpn : Ignoring the Router {} association with VPN {} "
192                     + "since it is not external router", routerName, vpnName);
193         }
194     }
195
196     void handleDNATConfigurationForRouterAssociation(String routerName, String vpnName, String externalNetwork)
197             throws ExecutionException, InterruptedException {
198         InstanceIdentifier<RouterPorts> routerPortsId = NatUtil.getRouterPortsId(routerName);
199         Optional<RouterPorts> optRouterPorts =
200                 MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerPortsId);
201         if (!optRouterPorts.isPresent()) {
202             LOG.debug("handleDNATConfigurationForRouterAssociation : Could not read Router Ports data "
203                     + "object with id: {} to handle associate vpn {}", routerName, vpnName);
204             return;
205         }
206         Uuid networkId = Uuid.getDefaultInstance(externalNetwork);
207         for (Ports port : optRouterPorts.get().nonnullPorts()) {
208             String portName = port.getPortName();
209             BigInteger dpnId = NatUtil.getDpnForInterface(interfaceManager, portName);
210             if (dpnId.equals(BigInteger.ZERO)) {
211                 LOG.warn("handleDNATConfigurationForRouterAssociation : DPN not found for {}, "
212                         + "skip handling of router {} association with vpn {}", portName, routerName, vpnName);
213                 continue;
214             }
215
216             for (InternalToExternalPortMap intExtPortMap : port.nonnullInternalToExternalPortMap()) {
217                 //remove all NAT related entries with routerName
218                 //floatingIpListener.removeNATOnlyFlowEntries(dpnId, portName, routerName, null,
219                 // intExtPortMap.getInternalIp(), externalIp);
220                 //Create NAT entries with VPN Id
221                 LOG.debug("handleDNATConfigurationForRouterAssociation : Updating DNAT flows with VPN metadata {} ",
222                         vpnName);
223                 floatingIpListener.createNATOnlyFlowEntries(dpnId, routerName, vpnName, networkId, intExtPortMap);
224             }
225         }
226     }
227
228     void handleDNATConfigurationForRouterDisassociation(String routerName, String vpnName, String externalNetwork)
229             throws ExecutionException, InterruptedException {
230         InstanceIdentifier<RouterPorts> routerPortsId = NatUtil.getRouterPortsId(routerName);
231         Optional<RouterPorts> optRouterPorts =
232                 MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerPortsId);
233         if (!optRouterPorts.isPresent()) {
234             LOG.error("handleDNATConfigurationForRouterDisassociation : Could not read Router Ports "
235                     + "data object with id: {} to handle disassociate vpn {}", routerName, vpnName);
236             return;
237         }
238         Uuid networkId = Uuid.getDefaultInstance(externalNetwork);
239         for (Ports port : optRouterPorts.get().nonnullPorts()) {
240             String portName = port.getPortName();
241             BigInteger dpnId = NatUtil.getDpnForInterface(interfaceManager, portName);
242             if (dpnId.equals(BigInteger.ZERO)) {
243                 LOG.debug("handleDNATConfigurationForRouterDisassociation : DPN not found for {}, "
244                         + "skip handling of router {} association with vpn {}", portName, routerName, vpnName);
245                 continue;
246             }
247             for (InternalToExternalPortMap intExtPortMap : port.nonnullInternalToExternalPortMap()) {
248                 //remove all NAT related entries with routerName
249                 //floatingIpListener.removeNATOnlyFlowEntries(dpnId, portName, routerName, vpnName,
250                 // intExtPortMap.getInternalIp(), externalIp);
251                 //Create NAT entries with VPN Id
252                 floatingIpListener.createNATOnlyFlowEntries(dpnId, routerName, null, networkId, intExtPortMap);
253             }
254         }
255     }
256
257 }