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