neutronvpn dead code removal
[netvirt.git] / neutronvpn / impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronvpnNatManager.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.neutronvpn;
9
10 import com.google.common.base.Optional;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Objects;
17 import java.util.Set;
18 import javax.annotation.PreDestroy;
19 import javax.inject.Inject;
20 import javax.inject.Singleton;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
25 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
26 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
27 import org.opendaylight.netvirt.elanmanager.api.IElanService;
28 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
29 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
30 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
31 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.ExternalGatewayInfo;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.external_gateway_info.ExternalFixedIps;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
63 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66
67 @Singleton
68 public class NeutronvpnNatManager implements AutoCloseable {
69     private static final Logger LOG = LoggerFactory.getLogger(NeutronvpnNatManager.class);
70     private static final int EXTERNAL_NO_CHANGE = 0;
71     private static final int EXTERNAL_ADDED = 1;
72     private static final int EXTERNAL_REMOVED = 2;
73     private static final int EXTERNAL_CHANGED = 3;
74
75     private final DataBroker dataBroker;
76     private final NeutronvpnUtils neutronvpnUtils;
77     private final IElanService elanService;
78
79     @Inject
80     public NeutronvpnNatManager(final DataBroker dataBroker, final NeutronvpnUtils neutronvpnUtils,
81                                 final IElanService elanService) {
82         this.dataBroker = dataBroker;
83         this.neutronvpnUtils = neutronvpnUtils;
84         this.elanService = elanService;
85     }
86
87     @Override
88     @PreDestroy
89     public void close() {
90         LOG.info("{} close", getClass().getSimpleName());
91     }
92
93     public void handleExternalNetworkForRouter(@Nullable Router original, Router update) {
94         Uuid routerId = update.getUuid();
95         Uuid origExtNetId = null;
96         Uuid updExtNetId = null;
97         List<ExternalFixedIps> origExtFixedIps;
98
99         LOG.trace("handleExternalNetwork for router {}", routerId);
100         int extNetChanged = externalNetworkChanged(original, update);
101         if (extNetChanged != EXTERNAL_NO_CHANGE) {
102             if (extNetChanged == EXTERNAL_ADDED) {
103                 updExtNetId = update.getExternalGatewayInfo().getExternalNetworkId();
104                 LOG.trace("External Network {} addition detected for router {}", updExtNetId.getValue(),
105                         routerId.getValue());
106                 addExternalNetworkToRouter(update);
107                 return;
108             }
109             if (extNetChanged == EXTERNAL_REMOVED) {
110                 origExtNetId = original.getExternalGatewayInfo().getExternalNetworkId();
111                 origExtFixedIps = original.getExternalGatewayInfo().getExternalFixedIps();
112                 LOG.trace("External Network removal detected for router {}", routerId.getValue());
113                 removeExternalNetworkFromRouter(origExtNetId, update, origExtFixedIps);
114                 //gateway mac unset handled as part of gateway clear deleting top-level routers node
115                 return;
116             }
117
118             origExtNetId = original.getExternalGatewayInfo().getExternalNetworkId();
119             origExtFixedIps = original.getExternalGatewayInfo().getExternalFixedIps();
120             updExtNetId = update.getExternalGatewayInfo().getExternalNetworkId();
121             LOG.trace("External Network changed from {} to {} for router {}",
122                 origExtNetId.getValue(), updExtNetId.getValue(), routerId.getValue());
123             removeExternalNetworkFromRouter(origExtNetId, update, origExtFixedIps);
124             addExternalNetworkToRouter(update);
125             return;
126         }
127
128         if (snatSettingChanged(original, update)) {
129             LOG.trace("SNAT settings on gateway changed for router {}", routerId.getValue());
130             handleSnatSettingChangeForRouter(update);
131         }
132
133         if (externalFixedIpsChanged(original, update)) {
134             LOG.trace("External Fixed IPs changed for router {}", routerId.getValue());
135             handleExternalFixedIpsForRouter(update);
136         }
137     }
138
139     private static int externalNetworkChanged(Router original, Router update) {
140         String origExtNet = null;
141         String newExtNet = null;
142         if (original != null && original.getExternalGatewayInfo() != null) {
143             origExtNet = original.getExternalGatewayInfo().getExternalNetworkId().getValue();
144         }
145
146         if (update != null && update.getExternalGatewayInfo() != null) {
147             newExtNet = update.getExternalGatewayInfo().getExternalNetworkId().getValue();
148         }
149
150         if (origExtNet == null) {
151             if (newExtNet == null) {
152                 return EXTERNAL_NO_CHANGE;
153             }
154             return EXTERNAL_ADDED;
155         } else {
156             if (newExtNet == null) {
157                 return EXTERNAL_REMOVED;
158             }
159             if (!origExtNet.equals(newExtNet)) {
160                 return EXTERNAL_CHANGED;
161             }
162             return EXTERNAL_NO_CHANGE;
163         }
164     }
165
166     private static boolean snatSettingChanged(Router orig, Router update) {
167         ExternalGatewayInfo origExtGw = null;
168         ExternalGatewayInfo newExtGw = null;
169         if (orig != null && orig.getExternalGatewayInfo() != null) {
170             origExtGw = orig.getExternalGatewayInfo();
171         }
172
173         if (update != null && update.getExternalGatewayInfo() != null) {
174             newExtGw = update.getExternalGatewayInfo();
175         }
176
177         if (origExtGw == null) {
178             if (newExtGw != null) {
179                 return true;
180             }
181         } else if (newExtGw == null || !Objects.equals(origExtGw.isEnableSnat(), newExtGw.isEnableSnat())) {
182             return true;
183         }
184         return false;
185     }
186
187     private static boolean externalFixedIpsChanged(Router orig, Router update) {
188         ExternalGatewayInfo origExtGw = null;
189         ExternalGatewayInfo newExtGw = null;
190         if (orig != null && orig.getExternalGatewayInfo() != null) {
191             origExtGw = orig.getExternalGatewayInfo();
192         }
193
194         if (update != null && update.getExternalGatewayInfo() != null) {
195             newExtGw = update.getExternalGatewayInfo();
196         }
197
198         if (origExtGw == null && newExtGw != null && newExtGw.getExternalFixedIps() != null && !newExtGw
199                 .getExternalFixedIps().isEmpty()) {
200             return true;
201         }
202
203         if (newExtGw == null && origExtGw != null && origExtGw.getExternalFixedIps() != null && !origExtGw
204                 .getExternalFixedIps().isEmpty()) {
205             return true;
206         }
207
208         if (origExtGw != null && newExtGw != null) {
209             if (origExtGw.getExternalFixedIps() != null) {
210                 if (!origExtGw.getExternalFixedIps().isEmpty()) {
211                     if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
212                         List<ExternalFixedIps> origExtFixedIps = origExtGw.getExternalFixedIps();
213                         HashSet<String> origFixedIpSet = new HashSet<>();
214                         for (ExternalFixedIps fixedIps : origExtFixedIps) {
215                             origFixedIpSet.add(fixedIps.getIpAddress().stringValue());
216                         }
217                         List<ExternalFixedIps> newExtFixedIps = newExtGw.getExternalFixedIps();
218                         HashSet<String> updFixedIpSet = new HashSet<>();
219                         for (ExternalFixedIps fixedIps : newExtFixedIps) {
220                             updFixedIpSet.add(fixedIps.getIpAddress().stringValue());
221                         }
222                         // returns true if external subnets have changed
223                         return !origFixedIpSet.equals(updFixedIpSet) ? true : false;
224                     }
225                     return true;
226                 } else if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
227                     return true;
228                 }
229             } else if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
230                 return true;
231             }
232         }
233         return false;
234     }
235
236     public void addExternalNetwork(Network net) {
237         Uuid extNetId = net.getUuid();
238
239         // Create and add Networks object for this External Network to the ExternalNetworks list
240         InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
241             .child(Networks.class, new NetworksKey(extNetId)).build();
242
243         try {
244             LOG.trace(" Creating/Updating a new Networks node {}", extNetId.getValue());
245             Optional<Networks> optionalNets =
246                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
247                             netsIdentifier);
248             if (optionalNets.isPresent()) {
249                 LOG.error("External Network {} already detected to be present", extNetId.getValue());
250                 return;
251             }
252             ProviderTypes provType = NeutronvpnUtils.getProviderNetworkType(net);
253             if (provType == null) {
254                 LOG.error("Unable to get Network Provider Type for network {}", extNetId);
255                 return;
256             }
257             NetworksBuilder builder = null;
258             builder = new NetworksBuilder().withKey(new NetworksKey(extNetId)).setId(extNetId);
259             builder.setVpnid(neutronvpnUtils.getVpnForNetwork(extNetId));
260             builder.setRouterIds(new ArrayList<>());
261             builder.setProviderNetworkType(provType);
262
263             Networks networkss = builder.build();
264             // Add Networks object to the ExternalNetworks list
265             LOG.trace("Creating externalnetworks {}", networkss);
266             SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier,
267                     networkss);
268             LOG.trace("Wrote externalnetwork successfully to CONFIG Datastore");
269         } catch (TransactionCommitFailedException | ReadFailedException ex) {
270             LOG.error("Creation of External Network {} failed", extNetId.getValue(), ex);
271         }
272     }
273
274     public void removeExternalNetwork(Network net) {
275         Uuid extNetId = net.getUuid();
276
277         // Create and add Networks object for this External Network to the ExternalNetworks list
278         InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
279             .child(Networks.class, new NetworksKey(extNetId)).build();
280
281         try {
282             Optional<Networks> optionalNets =
283                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
284                             netsIdentifier);
285             LOG.trace("Removing Networks node {}", extNetId.getValue());
286             if (!optionalNets.isPresent()) {
287                 LOG.error("External Network {} not available in the datastore", extNetId.getValue());
288                 return;
289             }
290             // Delete Networks object from the ExternalNetworks list
291             LOG.trace("Deleting External Network {}", extNetId.getValue());
292             SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier);
293             LOG.trace("Deleted External Network {} successfully from CONFIG Datastore", extNetId.getValue());
294
295         } catch (TransactionCommitFailedException | ReadFailedException ex) {
296             LOG.error("Deletion of External Network {} failed", extNetId.getValue(), ex);
297         }
298     }
299
300     private void addExternalNetworkToRouter(Router update) {
301         Uuid routerId = update.getUuid();
302         Uuid extNetId = update.getExternalGatewayInfo().getExternalNetworkId();
303         List<ExternalFixedIps> externalFixedIps = update.getExternalGatewayInfo().getExternalFixedIps();
304
305         try {
306             Network input = neutronvpnUtils.getNeutronNetwork(extNetId);
307             ProviderTypes providerNwType = NeutronvpnUtils.getProviderNetworkType(input);
308             if (providerNwType == null) {
309                 LOG.error("Unable to get Network Provider Type for network {}", input.getUuid().getValue());
310                 return;
311             }
312             // Add this router to the ExtRouters list
313             addExternalRouter(update);
314
315             // Update External Subnets for this router
316             updateExternalSubnetsForRouter(routerId, extNetId, externalFixedIps);
317
318             // Create and add Networks object for this External Network to the ExternalNetworks list
319             InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
320                 .child(Networks.class, new NetworksKey(extNetId)).build();
321
322             Optional<Networks> optionalNets =
323                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
324                             netsIdentifier);
325             if (!optionalNets.isPresent()) {
326                 LOG.error("External Network {} not present in the NVPN datamodel", extNetId.getValue());
327                 return;
328             }
329             NetworksBuilder builder = new NetworksBuilder(optionalNets.get());
330             List<Uuid> rtrList = builder.getRouterIds();
331             if (rtrList == null) {
332                 rtrList = new ArrayList<>();
333             }
334             rtrList.add(routerId);
335             builder.setRouterIds(rtrList);
336             if (NeutronvpnUtils.isFlatOrVlanNetwork(input)) {
337                 builder.setVpnid(extNetId);
338             }
339
340             Networks networkss = builder.build();
341             // Add Networks object to the ExternalNetworks list
342             LOG.trace("Updating externalnetworks {}", networkss);
343             SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier,
344                     networkss);
345             LOG.trace("Updated externalnetworks successfully to CONFIG Datastore");
346         } catch (TransactionCommitFailedException | ReadFailedException ex) {
347             LOG.error("Creation of externalnetworks failed for {}",
348                 extNetId.getValue(), ex);
349         }
350     }
351
352     public void removeExternalNetworkFromRouter(Uuid origExtNetId, Router update,
353             List<ExternalFixedIps> origExtFixedIps) {
354         Uuid routerId = update.getUuid();
355
356         // Remove the router to the ExtRouters list
357         removeExternalRouter(update);
358
359         //Remove router entry from floating-ip-info list
360         removeRouterFromFloatingIpInfo(update, dataBroker);
361
362         // Remove the router from External Subnets
363         removeRouterFromExternalSubnets(routerId, origExtNetId, origExtFixedIps);
364
365         // Remove the router from the ExternalNetworks list
366         InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
367             .child(Networks.class, new NetworksKey(origExtNetId)).build();
368         Optional<Networks> optionalNets = null;
369         try {
370             optionalNets = SingleTransactionDataBroker.syncReadOptional(dataBroker,
371                                             LogicalDatastoreType.CONFIGURATION, netsIdentifier);
372         } catch (ReadFailedException ex) {
373             LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
374                       origExtNetId.getValue(), routerId.getValue(), ex);
375             return;
376         }
377         if (!optionalNets.isPresent()) {
378             LOG.error("removeExternalNetworkFromRouter: Provider Network {} not present in the NVPN datamodel",
379                       origExtNetId.getValue());
380             return;
381         }
382         Networks nets = optionalNets.get();
383         try {
384             NetworksBuilder builder = new NetworksBuilder(nets);
385             List<Uuid> rtrList = builder.getRouterIds();
386             if (rtrList != null) {
387                 rtrList.remove(routerId);
388                 builder.setRouterIds(rtrList);
389                 Networks networkss = builder.build();
390                 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
391                         netsIdentifier, networkss);
392                 LOG.trace("removeExternalNetworkFromRouter: Remove router {} from External Networks node {}",
393                           routerId, origExtNetId.getValue());
394             }
395         } catch (TransactionCommitFailedException ex) {
396             LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
397                       origExtNetId.getValue(), routerId.getValue(), ex);
398         }
399     }
400
401     public void addExternalRouter(Router update) {
402         Uuid routerId = update.getUuid();
403         Uuid extNetId = update.getExternalGatewayInfo().getExternalNetworkId();
404         Uuid gatewayPortId = update.getGatewayPortId();
405         // Create and add Routers object for this Router to the ExtRouters list
406
407         // Create a Routers object
408         InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
409
410         try {
411             Network input = neutronvpnUtils.getNeutronNetwork(extNetId);
412             ProviderTypes providerNwType = NeutronvpnUtils.getProviderNetworkType(input);
413             if (providerNwType == null) {
414                 LOG.error("Unable to get Network Provider Type for network {}", input.getUuid().getValue());
415                 return;
416             }
417             Optional<Routers> optionalRouters =
418                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
419                             routersIdentifier);
420             LOG.trace("Creating/Updating a new Routers node: {}", routerId.getValue());
421             RoutersBuilder builder = null;
422             if (optionalRouters.isPresent()) {
423                 builder = new RoutersBuilder(optionalRouters.get());
424             } else {
425                 builder = new RoutersBuilder().withKey(new RoutersKey(routerId.getValue()));
426             }
427             builder.setRouterName(routerId.getValue());
428             builder.setNetworkId(extNetId);
429             builder.setEnableSnat(update.getExternalGatewayInfo().isEnableSnat());
430
431             ArrayList<ExternalIps> externalIps = new ArrayList<>();
432             for (ExternalFixedIps fixedIps : update.getExternalGatewayInfo().nonnullExternalFixedIps()) {
433                 addExternalFixedIpToExternalIpsList(externalIps, fixedIps);
434             }
435             builder.setExternalIps(externalIps);
436
437             if (gatewayPortId != null) {
438                 LOG.trace("Setting/Updating gateway Mac for router {}", routerId.getValue());
439                 Port port = neutronvpnUtils.getNeutronPort(gatewayPortId);
440                 if (port != null && port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_GATEWAY_INF)) {
441                     builder.setExtGwMacAddress(port.getMacAddress().getValue());
442                 }
443             }
444             List<Uuid> subList = neutronvpnUtils.getNeutronRouterSubnetIds(routerId);
445             builder.setSubnetIds(subList);
446             Routers routers = builder.build();
447             // Add Routers object to the ExtRouters list
448             LOG.trace("Creating extrouters {}", routers);
449             SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routersIdentifier,
450                     builder.build());
451             LOG.trace("Wrote successfully Routers to CONFIG Datastore");
452
453         } catch (ReadFailedException | TransactionCommitFailedException ex) {
454             LOG.error("Creation of extrouters failed for router {} failed",
455                 routerId.getValue(), ex);
456         }
457     }
458
459     // TODO Clean up the exception handling
460     @SuppressWarnings("checkstyle:IllegalCatch")
461     private void removeExternalRouter(Router update) {
462         Uuid routerId = update.getUuid();
463
464         InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
465
466         try {
467             Optional<Routers> optionalRouters =
468                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
469                             routersIdentifier);
470             LOG.trace(" Removing Routers node {}", routerId.getValue());
471             if (optionalRouters.isPresent()) {
472                 RoutersBuilder builder = new RoutersBuilder(optionalRouters.get());
473                 builder.setExternalIps(null);
474                 builder.setSubnetIds(null);
475                 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
476                         routersIdentifier);
477                 LOG.trace("Removed router {} from extrouters", routerId.getValue());
478             }
479         } catch (TransactionCommitFailedException | ReadFailedException ex) {
480             LOG.error("Removing extrouter {} from extrouters failed", routerId.getValue(), ex);
481         }
482     }
483
484     public void removeNeutronRouterDpns(Router router) {
485         Uuid routerId = router.getUuid();
486         InstanceIdentifier<RouterDpnList> iid = InstanceIdentifier.builder(NeutronRouterDpns.class)
487                 .child(RouterDpnList.class, new RouterDpnListKey(routerId.getValue())).build();
488         neutronvpnUtils.asyncReadAndExecute(LogicalDatastoreType.OPERATIONAL, iid, router.getUuid().toString(),
489             (routerDpnListOptional) -> {
490                 if (routerDpnListOptional.isPresent()) {
491                     if (routerDpnListOptional.get().getDpnVpninterfacesList() != null) {
492                         routerDpnListOptional.get().getDpnVpninterfacesList().stream()
493                                 .filter((dpnList) -> (dpnList != null))
494                                 .forEach((dpnList) -> {
495                                     LOG.warn("DPN {} presence exists while deleting router instance {}",
496                                             dpnList.getDpnId(), routerId);
497                                 });
498                         try {
499                             SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, iid);
500                         } catch (TransactionCommitFailedException e) {
501                             LOG.warn("Failed to read from NeutronRouterDpn DS for routerid {}", routerId, e);
502                         }
503                     }
504                 }
505                 return null;
506             });
507     }
508
509     private void removeRouterFromFloatingIpInfo(Router update, DataBroker broker) {
510         Uuid routerId = update.getUuid();
511         InstanceIdentifier.InstanceIdentifierBuilder<RouterPorts> routerPortsIdentifierBuilder = InstanceIdentifier
512                 .builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId.getValue()));
513         try {
514             Optional<RouterPorts> optionalRouterPorts =
515                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
516                             routerPortsIdentifierBuilder.build());
517             if (optionalRouterPorts.isPresent()) {
518                 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.CONFIGURATION,
519                         routerPortsIdentifierBuilder.build());
520             }
521         } catch (ReadFailedException | TransactionCommitFailedException e) {
522             LOG.error("Failed to read from FloatingIpInfo DS for routerid {}", routerId, e);
523         }
524     }
525
526     // TODO Clean up the exception handling
527     @SuppressWarnings("checkstyle:IllegalCatch")
528     private void handleExternalFixedIpsForRouter(Router update) {
529         Uuid routerId = update.getUuid();
530         InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
531         try {
532             Optional<Routers> optionalRouters =
533                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
534                             routersIdentifier);
535             LOG.trace("Updating External Fixed IPs Routers node {}", routerId.getValue());
536             if (optionalRouters.isPresent()) {
537                 RoutersBuilder builder = new RoutersBuilder(optionalRouters.get());
538                 List<ExternalIps> externalIps = new ArrayList<>();
539                 for (ExternalFixedIps fixedIps : update.getExternalGatewayInfo().getExternalFixedIps()) {
540                     addExternalFixedIpToExternalIpsList(externalIps, fixedIps);
541                 }
542
543                 builder.setExternalIps(externalIps);
544
545                 updateExternalSubnetsForRouter(routerId, update.getExternalGatewayInfo().getExternalNetworkId(),
546                         update.getExternalGatewayInfo().getExternalFixedIps());
547                 Routers routerss = builder.build();
548                 LOG.trace("Updating external fixed ips for router {} with value {}", routerId.getValue(), routerss);
549                 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routersIdentifier,
550                         routerss);
551                 LOG.trace("Added External Fixed IPs successfully for Routers to CONFIG Datastore");
552             }
553         } catch (TransactionCommitFailedException | ReadFailedException ex) {
554             LOG.error("Updating extfixedips for {} in extrouters failed", routerId.getValue(), ex);
555         }
556     }
557
558     public void handleSubnetsForExternalRouter(Uuid routerId) {
559         InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
560
561         try {
562             Optional<Routers> optionalRouters =
563                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
564                             routersIdentifier);
565             LOG.trace("Updating Internal subnets for Routers node: {}", routerId.getValue());
566             RoutersBuilder builder = null;
567             if (optionalRouters.isPresent()) {
568                 builder = new RoutersBuilder(optionalRouters.get());
569             } else {
570                 LOG.debug("No Routers element found for router {}", routerId.getValue());
571                 return;
572             }
573             List<Uuid> subList = neutronvpnUtils.getNeutronRouterSubnetIds(routerId);
574             builder.setSubnetIds(subList);
575             Routers routerss = builder.build();
576             // Add Routers object to the ExtRouters list
577             LOG.trace("Updating extrouters {}", routerss);
578             SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
579                     routersIdentifier, routerss);
580             LOG.trace("Updated successfully Routers to CONFIG Datastore");
581         } catch (TransactionCommitFailedException | ReadFailedException ex) {
582             LOG.error("Updation of internal subnets for extrouters failed for router {}",
583                 routerId.getValue(), ex);
584         }
585     }
586
587     private void handleSnatSettingChangeForRouter(Router update) {
588         Uuid routerId = update.getUuid();
589
590         InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
591
592         try {
593             Optional<Routers> optionalRouters =
594                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
595                             routersIdentifier);
596             LOG.trace("Updating Internal subnets for Routers node: {}", routerId.getValue());
597             RoutersBuilder builder = null;
598             if (optionalRouters.isPresent()) {
599                 builder = new RoutersBuilder(optionalRouters.get());
600             } else {
601                 LOG.trace("No Routers element found for router name {}", routerId.getValue());
602                 return;
603             }
604             builder.setEnableSnat(update.getExternalGatewayInfo().isEnableSnat());
605             Routers routerss = builder.build();
606             // Add Routers object to the ExtRouters list
607             LOG.trace("Updating extrouters for snat change {}", routerss);
608             SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
609                     routersIdentifier, routerss);
610             LOG.trace("Updated successfully Routers to CONFIG Datastore");
611
612         } catch (TransactionCommitFailedException | ReadFailedException ex) {
613             LOG.error("Updation of snat for extrouters failed for router {}", routerId.getValue(), ex);
614         }
615     }
616
617     public void updateOrAddExternalSubnet(Uuid networkId, Uuid subnetId, @Nullable List<Uuid> routerIds) {
618         Optional<Subnets> optionalExternalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
619         if (optionalExternalSubnets.isPresent()) {
620             LOG.trace("Will update external subnet {} with networkId {} and routerIds {}",
621                     subnetId, networkId, routerIds);
622             updateExternalSubnet(networkId, subnetId, routerIds);
623         } else {
624             LOG.trace("Will add external subnet {} with networkId {} and routerIds {}",
625                     subnetId, networkId, routerIds);
626             addExternalSubnet(networkId, subnetId, routerIds);
627         }
628     }
629
630     public void addExternalSubnet(Uuid networkId, Uuid subnetId, List<Uuid> routerIds) {
631         InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
632                 .child(Subnets.class, new SubnetsKey(subnetId)).build();
633         try {
634             Subnets newExternalSubnets = createSubnets(subnetId, networkId, routerIds);
635             LOG.debug("Creating external subnet {}", newExternalSubnets);
636             SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier,
637                     newExternalSubnets);
638         } catch (TransactionCommitFailedException ex) {
639             LOG.error("Creation of External Subnets {} failed", subnetId, ex);
640         }
641     }
642
643     public void updateExternalSubnet(Uuid networkId, Uuid subnetId, @Nullable List<Uuid> routerIds) {
644         InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
645                 .child(Subnets.class, new SubnetsKey(subnetId)).build();
646         try {
647             Subnets newExternalSubnets = createSubnets(subnetId, networkId, routerIds);
648             LOG.debug("Updating external subnet {}", newExternalSubnets);
649             SingleTransactionDataBroker.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier,
650                     newExternalSubnets);
651         } catch (TransactionCommitFailedException ex) {
652             LOG.error("Update of External Subnets {} failed", subnetId, ex);
653         }
654     }
655
656     public void removeExternalSubnet(Uuid networkId, Uuid subnetId) {
657         removeAdjacencyAndLearnedEntriesforExternalSubnet(networkId, subnetId);
658         InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
659                 .child(Subnets.class, new SubnetsKey(subnetId)).build();
660         try {
661             LOG.debug("Removing external subnet {}", subnetId);
662             SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
663         } catch (TransactionCommitFailedException ex) {
664             LOG.error("Deletion of External Subnets {} failed", subnetId, ex);
665         }
666     }
667
668     public void addRouterIdToExternalSubnet(Uuid networkId, Uuid subnetId, Uuid routerId) {
669         Optional<Subnets> optionalExternalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
670         if (optionalExternalSubnets.isPresent()) {
671             Subnets subnets = optionalExternalSubnets.get();
672             List<Uuid> routerIds;
673             if (subnets.getRouterIds() != null) {
674                 routerIds = subnets.getRouterIds();
675             } else {
676                 routerIds = new ArrayList<>();
677             }
678
679             if (subnets.getExternalNetworkId() != null
680                     && subnets.getExternalNetworkId().equals(networkId) && !routerIds.contains(routerId)) {
681                 LOG.debug("Will add routerID {} for external subnet {}.", routerId, subnetId);
682                 routerIds.add(routerId);
683                 updateExternalSubnet(networkId, subnetId, routerIds);
684             }
685         }
686     }
687
688     private static Subnets createSubnets(Uuid subnetId, Uuid networkId, @Nullable List<Uuid> routerIds) {
689         SubnetsBuilder subnetsBuilder = new SubnetsBuilder();
690         subnetsBuilder.withKey(new SubnetsKey(subnetId));
691         subnetsBuilder.setId(subnetId);
692         subnetsBuilder.setVpnId(subnetId);
693         subnetsBuilder.setExternalNetworkId(networkId);
694         if (routerIds != null) {
695             subnetsBuilder.setRouterIds(routerIds);
696         }
697
698         return subnetsBuilder.build();
699     }
700
701     private void updateExternalSubnetsForRouter(Uuid routerId, Uuid externalNetworkId,
702             List<ExternalFixedIps> externalFixedIps) {
703         LOG.debug("Updating external subnets for router {} for external network ID {}",
704                 routerId, externalNetworkId);
705         Set<Uuid> subnetsUuidsSet = getExternalSubnetsUuidsSetForFixedIps(externalFixedIps);
706         for (Uuid subnetId : subnetsUuidsSet) {
707             addRouterIdToExternalSubnet(externalNetworkId, subnetId, routerId);
708         }
709     }
710
711     private void removeRouterFromExternalSubnets(Uuid routerId, Uuid externalNetworkId,
712             List<ExternalFixedIps> externalFixedIps) {
713         LOG.debug("Removing routerID {} from external subnets of external network{}",
714                 routerId, externalNetworkId);
715
716         List<Subnets> fixedIpsSubnets = getSubnets(getExternalSubnetsUuidsSetForFixedIps(externalFixedIps));
717         for (Subnets subnets : fixedIpsSubnets) {
718             Uuid subnetId = subnets.getId();
719             List<Uuid> routerIds = subnets.getRouterIds();
720             if (routerIds != null) {
721                 if (subnets.getExternalNetworkId() != null
722                         && subnets.getExternalNetworkId().equals(externalNetworkId)
723                         && routerIds.contains(routerId)) {
724                     routerIds.remove(routerId);
725                     LOG.debug("Will remove routerIDs {} from external subnet {} router ID {}",
726                         routerIds, subnetId, routerId);
727                     addExternalSubnet(externalNetworkId, subnetId, routerIds);
728                 }
729             }
730         }
731     }
732
733     private static Set<Uuid> getExternalSubnetsUuidsSetForFixedIps(List<ExternalFixedIps> externalFixedIps) {
734         Set<Uuid> subnetsUuidsSet = new HashSet<>();
735         for (ExternalFixedIps externalFixedIp : externalFixedIps) {
736             subnetsUuidsSet.add(externalFixedIp.getSubnetId());
737         }
738
739         return subnetsUuidsSet;
740     }
741
742     private List<Subnets> getSubnets(Set<Uuid> subnetsUuidsSet) {
743         List<Subnets> subnetsList = new ArrayList<>();
744         for (Uuid subnetId : subnetsUuidsSet) {
745             Optional<Subnets> optionalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
746             if (optionalSubnets.isPresent()) {
747                 subnetsList.add(optionalSubnets.get());
748             }
749         }
750
751         return subnetsList;
752     }
753
754     private static void addExternalFixedIpToExternalIpsList(List<ExternalIps> externalIps, ExternalFixedIps fixedIps) {
755         Uuid subnetId = fixedIps.getSubnetId();
756         String ip = fixedIps.getIpAddress().stringValue();
757         ExternalIpsBuilder externalIpsBuilder = new ExternalIpsBuilder();
758         externalIpsBuilder.withKey(new ExternalIpsKey(ip, subnetId));
759         externalIpsBuilder.setIpAddress(ip);
760         externalIpsBuilder.setSubnetId(subnetId);
761         externalIps.add(externalIpsBuilder.build());
762     }
763
764     private void removeAdjacencyAndLearnedEntriesforExternalSubnet(Uuid extNetId, Uuid extSubnetId) {
765         Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
766         if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
767             LOG.error("No external ports attached to external network {}", extNetId.getValue());
768             return;
769         }
770
771         for (String infName : extElanInterfaces) {
772             InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
773                 VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
774             InstanceIdentifier<Adjacencies> adjacenciesIdentifier = vpnIfIdentifier.augmentation(Adjacencies.class);
775             try {
776                 // Looking for existing prefix in MDSAL database
777                 Optional<Adjacencies> optionalAdjacencies = SingleTransactionDataBroker.syncReadOptional(dataBroker,
778                     LogicalDatastoreType.CONFIGURATION, adjacenciesIdentifier);
779                 if (optionalAdjacencies.isPresent()) {
780                     List<Adjacency> adjacencies = optionalAdjacencies.get().getAdjacency();
781                     Iterator<Adjacency> adjacencyIter = adjacencies.iterator();
782                     while (adjacencyIter.hasNext()) {
783                         Adjacency adjacency = adjacencyIter.next();
784                         if (!adjacency.getSubnetId().equals(extSubnetId)) {
785                             continue;
786                         }
787                         InstanceIdentifier<Adjacency> adjacencyIdentifier =
788                             adjacenciesIdentifier.child(Adjacency.class, new AdjacencyKey(adjacency.getIpAddress()));
789                         SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
790                             adjacencyIdentifier);
791                         LOG.trace("Removed Adjacency for fixedIP {} for port {} on external subnet {} ",
792                             adjacency.getIpAddress(), infName, extSubnetId);
793                         String extNetVpnName = extNetId.getValue();
794                         String learnedSrcIp = adjacency.getIpAddress().split("/")[0];
795                         InstanceIdentifier<LearntVpnVipToPort> id =
796                             NeutronvpnUtils.buildLearntVpnVipToPortIdentifier(extNetVpnName, learnedSrcIp);
797                         Optional<LearntVpnVipToPort> optionalLearntVpnVipToPort = SingleTransactionDataBroker
798                             .syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
799                         if (optionalLearntVpnVipToPort.isPresent()) {
800                             neutronvpnUtils.removeLearntVpnVipToPort(extNetVpnName, learnedSrcIp);
801                             LOG.trace("Removed Learnt Entry for fixedIP {} for port {}",
802                                 adjacency.getIpAddress(), infName);
803                         }
804                     }
805                 }
806             } catch (TransactionCommitFailedException | ReadFailedException e) {
807                 LOG.error("exception in removeAdjacencyAndLearnedEntriesforExternalSubnet for interface {}",
808                     infName, e);
809             }
810         }
811     }
812
813
814 }