Merge "Fix NPE and other exceptions"
[netvirt.git] / vpnservice / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronvpnManager.java
1 /*
2  * Copyright (c) 2015 - 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 java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.EventListener;
13 import java.util.HashMap;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.Future;
19
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.genius.mdsalutil.MDSALUtil;
24 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
25 import org.opendaylight.netvirt.elanmanager.api.IElanService;
26 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
27 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
28 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets;
29 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargetsBuilder;
30 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
31 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetBuilder;
32 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetKey;
33 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
34 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
35 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
36 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
37 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
38 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
39 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.LockManagerService;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.config.rev160806.NeutronvpnConfig;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksInput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksOutput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksOutputBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateRouterInput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNOutput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNOutputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNOutput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNOutputBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksOutput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksOutputBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateRouterInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInputBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNOutput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNOutputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.L3vpnInstance;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterAssociatedToVpn;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterAssociatedToVpnBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterDisassociatedFromVpn;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterDisassociatedFromVpnBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterInterfacesMap;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetAddedToVpnBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetDeletedFromVpnBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetUpdatedInVpnBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.createl3vpn.input.L3vpn;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstances;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstancesBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfaces;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesKey;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.InterfacesBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.InterfacesKey;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteInput;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteInputBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteOutput;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.RemoveStaticRouteInput;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.RemoveStaticRouteInputBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.VpnRpcService;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.l3.attributes.Routes;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
116 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
117 import org.opendaylight.yangtools.yang.common.RpcError;
118 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
119 import org.opendaylight.yangtools.yang.common.RpcResult;
120 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
121 import org.slf4j.Logger;
122 import org.slf4j.LoggerFactory;
123
124 import com.google.common.base.Optional;
125 import com.google.common.util.concurrent.SettableFuture;
126
127 public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, EventListener {
128     private static final Logger LOG = LoggerFactory.getLogger(NeutronvpnManager.class);
129     private final DataBroker dataBroker;
130     private final LockManagerService lockManager;
131     private final NeutronvpnNatManager nvpnNatManager;
132     private final NotificationPublishService notificationPublishService;
133     private final VpnRpcService vpnRpcService;
134     private final NeutronFloatingToFixedIpMappingChangeListener floatingIpMapListener;
135     private final NeutronvpnConfig neutronvpnConfig;
136     private final IMdsalApiManager mdsalUtil;
137     private final IElanService elanService;
138     Boolean isExternalVpn;
139
140     /**
141      * @param dataBroker DataBroker reference
142      * @param mdsalManager MDSAL Util API access
143      */
144     public NeutronvpnManager(
145             final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
146             final NotificationPublishService notiPublishService, final NeutronvpnNatManager vpnNatMgr,
147             final LockManagerService lockManager, final VpnRpcService vpnRpcSrv,
148             final IElanService elanService,
149             final NeutronFloatingToFixedIpMappingChangeListener neutronFloatingToFixedIpMappingChangeListener,
150             final NeutronvpnConfig neutronvpnConfig) {
151         this.dataBroker = dataBroker;
152         mdsalUtil = mdsalManager;
153         nvpnNatManager = vpnNatMgr;
154         notificationPublishService = notiPublishService;
155         vpnRpcService = vpnRpcSrv;
156         this.elanService = elanService;
157         floatingIpMapListener = neutronFloatingToFixedIpMappingChangeListener;
158         this.lockManager = lockManager;
159         LOG.info("neutronvpnConfig: {}", neutronvpnConfig);
160         this.neutronvpnConfig = neutronvpnConfig;
161     }
162
163     @Override
164     public void close() throws Exception {
165         LOG.info("{} close", getClass().getSimpleName());
166     }
167
168     public NeutronvpnConfig getNeutronvpnConfig() {
169         return neutronvpnConfig;
170     }
171
172     protected void updateSubnetNodeWithFixedIps(Uuid subnetId, Uuid routerId,
173                                                 Uuid routerInterfaceName, String fixedIp,
174                                                 String routerIntfMacAddress) {
175         Subnetmap subnetmap = null;
176         SubnetmapBuilder builder = null;
177         boolean isLockAcquired = false;
178         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).
179                 child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
180         try {
181             Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
182             if (sn.isPresent()) {
183                 builder = new SubnetmapBuilder(sn.get());
184                 if (routerId != null) {
185                     builder.setRouterId(routerId);
186                 } else {
187                     builder.setRouterId(null);
188                 }
189                 if (routerInterfaceName != null) {
190                     builder.setRouterInterfaceName(routerInterfaceName);
191                 } else {
192                     builder.setRouterInterfaceName(null);
193                 }
194                 if (routerIntfMacAddress != null) {
195                     builder.setRouterIntfMacAddress(routerIntfMacAddress);
196                 } else {
197                     builder.setRouterIntfMacAddress(null);
198                 }
199                 if (fixedIp != null) {
200                     List<String> fixedIps = builder.getRouterInterfaceFixedIps();
201                     if (fixedIps == null) {
202                         fixedIps = new ArrayList<String>();
203                     }
204                     fixedIps.add(fixedIp);
205                     builder.setRouterInterfaceFixedIps(fixedIps);
206                 } else {
207                     builder.setRouterInterfaceFixedIps(null);
208                 }
209                 subnetmap = builder.build();
210                 isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
211                 LOG.debug("Creating/Updating subnetMap node for FixedIps: {} ", subnetId.getValue());
212                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
213             }
214         } catch (Exception e) {
215             LOG.error("Updation of subnetMap for FixedIps failed for node: {}", subnetId.getValue());
216         } finally {
217             if (isLockAcquired) {
218                 NeutronvpnUtils.unlock(lockManager, subnetId.getValue());
219             }
220         }
221     }
222
223     protected Subnetmap updateSubnetNode(Uuid subnetId, String subnetIp, Uuid tenantId, Uuid networkId, Uuid routerId,
224                                          Uuid vpnId) {
225         Subnetmap subnetmap = null;
226         SubnetmapBuilder builder = null;
227         boolean isLockAcquired = false;
228         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
229                 .child(Subnetmap.class, new SubnetmapKey(subnetId))
230                 .build();
231         try {
232             Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
233             LOG.debug("updating Subnet :read: ");
234             if (sn.isPresent()) {
235                 builder = new SubnetmapBuilder(sn.get());
236                 LOG.debug("updating Subnet :existing: ");
237             } else {
238                 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
239                 LOG.debug("updating Subnet :new: ");
240             }
241
242             if (subnetIp != null) {
243                 builder.setSubnetIp(subnetIp);
244             }
245             if (routerId != null) {
246                 builder.setRouterId(routerId);
247             }
248             if (networkId != null) {
249                 builder.setNetworkId(networkId);
250             }
251             if (vpnId != null) {
252                 builder.setVpnId(vpnId);
253             }
254             if (tenantId != null) {
255                 builder.setTenantId(tenantId);
256             }
257
258             subnetmap = builder.build();
259             isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
260             LOG.debug("Creating/Updating subnetMap node: {} ", subnetId.getValue());
261             MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
262         } catch (Exception e) {
263             LOG.error("Updation of subnetMap failed for node: {}", subnetId.getValue());
264         } finally {
265             if (isLockAcquired) {
266                 NeutronvpnUtils.unlock(lockManager, subnetId.getValue());
267             }
268         }
269         return subnetmap;
270     }
271
272     protected Subnetmap removeFromSubnetNode(Uuid subnetId, Uuid networkId, Uuid routerId, Uuid vpnId, Uuid portId) {
273         Subnetmap subnetmap = null;
274         boolean isLockAcquired = false;
275         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
276                 .child(Subnetmap.class, new SubnetmapKey(subnetId))
277                 .build();
278         try {
279             Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
280             if (sn.isPresent()) {
281                 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
282                 if (routerId != null) {
283                     builder.setRouterId(null);
284                 }
285                 if (networkId != null) {
286                     builder.setNetworkId(null);
287                 }
288                 if (vpnId != null) {
289                     builder.setVpnId(null);
290                 }
291                 if (portId != null && builder.getPortList() != null) {
292                     List<Uuid> portList = builder.getPortList();
293                     portList.remove(portId);
294                     builder.setPortList(portList);
295                 }
296
297                 subnetmap = builder.build();
298                 isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
299                 LOG.debug("Removing from existing subnetmap node: {} ", subnetId.getValue());
300                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
301             } else {
302                 LOG.warn("removing from non-existing subnetmap node: {} ", subnetId.getValue());
303             }
304         } catch (Exception e) {
305             LOG.error("Removal from subnetmap failed for node: {}", subnetId.getValue());
306         } finally {
307             if (isLockAcquired) {
308                 NeutronvpnUtils.unlock(lockManager, subnetId.getValue());
309             }
310         }
311         return subnetmap;
312     }
313
314     protected Subnetmap updateSubnetmapNodeWithPorts(Uuid subnetId, Uuid portId, Uuid directPortId) {
315         Subnetmap subnetmap = null;
316         boolean isLockAcquired = false;
317         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
318                 new SubnetmapKey(subnetId)).build();
319         try {
320             Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
321             if (sn.isPresent()) {
322                 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
323                 if (null != portId) {
324                     List<Uuid> portList = builder.getPortList();
325                     if (null == portList) {
326                         portList = new ArrayList<>();
327                     }
328                     portList.add(portId);
329                     builder.setPortList(portList);
330                     LOG.debug("Updating existing subnetmap node {} with port {}", subnetId.getValue(),
331                             portId.getValue());
332                 }
333                 if (null != directPortId) {
334                     List<Uuid> directPortList = builder.getDirectPortList();
335                     if (null == directPortList) {
336                         directPortList = new ArrayList<>();
337                     }
338                     directPortList.add(directPortId);
339                     builder.setDirectPortList(directPortList);
340                     LOG.debug("Updating existing subnetmap node {} with port {}", subnetId.getValue(),
341                             directPortId.getValue());
342                 }
343                 subnetmap = builder.build();
344                 isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
345                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
346             } else {
347                 LOG.error("Trying to update non-existing subnetmap node {} ", subnetId.getValue());
348             }
349         } catch (Exception e) {
350             LOG.error("Updating port list of a given subnetMap failed for node: {} with exception{}",
351                     subnetId.getValue(), e);
352         } finally {
353             if (isLockAcquired) {
354                 NeutronvpnUtils.unlock(lockManager, subnetId.getValue());
355             }
356         }
357         return subnetmap;
358     }
359
360     protected Subnetmap removePortsFromSubnetmapNode(Uuid subnetId, Uuid portId, Uuid directPortId) {
361         Subnetmap subnetmap = null;
362         boolean isLockAcquired = false;
363         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
364                 new SubnetmapKey(subnetId)).build();
365         try {
366             Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
367             if (sn.isPresent()) {
368                 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
369                 if (null != portId && null != builder.getPortList()) {
370                     List<Uuid> portList = builder.getPortList();
371                     portList.remove(portId);
372                     builder.setPortList(portList);
373                     LOG.debug("Removing port {} from existing subnetmap node: {} ", portId.getValue(),
374                             subnetId.getValue());
375                 }
376                 if (null != directPortId && null != builder.getDirectPortList()) {
377                     List<Uuid> directPortList = builder.getDirectPortList();
378                     directPortList.remove(directPortId);
379                     builder.setDirectPortList(directPortList);
380                     LOG.debug("Removing direct port {} from existing subnetmap node: {} ", directPortId.getValue(),
381                             subnetId.getValue());
382                 }
383                 subnetmap = builder.build();
384                 isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
385                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
386             } else {
387                 LOG.error("Trying to remove port from non-existing subnetmap node {}", subnetId.getValue());
388             }
389         } catch (Exception e) {
390             LOG.error("Removing a port from port list of a subnetmap failed for node: {} with expection {}",
391                     subnetId.getValue(), e);
392         } finally {
393             if (isLockAcquired) {
394                 NeutronvpnUtils.unlock(lockManager, subnetId.getValue());
395             }
396         }
397         return subnetmap;
398     }
399
400     protected void deleteSubnetMapNode(Uuid subnetId) {
401         boolean isLockAcquired = false;
402         InstanceIdentifier<Subnetmap> subnetMapIdentifier =
403                 InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,new SubnetmapKey(subnetId)).build();
404         LOG.debug("removing subnetMap node: {} ", subnetId.getValue());
405         try {
406             isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
407             MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetMapIdentifier);
408         } catch (Exception e) {
409             LOG.error("Delete subnetMap node failed for subnet : {} ", subnetId.getValue());
410         } finally {
411             if (isLockAcquired) {
412                 NeutronvpnUtils.unlock(lockManager, subnetId.getValue());
413             }
414         }
415     }
416
417     private void updateVpnInstanceNode(String vpnName, List<String> rd, List<String> irt, List<String> ert) {
418
419         VpnInstanceBuilder builder = null;
420         List<VpnTarget> vpnTargetList = new ArrayList<>();
421         boolean isLockAcquired = false;
422         InstanceIdentifier<VpnInstance> vpnIdentifier =
423                 InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class,new VpnInstanceKey(vpnName)).build();
424         try {
425             Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
426                     vpnIdentifier);
427             LOG.debug("Creating/Updating a new vpn-instance node: {} ", vpnName);
428             if (optionalVpn.isPresent()) {
429                 builder = new VpnInstanceBuilder(optionalVpn.get());
430                 LOG.debug("updating existing vpninstance node");
431             } else {
432                 builder = new VpnInstanceBuilder().setKey(new VpnInstanceKey(vpnName)).setVpnInstanceName(vpnName);
433             }
434             if (irt != null && !irt.isEmpty()) {
435                 if (ert != null && !ert.isEmpty()) {
436                     List<String> commonRT = new ArrayList<>(irt);
437                     commonRT.retainAll(ert);
438
439                     for (String common : commonRT) {
440                         irt.remove(common);
441                         ert.remove(common);
442                         VpnTarget vpnTarget =
443                                 new VpnTargetBuilder().setKey(new VpnTargetKey(common)).setVrfRTValue(common)
444                                         .setVrfRTType(VpnTarget.VrfRTType.Both).build();
445                         vpnTargetList.add(vpnTarget);
446                     }
447                 }
448                 for (String importRT : irt) {
449                     VpnTarget vpnTarget =
450                             new VpnTargetBuilder().setKey(new VpnTargetKey(importRT)).setVrfRTValue(importRT)
451                                     .setVrfRTType(VpnTarget.VrfRTType.ImportExtcommunity).build();
452                     vpnTargetList.add(vpnTarget);
453                 }
454             }
455
456             if (ert != null && !ert.isEmpty()) {
457                 for (String exportRT : ert) {
458                     VpnTarget vpnTarget =
459                             new VpnTargetBuilder().setKey(new VpnTargetKey(exportRT)).setVrfRTValue(exportRT)
460                                     .setVrfRTType(VpnTarget.VrfRTType.ExportExtcommunity).build();
461                     vpnTargetList.add(vpnTarget);
462                 }
463             }
464
465             VpnTargets vpnTargets = new VpnTargetsBuilder().setVpnTarget(vpnTargetList).build();
466
467             Ipv4FamilyBuilder ipv4vpnBuilder = new Ipv4FamilyBuilder().setVpnTargets(vpnTargets);
468
469             if (rd != null && !rd.isEmpty()) {
470                 ipv4vpnBuilder.setRouteDistinguisher(rd.get(0));
471             }
472
473             VpnInstance newVpn = builder.setIpv4Family(ipv4vpnBuilder.build()).build();
474             isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnName);
475             LOG.debug("Creating/Updating vpn-instance for {} ", vpnName);
476             MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier, newVpn);
477         } catch (Exception e) {
478             LOG.error("Update VPN Instance node failed for node: {} {} {} {}", vpnName, rd, irt, ert);
479         } finally {
480             if (isLockAcquired) {
481                 NeutronvpnUtils.unlock(lockManager, vpnName);
482             }
483         }
484     }
485
486     private void deleteVpnMapsNode(Uuid vpnid) {
487         boolean isLockAcquired = false;
488         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
489                 .child(VpnMap.class, new VpnMapKey(vpnid))
490                 .build();
491         LOG.debug("removing vpnMaps node: {} ", vpnid.getValue());
492         try {
493             isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnid.getValue());
494             MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
495         } catch (Exception e) {
496             LOG.error("Delete vpnMaps node failed for vpn : {} ", vpnid.getValue());
497         } finally {
498             if (isLockAcquired) {
499                 NeutronvpnUtils.unlock(lockManager, vpnid.getValue());
500             }
501         }
502     }
503
504     private void updateVpnMaps(Uuid vpnId, String name, Uuid router, Uuid tenantId, List<Uuid> networks) {
505         VpnMapBuilder builder;
506         boolean isLockAcquired = false;
507         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
508                 .child(VpnMap.class, new VpnMapKey(vpnId))
509                 .build();
510         try {
511             Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
512                     vpnMapIdentifier);
513             if (optionalVpnMap.isPresent()) {
514                 builder = new VpnMapBuilder(optionalVpnMap.get());
515             } else {
516                 builder = new VpnMapBuilder().setKey(new VpnMapKey(vpnId)).setVpnId(vpnId);
517             }
518
519             if (name != null) {
520                 builder.setName(name);
521             }
522             if (tenantId != null) {
523                 builder.setTenantId(tenantId);
524             }
525             if (router != null) {
526                 builder.setRouterId(router);
527             }
528             if (networks != null) {
529                 List<Uuid> nwList = builder.getNetworkIds();
530                 if (nwList == null) {
531                     nwList = new ArrayList<>();
532                 }
533                 nwList.addAll(networks);
534                 builder.setNetworkIds(nwList);
535             }
536
537             isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnId.getValue());
538             LOG.debug("Creating/Updating vpnMaps node: {} ", vpnId.getValue());
539             MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier, builder.build());
540             LOG.debug("VPNMaps DS updated for VPN {} ", vpnId.getValue());
541         } catch (Exception e) {
542             LOG.error("UpdateVpnMaps failed for node: {} ", vpnId.getValue());
543         } finally {
544             if (isLockAcquired) {
545                 NeutronvpnUtils.unlock(lockManager, vpnId.getValue());
546             }
547         }
548     }
549
550     private void clearFromVpnMaps(Uuid vpnId, Uuid routerId, List<Uuid> networkIds) {
551         boolean isLockAcquired = false;
552         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
553                 .child(VpnMap.class, new VpnMapKey(vpnId))
554                 .build();
555         Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
556                 vpnMapIdentifier);
557         if (optionalVpnMap.isPresent()) {
558             VpnMap vpnMap = optionalVpnMap.get();
559             VpnMapBuilder vpnMapBuilder = new VpnMapBuilder(vpnMap);
560             if (routerId != null) {
561                 if (vpnMap.getNetworkIds() == null && routerId.equals(vpnMap.getVpnId())) {
562                     try {
563                         // remove entire node in case of internal VPN
564                         isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnId.getValue());
565                         LOG.debug("removing vpnMaps node: {} ", vpnId);
566                         MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
567                     } catch (Exception e) {
568                         LOG.error("Deletion of vpnMaps node failed for vpn {}", vpnId.getValue());
569                     } finally {
570                         if (isLockAcquired) {
571                             NeutronvpnUtils.unlock(lockManager, vpnId.getValue());
572                         }
573                     }
574                     return;
575                 }
576                 vpnMapBuilder.setRouterId(null);
577             }
578             if (networkIds != null) {
579                 List<Uuid> vpnNw = vpnMap.getNetworkIds();
580                 for (Uuid nw : networkIds) {
581                     vpnNw.remove(nw);
582                 }
583                 if (vpnNw.isEmpty()) {
584                     LOG.debug("setting networks null in vpnMaps node: {} ", vpnId.getValue());
585                     vpnMapBuilder.setNetworkIds(null);
586                 } else {
587                     vpnMapBuilder.setNetworkIds(vpnNw);
588                 }
589             }
590
591             try {
592                 isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnId.getValue());
593                 LOG.debug("clearing from vpnMaps node: {} ", vpnId.getValue());
594                 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier,
595                         vpnMapBuilder.build());
596             } catch (Exception e) {
597                 LOG.error("Clearing from vpnMaps node failed for vpn {}", vpnId.getValue());
598             } finally {
599                 if (isLockAcquired) {
600                     NeutronvpnUtils.unlock(lockManager, vpnId.getValue());
601                 }
602             }
603         } else {
604             LOG.error("VPN : {} not found", vpnId.getValue());
605         }
606         LOG.debug("Clear from VPNMaps DS successful for VPN {} ", vpnId.getValue());
607     }
608
609     private void deleteVpnInstance(Uuid vpnId) {
610         boolean isLockAcquired = false;
611         InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
612                 .child(VpnInstance.class,
613                         new VpnInstanceKey(vpnId.getValue()))
614                 .build();
615         try {
616             isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnId.getValue());
617             LOG.debug("Deleting vpnInstance {}", vpnId.getValue());
618             MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
619         } catch (Exception e) {
620             LOG.error("Deletion of VPNInstance node failed for VPN {}", vpnId.getValue());
621         } finally {
622             if (isLockAcquired) {
623                 NeutronvpnUtils.unlock(lockManager, vpnId.getValue());
624             }
625         }
626     }
627
628     protected void createVpnInterface(Uuid vpnId, Port port) {
629         boolean isLockAcquired = false;
630         if (vpnId == null || port == null) {
631             return;
632         }
633         String infName = port.getUuid().getValue();
634         List<Adjacency> adjList = new ArrayList<>();
635         InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
636
637         // find router associated to vpn
638         Uuid routerId = NeutronvpnUtils.getRouterforVpn(dataBroker, vpnId);
639         Router rtr = null;
640         if (routerId != null) {
641             rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
642         }
643         // find all subnets to which this port is associated
644         List<FixedIps> ips = port.getFixedIps();
645         // create adjacency list
646         for (FixedIps ip : ips) {
647             // create vm adjacency
648             StringBuilder IpPrefixBuild = new StringBuilder(ip.getIpAddress().getIpv4Address().getValue());
649             String IpPrefix = IpPrefixBuild.append("/32").toString();
650             Adjacency vmAdj = new AdjacencyBuilder().setKey(new AdjacencyKey(IpPrefix)).setIpAddress(IpPrefix)
651                     .setMacAddress(port.getMacAddress().getValue()).build();
652             adjList.add(vmAdj);
653             // create extra route adjacency
654             if (rtr != null && rtr.getRoutes() != null) {
655                 List<Routes> routeList = rtr.getRoutes();
656                 List<Adjacency> erAdjList = addAdjacencyforExtraRoute(vpnId, routeList);
657                 if (erAdjList != null && !erAdjList.isEmpty()) {
658                     adjList.addAll(erAdjList);
659                 }
660             }
661             String ipValue = ip.getIpAddress().getIpv4Address().getValue();
662             NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
663                     .getMacAddress()
664                     .getValue(), false, true, false);
665         }
666         // create vpn-interface on this neutron port
667         Adjacencies adjs = new AdjacenciesBuilder().setAdjacency(adjList).build();
668         VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
669                 .setName(infName)
670                 .setVpnInstanceName(vpnId.getValue())
671                 .addAugmentation(Adjacencies.class, adjs);
672         VpnInterface vpnIf = vpnb.build();
673
674         try {
675             isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
676             LOG.debug("Creating vpn interface {}", vpnIf);
677             MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
678         } catch (Exception ex) {
679             LOG.error("Creation of vpninterface {} failed due to {}", infName, ex);
680         } finally {
681             if (isLockAcquired) {
682                 NeutronvpnUtils.unlock(lockManager, infName);
683             }
684         }
685     }
686
687     protected void deleteVpnInterface(Uuid vpnId, Port port) {
688
689         if (port != null) {
690             boolean isLockAcquired = false;
691             String infName = port.getUuid().getValue();
692             InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
693
694             try {
695                 isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
696                 LOG.debug("Deleting vpn interface {}", infName);
697                 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
698
699                 List<FixedIps> ips = port.getFixedIps();
700                 for (FixedIps ip : ips) {
701                     String ipValue = ip.getIpAddress().getIpv4Address().getValue();
702                     NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue);
703                 }
704             } catch (Exception ex) {
705                 LOG.error("Deletion of vpninterface {} failed due to {}", infName, ex);
706             } finally {
707                 if (isLockAcquired) {
708                     NeutronvpnUtils.unlock(lockManager, infName);
709                 }
710             }
711         }
712     }
713
714     protected void updateVpnInterface(Uuid vpnId, Uuid oldVpnId, Port port, boolean  isBeingAssociated) {
715         if (vpnId == null || port == null) {
716             return;
717         }
718         boolean isLockAcquired = false;
719         String infName = port.getUuid().getValue();
720         InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
721         try {
722             isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
723             Optional<VpnInterface> optionalVpnInterface = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
724                     .CONFIGURATION, vpnIfIdentifier);
725             if (optionalVpnInterface.isPresent()) {
726                 VpnInterfaceBuilder vpnIfBuilder = new VpnInterfaceBuilder(optionalVpnInterface.get())
727                         .setVpnInstanceName(vpnId.getValue());
728                 LOG.debug("Updating vpn interface {}", infName);
729                 if (!isBeingAssociated) {
730                     List<Adjacency> adjacencyList = vpnIfBuilder.getAugmentation(Adjacencies.class).getAdjacency();
731                     Iterator<Adjacency> adjacencyIter = adjacencyList.iterator();
732                     while (adjacencyIter.hasNext()) {
733                         Adjacency adjacency = adjacencyIter.next();
734                         String mipToQuery = adjacency.getIpAddress().split("/")[0];
735                         InstanceIdentifier<VpnPortipToPort> id = NeutronvpnUtils.buildVpnPortipToPortIdentifier
736                                 (oldVpnId.getValue(), mipToQuery);
737                         Optional<VpnPortipToPort> optionalVpnPort = NeutronvpnUtils.read(dataBroker,
738                                 LogicalDatastoreType
739                                 .OPERATIONAL, id);
740                         if (optionalVpnPort.isPresent() && optionalVpnPort.get().isLearnt()) {
741                             LOG.trace("Removing adjacencies from vpninterface {} upon dissociation of router {} " +
742                                     "from VPN " + "{}", infName, vpnId, oldVpnId);
743                             adjacencyIter.remove();
744                             NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(), mipToQuery);
745                             LOG.trace("Entry for fixedIP {} for port {} on VPN removed from " +
746                                     "VpnPortFixedIPToPortData", mipToQuery, infName, vpnId.getValue());
747                         }
748                     }
749                     Adjacencies adjacencies = new AdjacenciesBuilder().setAdjacency(adjacencyList).build();
750                     vpnIfBuilder.addAugmentation(Adjacencies.class, adjacencies);
751                 }
752                 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIfBuilder
753                         .build());
754
755                 List<FixedIps> ips = port.getFixedIps();
756                 for (FixedIps ip : ips) {
757                     String ipValue = ip.getIpAddress().getIpv4Address().getValue();
758                     if (oldVpnId != null) {
759                         NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(), ipValue);
760                     }
761                     NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, port.getUuid()
762                             .getValue(), port.getMacAddress().getValue(), false, true, false);
763                 }
764             } else {
765                 LOG.error("VPN Interface {} not found", infName);
766             }
767         } catch (Exception ex) {
768             LOG.error("Updation of vpninterface {} failed due to {}", infName, ex);
769         } finally {
770             if (isLockAcquired) {
771                 NeutronvpnUtils.unlock(lockManager, infName);
772             }
773         }
774     }
775
776     protected void deleteVpnInterface(String vpnName, String infName) {
777         if (vpnName == null || infName == null) {
778             return;
779         }
780
781         boolean isLockAcquired = false;
782         InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
783         try {
784             isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
785             LOG.debug("Deleting vpn interface {}", infName);
786             MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
787         } catch (Exception ex) {
788             LOG.error("Deletion of vpninterface {} failed due to {}", infName, ex);
789         } finally {
790             if (isLockAcquired) {
791                 NeutronvpnUtils.unlock(lockManager, infName);
792             }
793         }
794     }
795
796     public void createL3InternalVpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt,
797                                     List<String> ert, Uuid router, List<Uuid> networks) {
798
799         // Update VPN Instance node
800         updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
801
802         // Update local vpn-subnet DS
803         updateVpnMaps(vpn, name, router, tenant, networks);
804
805         if (router != null) {
806             Uuid existingVpn = NeutronvpnUtils.getVpnForRouter(dataBroker, router, true);
807             if (existingVpn != null) {
808                 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, router);
809                 if (routerSubnets != null) {
810                     // Update the router interfaces alone and exit
811                     for (Uuid subnetId : routerSubnets) {
812                         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).
813                                 child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
814                         Optional<Subnetmap> snMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
815                         if (snMap.isPresent()) {
816                             Subnetmap sn = snMap.get();
817                             List<Uuid> portList = sn.getPortList();
818                             if (portList != null) {
819                                 for (Uuid port : sn.getPortList()) {
820                                     addToNeutronRouterInterfacesMap(router, port.getValue());
821                                 }
822                             }
823                         }
824                     }
825                 }
826                 LOG.info("Creation of Internal L3VPN skipped for VPN {} due to router {} already associated to " +
827                         "external VPN {}", vpn.getValue(), router.getValue(), existingVpn.getValue());
828                 return;
829             }
830             associateRouterToInternalVpn(vpn, router);
831         }
832     }
833
834     /**
835      * Performs the creation of a Neutron L3VPN, associating the new VPN to the
836      * specified Neutron Networks and Routers
837      *
838      * @param vpn Uuid of the VPN tp be created
839      * @param name Representative name of the new VPN
840      * @param tenant Uuid of the Tenant under which the VPN is going to be created
841      * @param rd Route-distinguisher for the VPN
842      * @param irt A list of Import Route Targets
843      * @param ert A list of Export Route Targets
844      * @param router UUID of the neutron router the VPN may be associated to
845      * @param networks UUID of the neutron network the VPN may be associated to
846      */
847     public void createL3Vpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt, List<String> ert,
848                             Uuid router, List<Uuid> networks) throws Exception {
849
850         // Update VPN Instance node
851         updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
852
853         // Please note that router and networks will be filled into VPNMaps
854         // by subsequent calls here to associateRouterToVpn and
855         // associateNetworksToVpn
856         updateVpnMaps(vpn, name, null, tenant, null);
857
858         if (router != null) {
859             associateRouterToVpn(vpn, router);
860         }
861         if (networks != null) {
862             List<String> failStrings = associateNetworksToVpn(vpn, networks);
863             if (failStrings != null &&  !failStrings.isEmpty()) {
864                 LOG.error("L3VPN {} association to networks failed with error message {}. ",
865                         vpn.getValue(), failStrings.get(0));
866                 throw new Exception(failStrings.get(0));
867             }
868         }
869     }
870
871     /**
872      * It handles the invocations to the createL3VPN RPC method
873      *
874      * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#createL3VPN
875      * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNInput)
876      */
877     @Override
878     public Future<RpcResult<CreateL3VPNOutput>> createL3VPN(CreateL3VPNInput input) {
879
880         CreateL3VPNOutputBuilder opBuilder = new CreateL3VPNOutputBuilder();
881         SettableFuture<RpcResult<CreateL3VPNOutput>> result = SettableFuture.create();
882         List<RpcError> errorList = new ArrayList<>();
883         int failurecount = 0;
884         int warningcount = 0;
885
886         List<L3vpn> vpns = input.getL3vpn();
887         for (L3vpn vpn : vpns) {
888             RpcError error = null;
889             String msg;
890             if (vpn.getRouteDistinguisher() == null || vpn.getImportRT() == null || vpn.getExportRT() == null) {
891                 msg = String.format("Creation of L3VPN failed for VPN %s due to absence of RD/iRT/eRT input",
892                         vpn.getId().getValue());
893                 LOG.warn(msg);
894                 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
895                 errorList.add(error);
896                 warningcount++;
897                 continue;
898             }
899             if (vpn.getRouteDistinguisher().size() > 1) {
900                 msg = String.format("Creation of L3VPN failed for VPN %s due to multiple RD input %s",
901                         vpn.getId().getValue(), vpn.getRouteDistinguisher());
902                 LOG.warn(msg);
903                 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
904                 errorList.add(error);
905                 warningcount++;
906                 continue;
907             }
908             if (vpn.getRouterId() != null) {
909                 if (NeutronvpnUtils.getNeutronRouter(dataBroker, vpn.getRouterId()) == null) {
910                     msg = String.format("Creation of L3VPN failed for VPN %s due to router not found %s",
911                             vpn.getId().getValue(), vpn.getRouterId().getValue());
912                     LOG.warn(msg);
913                     error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
914                     errorList.add(error);
915                     warningcount++;
916                     continue;
917                 }
918                 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, vpn.getRouterId(), true);
919                 if (vpnId != null) {
920                     msg = String.format("Creation of L3VPN failed for VPN %s due to router %s already associated to "
921                                     + "another VPN %s", vpn.getId().getValue(), vpn.getRouterId().getValue(),
922                             vpnId.getValue());
923                     LOG.warn(msg);
924                     error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
925                     errorList.add(error);
926                     warningcount++;
927                     continue;
928                 }
929             }
930             if (vpn.getNetworkIds() != null) {
931                 for (Uuid nw : vpn.getNetworkIds()) {
932                     Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
933                     Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
934                     if (network == null) {
935                         msg = String.format("Creation of L3VPN failed for VPN %s due to network not found %s",
936                                 vpn.getId().getValue(), nw.getValue());
937                         LOG.warn(msg);
938                         error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
939                         errorList.add(error);
940                         warningcount++;
941                     } else if (vpnId != null) {
942                         msg = String.format("Creation of L3VPN failed for VPN %s due to network %s already associated"
943                                         + " to another VPN %s", vpn.getId().getValue(), nw.getValue(),
944                                 vpnId.getValue());
945                         LOG.warn(msg);
946                         error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
947                         errorList.add(error);
948                         warningcount++;
949                     }
950                 }
951                 if (error != null) {
952                     continue;
953                 }
954             }
955             try {
956                 createL3Vpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), vpn.getRouteDistinguisher(),
957                         vpn.getImportRT(), vpn.getExportRT(), vpn.getRouterId(), vpn.getNetworkIds());
958             } catch (Exception ex) {
959                 msg = String.format("Creation of L3VPN failed for VPN %s", vpn.getId().getValue());
960                 LOG.error(msg, ex);
961                 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
962                 errorList.add(error);
963                 failurecount++;
964             }
965         }
966         // if at least one succeeds; result is success
967         // if none succeeds; result is failure
968         if (failurecount + warningcount == vpns.size()) {
969             result.set(RpcResultBuilder.<CreateL3VPNOutput> failed().withRpcErrors(errorList).build());
970         } else {
971             List<String> errorResponseList = new ArrayList<>();
972             if (!errorList.isEmpty()) {
973                 for (RpcError rpcError : errorList) {
974                     String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
975                             .getErrorType(), rpcError.getTag(), rpcError.getMessage());
976                     errorResponseList.add(errorResponse);
977                 }
978             } else {
979                 errorResponseList.add("Operation successful with no errors");
980             }
981             opBuilder.setResponse(errorResponseList);
982             result.set(RpcResultBuilder.<CreateL3VPNOutput> success().withResult(opBuilder.build()).build());
983         }
984         return result;
985     }
986
987     /**
988      * It handles the invocations to the neutronvpn:getL3VPN RPC method
989      *
990      * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#getL3VPN
991      * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInput)
992      */
993     @Override
994     public Future<RpcResult<GetL3VPNOutput>> getL3VPN(GetL3VPNInput input) {
995
996         GetL3VPNOutputBuilder opBuilder = new GetL3VPNOutputBuilder();
997         SettableFuture<RpcResult<GetL3VPNOutput>> result = SettableFuture.create();
998         Uuid inputVpnId = input.getId();
999         List<VpnInstance> vpns = new ArrayList<>();
1000
1001         try {
1002             if (inputVpnId == null) {
1003                 // get all vpns
1004                 InstanceIdentifier<VpnInstances> vpnsIdentifier = InstanceIdentifier.builder(VpnInstances.class)
1005                         .build();
1006                 Optional<VpnInstances> optionalVpns = NeutronvpnUtils.read(dataBroker,
1007                         LogicalDatastoreType.CONFIGURATION,
1008                         vpnsIdentifier);
1009                 if (optionalVpns.isPresent() && optionalVpns.get().getVpnInstance() != null) {
1010                     for (VpnInstance vpn : optionalVpns.get().getVpnInstance()) {
1011                         // eliminating internal VPNs from getL3VPN output
1012                         if (vpn.getIpv4Family().getRouteDistinguisher() != null) {
1013                             vpns.add(vpn);
1014                         }
1015                     }
1016                 } else {
1017                     // No VPN present
1018                     result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withWarning(ErrorType.PROTOCOL, "", "No VPN " +
1019                             "is present").build());
1020                     return result;
1021                 }
1022             } else {
1023                 String name = inputVpnId.getValue();
1024                 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
1025                         .child(VpnInstance.class,
1026                                 new VpnInstanceKey(name))
1027                         .build();
1028                 // read VpnInstance Info
1029                 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1030                         vpnIdentifier);
1031                 if (optionalVpn.isPresent()) {
1032                     vpns.add(optionalVpn.get());
1033                 } else {
1034                     String message = String.format("GetL3VPN failed because VPN %s is not present", name);
1035                     LOG.error(message);
1036                     result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withWarning(ErrorType.PROTOCOL,
1037                             "invalid-value", message).build());
1038                 }
1039             }
1040             List<L3vpnInstances> l3vpnList = new ArrayList<>();
1041             for (VpnInstance vpnInstance : vpns) {
1042                 Uuid vpnId = new Uuid(vpnInstance.getVpnInstanceName());
1043                 // create VpnMaps id
1044                 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap
1045                         .class, new VpnMapKey(vpnId)).build();
1046                 L3vpnInstancesBuilder l3vpn = new L3vpnInstancesBuilder();
1047
1048                 List<String> rd = Arrays.asList(vpnInstance.getIpv4Family().getRouteDistinguisher().split(","));
1049                 List<VpnTarget> vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
1050
1051                 List<String> ertList = new ArrayList<>();
1052                 List<String> irtList = new ArrayList<>();
1053
1054                 for (VpnTarget vpnTarget : vpnTargetList) {
1055                     if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
1056                         ertList.add(vpnTarget.getVrfRTValue());
1057                     }
1058                     if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ImportExtcommunity) {
1059                         irtList.add(vpnTarget.getVrfRTValue());
1060                     }
1061                     if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.Both) {
1062                         ertList.add(vpnTarget.getVrfRTValue());
1063                         irtList.add(vpnTarget.getVrfRTValue());
1064                     }
1065                 }
1066
1067                 l3vpn.setId(vpnId).setRouteDistinguisher(rd).setImportRT(irtList).setExportRT(ertList);
1068                 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1069                         vpnMapIdentifier);
1070                 if (optionalVpnMap.isPresent()) {
1071                     VpnMap vpnMap = optionalVpnMap.get();
1072                     l3vpn.setRouterId(vpnMap.getRouterId()).setNetworkIds(vpnMap.getNetworkIds())
1073                             .setTenantId(vpnMap.getTenantId()).setName(vpnMap.getName());
1074                 }
1075                 l3vpnList.add(l3vpn.build());
1076             }
1077
1078             opBuilder.setL3vpnInstances(l3vpnList);
1079             result.set(RpcResultBuilder.<GetL3VPNOutput> success().withResult(opBuilder.build()).build());
1080
1081         } catch (Exception ex) {
1082             String message = String.format("GetL3VPN failed due to %s", ex.getMessage());
1083             LOG.error(message, ex);
1084             result.set(RpcResultBuilder.<GetL3VPNOutput> failed().withError(ErrorType.APPLICATION, message).build());
1085         }
1086         return result;
1087     }
1088
1089     /**
1090      * It handles the invocations to the neutronvpn:deleteL3VPN RPC method
1091      *
1092      * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#deleteL3VPN
1093      * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNInput)
1094      */
1095     @Override
1096     public Future<RpcResult<DeleteL3VPNOutput>> deleteL3VPN(DeleteL3VPNInput input) {
1097
1098         DeleteL3VPNOutputBuilder opBuilder = new DeleteL3VPNOutputBuilder();
1099         SettableFuture<RpcResult<DeleteL3VPNOutput>> result = SettableFuture.create();
1100         List<RpcError> errorList = new ArrayList<>();
1101
1102         int failurecount = 0;
1103         int warningcount = 0;
1104         List<Uuid> vpns = input.getId();
1105         for (Uuid vpn : vpns) {
1106             RpcError error;
1107             String msg;
1108             try {
1109                 InstanceIdentifier<VpnInstance> vpnIdentifier =
1110                         InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey
1111                                 (vpn.getValue())).build();
1112                 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
1113                 if (optionalVpn.isPresent()) {
1114                     removeL3Vpn(vpn);
1115                 } else {
1116                     msg = String.format("VPN with vpnid: %s does not exist", vpn.getValue());
1117                     LOG.warn(msg);
1118                     error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-value", msg);
1119                     errorList.add(error);
1120                     warningcount++;
1121                 }
1122             } catch (Exception ex) {
1123                 msg = String.format("Deletion of L3VPN failed when deleting for uuid %s", vpn.getValue());
1124                 LOG.error(msg, ex);
1125                 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
1126                 errorList.add(error);
1127                 failurecount++;
1128             }
1129         }
1130         // if at least one succeeds; result is success
1131         // if none succeeds; result is failure
1132         if (failurecount + warningcount == vpns.size()) {
1133             result.set(RpcResultBuilder.<DeleteL3VPNOutput> failed().withRpcErrors(errorList).build());
1134         } else {
1135             List<String> errorResponseList = new ArrayList<>();
1136             if (!errorList.isEmpty()) {
1137                 for (RpcError rpcError : errorList) {
1138                     String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
1139                             .getErrorType(), rpcError.getTag(), rpcError.getMessage());
1140                     errorResponseList.add(errorResponse);
1141                 }
1142             } else {
1143                 errorResponseList.add("Operation successful with no errors");
1144             }
1145             opBuilder.setResponse(errorResponseList);
1146             result.set(RpcResultBuilder.<DeleteL3VPNOutput> success().withResult(opBuilder.build()).build());
1147         }
1148         return result;
1149     }
1150
1151     protected void addSubnetToVpn(Uuid vpnId, Uuid subnet) {
1152         LOG.debug("Adding subnet {} to vpn {}", subnet.getValue(), vpnId.getValue());
1153         Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1154         boolean isLockAcquired = false;
1155         String lockName = vpnId.getValue() + subnet.getValue();
1156         String elanInstanceName = sn.getNetworkId().getValue();
1157         InstanceIdentifier<ElanInstance> elanIdentifierId =
1158                 InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class,
1159                         new ElanInstanceKey(elanInstanceName)).build();
1160         Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1161                 elanIdentifierId);
1162         long elanTag = elanInstance.get().getElanTag();
1163         Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1164         if (vpnId.equals(routerId)) {
1165             isExternalVpn = false;
1166         } else {
1167             isExternalVpn = true;
1168         }
1169         try {
1170             isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
1171             checkAndPublishSubnetAddNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn, elanTag);
1172             LOG.debug("Subnet added to Vpn notification sent");
1173         } catch (Exception e) {
1174             LOG.error("Subnet added to Vpn notification failed", e);
1175         } finally {
1176             if (isLockAcquired) {
1177                 NeutronvpnUtils.unlock(lockManager, lockName);
1178             }
1179         }
1180         // Check if there are ports on this subnet and add corresponding
1181         // vpn-interfaces
1182         List<Uuid> portList = sn.getPortList();
1183         if (portList != null) {
1184             for (Uuid port : sn.getPortList()) {
1185                 LOG.debug("adding vpn-interface for port {}", port.getValue());
1186                 createVpnInterface(vpnId, NeutronvpnUtils.getNeutronPort(dataBroker, port));
1187                 if (routerId != null) {
1188                     addToNeutronRouterInterfacesMap(routerId, port.getValue());
1189                 }
1190             }
1191         }
1192     }
1193
1194     protected void updateVpnForSubnet(Uuid vpnId, Uuid subnet, boolean isBeingAssociated) {
1195         LOG.debug("Updating VPN {} for subnet {}", vpnId.getValue(), subnet.getValue());
1196         // Read the subnet first to see if its already associated to a VPN
1197         Uuid oldVpnId = null;
1198         InstanceIdentifier<Subnetmap> snId = InstanceIdentifier.builder(Subnetmaps.class).
1199                 child(Subnetmap.class, new SubnetmapKey(subnet)).build();
1200         Subnetmap sn = null;
1201         Optional<Subnetmap> optSn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, snId);
1202         if (optSn.isPresent()) {
1203             sn = optSn.get();
1204             oldVpnId = sn.getVpnId();
1205             List<String> ips = sn.getRouterInterfaceFixedIps();
1206             for (String ipValue : ips) {
1207                 IpAddress ip = new IpAddress(ipValue.toCharArray());
1208                 if (oldVpnId != null) {
1209                     NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(), ipValue);
1210                 }
1211                 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, sn
1212                         .getRouterInterfaceName().getValue(), sn.getRouterIntfMacAddress(), true, true, false);
1213             }
1214         }
1215         sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1216         boolean isLockAcquired = false;
1217         String lockName = vpnId.getValue() + subnet.getValue();
1218         String elanInstanceName = sn.getNetworkId().getValue();
1219         InstanceIdentifier<ElanInstance> elanIdentifierId =
1220                 InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class,
1221                         new ElanInstanceKey(elanInstanceName)).build();
1222         Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1223                 elanIdentifierId);
1224         long elanTag = elanInstance.get().getElanTag();
1225         try {
1226             isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
1227             checkAndPublishSubnetUpdNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isBeingAssociated,
1228                     elanTag);
1229             LOG.debug("Subnet updated in Vpn notification sent");
1230         } catch (Exception e) {
1231             LOG.error("Subnet updated in Vpn notification failed", e);
1232         } finally {
1233             if (isLockAcquired) {
1234                 NeutronvpnUtils.unlock(lockManager, lockName);
1235             }
1236         }
1237         // Check for ports on this subnet and update association of
1238         // corresponding vpn-interfaces to external vpn
1239         List<Uuid> portList = sn.getPortList();
1240         if (portList != null) {
1241             for (Uuid port : sn.getPortList()) {
1242                 LOG.debug("Updating vpn-interface for port {}", port.getValue());
1243                 updateVpnInterface(vpnId, oldVpnId, NeutronvpnUtils.getNeutronPort(dataBroker, port), isBeingAssociated);
1244             }
1245         }
1246     }
1247
1248     InstanceIdentifier<RouterInterfaces> getRouterInterfacesId(Uuid routerId) {
1249         return InstanceIdentifier.builder(RouterInterfacesMap.class)
1250                 .child(RouterInterfaces.class, new RouterInterfacesKey(routerId)).build();
1251     }
1252     void addToNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1253         InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1254         Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1255                 .CONFIGURATION, routerInterfacesId);
1256         Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId
1257                 (interfaceName).build();
1258         if (optRouterInterfaces.isPresent()) {
1259             MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1260                     .class, new InterfacesKey(interfaceName)), routerInterface);
1261         } else {
1262             RouterInterfacesBuilder builder = new RouterInterfacesBuilder().setRouterId(routerId);
1263             List<Interfaces> interfaces = new ArrayList<>();
1264             interfaces.add(routerInterface);
1265             MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId, builder.setInterfaces
1266                     (interfaces).build());
1267         }
1268     }
1269
1270     void removeFromNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1271         InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1272         Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1273                 .CONFIGURATION, routerInterfacesId);
1274         Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId
1275                 (interfaceName).build();
1276         if (optRouterInterfaces.isPresent()) {
1277             RouterInterfaces routerInterfaces = optRouterInterfaces.get();
1278             List<Interfaces> interfaces = routerInterfaces.getInterfaces();
1279             if (interfaces != null && interfaces.remove(routerInterface)) {
1280                 if (interfaces.isEmpty()) {
1281                     MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1282                 } else {
1283                     MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
1284                             routerInterfacesId.child(Interfaces.class, new InterfacesKey(interfaceName)));
1285                 }
1286             }
1287         }
1288     }
1289
1290     /**
1291      * Creates the corresponding static routes in the specified VPN. These static routes must be point to an
1292      * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink. Otherwise the
1293      * route will be ignored.
1294      *
1295      * @param vpnName the VPN identifier
1296      * @param interVpnLinkRoutes The list of static routes
1297      * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1298      */
1299     public void addInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1300                                   HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1301         for ( Routes route : interVpnLinkRoutes ) {
1302             String nexthop = String.valueOf(route.getNexthop().getValue());
1303             String destination = String.valueOf(route.getDestination().getValue());
1304             InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1305             if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1306                 AddStaticRouteInput rpcInput =
1307                         new AddStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1308                                 .setVpnInstanceName(vpnName.getValue())
1309                                 .build();
1310                 Future<RpcResult<AddStaticRouteOutput>> labelOuputFtr = vpnRpcService.addStaticRoute(rpcInput);
1311                 RpcResult<AddStaticRouteOutput> rpcResult;
1312                 try {
1313                     rpcResult = labelOuputFtr.get();
1314                     if ( rpcResult.isSuccessful() ) {
1315                         LOG.debug("Label generated for destination {} is: {}",
1316                                 destination, rpcResult.getResult().getLabel());
1317                     } else {
1318                         LOG.warn("RPC call to add a static Route to {} with nexthop {} returned with errors {}",
1319                                 destination, nexthop, rpcResult.getErrors());
1320                     }
1321                 } catch (InterruptedException | ExecutionException e) {
1322                     LOG.warn("Error happened while invoking addStaticRoute RPC: {}", e);
1323                 }
1324             } else {
1325                 // Any other case is a fault.
1326                 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1327                         String.valueOf(route.getDestination().getValue()), nexthop );
1328                 continue;
1329             }
1330         }
1331     }
1332
1333     /**
1334      * Removes the corresponding static routes from the specified VPN. These static routes point to an
1335      * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink.
1336      *
1337      * @param vpnName the VPN identifier
1338      * @param interVpnLinkRoutes The list of static routes
1339      * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1340      */
1341     public void removeInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1342                                      HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1343         for ( Routes route : interVpnLinkRoutes ) {
1344             String nexthop = String.valueOf(route.getNexthop().getValue());
1345             String destination = String.valueOf(route.getDestination().getValue());
1346             InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1347             if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1348                 RemoveStaticRouteInput rpcInput =
1349                         new RemoveStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1350                                 .setVpnInstanceName(vpnName.getValue())
1351                                 .build();
1352                 vpnRpcService.removeStaticRoute(rpcInput);
1353             } else {
1354                 // Any other case is a fault.
1355                 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1356                         String.valueOf(route.getDestination().getValue()), nexthop );
1357                 continue;
1358             }
1359         }
1360     }
1361
1362     /*
1363      * Returns true if the specified nexthop is the other endpoint in an
1364      * InterVpnLink, regarding one of the VPN's point of view.
1365      */
1366     private boolean isNexthopTheOtherVpnLinkEndpoint(String nexthop, String thisVpnUuid, InterVpnLink interVpnLink) {
1367         return
1368                 interVpnLink != null
1369                         && (   (interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(thisVpnUuid)
1370                         && interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(nexthop))
1371                         || (interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(thisVpnUuid )
1372                         && interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(nexthop)) );
1373     }
1374
1375     protected List<Adjacency> addAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList) {
1376         List<Adjacency> adjList = new ArrayList<Adjacency>();
1377         Map<String, List<String>> adjMap = new HashMap<>();
1378         for (Routes route : routeList) {
1379             if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1380                 LOG.error("Incorrect input received for extra route. {}", route);
1381             } else {
1382                 String nextHop = String.valueOf(route.getNexthop().getValue());
1383                 String destination = String.valueOf(route.getDestination().getValue());
1384                 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(), nextHop);
1385                 if (infName == null) {
1386                     LOG.error("Unable to find VPN NextHop interface to apply extra-route destination {} on VPN {} with nexthop {}",
1387                             destination, vpnId.getValue(), nextHop);
1388                     // Proceed to process the next extra-route
1389                     continue;
1390                 }
1391                 LOG.trace("Adding extra route for destination {} onto vpn {} with nexthop {} and infName {}", destination,
1392                         vpnId.getValue(), nextHop, infName);
1393                 List<String> hops = adjMap.get(destination);
1394                 if (hops == null){
1395                     hops = new ArrayList<>();
1396                     adjMap.put(destination, hops);
1397                 }
1398                 if (! hops.contains(nextHop))
1399                     hops.add(nextHop);
1400             }
1401         }
1402
1403         for (String destination : adjMap.keySet()) {
1404             Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIpList(adjMap.get
1405                     (destination)).setKey(new AdjacencyKey(destination)).build();
1406             adjList.add(erAdj);
1407         }
1408
1409         for (Adjacency adj : adjList) {
1410             for(String nextHop : adj.getNextHopIpList()) {
1411                 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(), nextHop);
1412                 if ( infName != null ) {
1413                     InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class)
1414                             .child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1415                     boolean isLockAcquired = false;
1416                     try {
1417                         Optional<VpnInterface> optionalVpnInterface =
1418                                 NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
1419                         if (optionalVpnInterface.isPresent()) {
1420                             Adjacency newAdj = new AdjacencyBuilder(adj).setNextHopIpList(Arrays.asList(nextHop))
1421                                     .build();
1422                             Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(newAdj)).build();
1423                             VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
1424                                     .addAugmentation(Adjacencies.class, erAdjs).build();
1425                             isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
1426                             MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
1427                         } else {
1428                             LOG.error("VM adjacency for interface {} not present; cannot add extra route adjacency",
1429                                     infName);
1430                         }
1431                     } catch (Exception e) {
1432                         LOG.error("exception in adding extra route with destination: {}, next hop: {}", adj
1433                                 .getIpAddress(), nextHop, e);
1434                     } finally {
1435                         if (isLockAcquired) {
1436                             NeutronvpnUtils.unlock(lockManager, infName);
1437                         }
1438                     }
1439                 } else {
1440                     LOG.warn("Could not find suitable Interface for {}", nextHop);
1441                 }
1442
1443             }
1444         }
1445         return adjList;
1446     }
1447
1448     protected void removeAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList) {
1449         for (Routes route : routeList) {
1450             if (route != null && route.getNexthop() != null && route.getDestination() != null) {
1451                 boolean isLockAcquired = false;
1452                 String nextHop = String.valueOf(route.getNexthop().getValue());
1453                 String destination = String.valueOf(route.getDestination().getValue());
1454                 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(), nextHop);
1455                 if (infName == null) {
1456                     LOG.error("Unable to find VPN NextHop interface to remove extra-route destination {} on VPN {} with nexthop {}",
1457                             destination, vpnId.getValue(), nextHop);
1458                     // Proceed to remove the next extra-route
1459                     continue;
1460                 }
1461                 LOG.trace("Removing extra route for destination {} on vpn {} with nexthop {} and infName {}",
1462                         destination, vpnId.getValue(), nextHop, infName);
1463
1464                 InstanceIdentifier<Adjacency> adjacencyIdentifier =
1465                         InstanceIdentifier.builder(VpnInterfaces.class)
1466                                 .child(VpnInterface.class, new VpnInterfaceKey(infName))
1467                                 .augmentation(Adjacencies.class)
1468                                 .child(Adjacency.class, new AdjacencyKey(destination))
1469                                 .build();
1470
1471                 // Looking for existing prefix in MDSAL database
1472                 Optional<Adjacency> adjacency = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1473                         adjacencyIdentifier);
1474                 boolean updateNextHops = false;
1475                 List<String> nextHopList = new ArrayList<>();
1476                 if (adjacency.isPresent()) {
1477                     List<String> nhListRead = adjacency.get().getNextHopIpList();
1478                     if (nhListRead.size() > 1) { // ECMP case
1479                         for (String nextHopRead : nhListRead) {
1480                             if (nextHopRead.equals(nextHop)) {
1481                                 updateNextHops = true;
1482                             } else {
1483                                 nextHopList.add(nextHopRead);
1484                             }
1485                         }
1486                     }
1487                 }
1488
1489                 try {
1490                     isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
1491                     if (updateNextHops) {
1492                         // An update must be done, not including the current next hop
1493                         InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
1494                                 VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1495                         Adjacency newAdj = new AdjacencyBuilder(adjacency.get()).setIpAddress(destination)
1496                                 .setNextHopIpList(nextHopList)
1497                                 .setKey(new AdjacencyKey(destination))
1498                                 .build();
1499                         Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(newAdj)).build();
1500                         VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
1501                                 .addAugmentation(Adjacencies.class, erAdjs).build();
1502                         MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
1503                     } else {
1504                         // Remove the whole route
1505                         MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
1506                         LOG.trace("extra route {} deleted successfully", route);
1507                     }
1508                 } catch (Exception e) {
1509                     LOG.error("exception in deleting extra route: {}" + e);
1510                 } finally {
1511                     if (isLockAcquired) {
1512                         NeutronvpnUtils.unlock(lockManager, infName);
1513                     }
1514                 }
1515             } else {
1516                 LOG.error("Incorrect input received for extra route. {}", route);
1517             }
1518         }
1519     }
1520
1521     protected void removeL3Vpn(Uuid id) {
1522         // read VPNMaps
1523         VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, id);
1524         Uuid router = vpnMap.getRouterId();
1525         // dissociate router
1526         if (router != null) {
1527             dissociateRouterFromVpn(id, router);
1528         }
1529         // dissociate networks
1530         if (!id.equals(router)) {
1531             dissociateNetworksFromVpn(id, vpnMap.getNetworkIds());
1532         }
1533         // remove entire vpnMaps node
1534         deleteVpnMapsNode(id);
1535
1536         // remove vpn-instance
1537         deleteVpnInstance(id);
1538     }
1539
1540     protected void removeSubnetFromVpn(Uuid vpnId, Uuid subnet) {
1541         LOG.debug("Removing subnet {} from vpn {}", subnet.getValue(), vpnId.getValue());
1542         Subnetmap sn = NeutronvpnUtils.getSubnetmap(dataBroker, subnet);
1543         boolean isLockAcquired = false;
1544         String lockName = vpnId.getValue() + subnet.getValue();
1545         String elanInstanceName = sn.getNetworkId().getValue();
1546         InstanceIdentifier<ElanInstance> elanIdentifierId =
1547                 InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class,
1548                         new ElanInstanceKey(elanInstanceName)).build();
1549         Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1550                 elanIdentifierId);
1551         long elanTag = elanInstance.get().getElanTag();
1552         Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1553         if (vpnId.equals(routerId)) {
1554             isExternalVpn = false;
1555         } else {
1556             isExternalVpn = true;
1557         }
1558         try {
1559             isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
1560             checkAndPublishSubnetDelNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn, elanTag);
1561             LOG.debug("Subnet removed from Vpn notification sent");
1562         } catch (Exception e) {
1563             LOG.error("Subnet removed from Vpn notification failed", e);
1564         } finally {
1565             if (isLockAcquired) {
1566                 NeutronvpnUtils.unlock(lockManager, lockName);
1567             }
1568         }
1569         if (sn != null) {
1570             // Check if there are ports on this subnet; remove corresponding vpn-interfaces
1571             List<Uuid> portList = sn.getPortList();
1572             if (portList != null) {
1573                 for (Uuid port : sn.getPortList()) {
1574                     LOG.debug("removing vpn-interface for port {}", port.getValue());
1575                     deleteVpnInterface(vpnId, NeutronvpnUtils.getNeutronPort(dataBroker, port));
1576                     if (routerId != null) {
1577                         removeFromNeutronRouterInterfacesMap(routerId, port.getValue());
1578                     }
1579                 }
1580             }
1581             // update subnet-vpn association
1582             removeFromSubnetNode(subnet, null, null, vpnId, null);
1583         } else {
1584             LOG.warn("Subnetmap for subnet {} not found", subnet.getValue());
1585         }
1586     }
1587
1588     protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
1589         updateVpnMaps(vpnId, null, routerId, null, null);
1590         LOG.debug("Updating association of subnets to external vpn {}", vpnId.getValue());
1591         List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1592 //        if (!vpnId.equals(routerId)) {
1593         if (routerSubnets != null) {
1594             for (Uuid subnetId : routerSubnets) {
1595                 updateVpnForSubnet(vpnId, subnetId, true);
1596             }
1597         }
1598         try {
1599             checkAndPublishRouterAssociatedtoVpnNotification(routerId, vpnId);
1600             LOG.debug("notification upon association of router {} to VPN {} published", routerId.getValue(),
1601                     vpnId.getValue());
1602         } catch (Exception e) {
1603             LOG.error("publishing of notification upon association of router {} to VPN {} failed : ", routerId
1604                     .getValue(), vpnId.getValue(), e);
1605         }
1606 //        }
1607 //        else {
1608 //            LOG.debug("Adding subnets to internal vpn {}", vpnId.getValue());
1609 //            for (Uuid subnet : routerSubnets) {
1610 //                addSubnetToVpn(vpnId, subnet);
1611 //            }
1612 //        }
1613     }
1614
1615     protected void associateRouterToInternalVpn(Uuid vpnId, Uuid routerId) {
1616         List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1617         LOG.debug("Adding subnets to internal vpn {}", vpnId.getValue());
1618         for (Uuid subnet : routerSubnets) {
1619             addSubnetToVpn(vpnId, subnet);
1620         }
1621     }
1622
1623     protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
1624
1625         List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1626         if (routerSubnets != null) {
1627             for (Uuid subnetId : routerSubnets) {
1628                 LOG.debug("Updating association of subnets to internal vpn {}", routerId.getValue());
1629                 updateVpnForSubnet(routerId, subnetId, false);
1630             }
1631         }
1632         clearFromVpnMaps(vpnId, routerId, null);
1633         try {
1634             checkAndPublishRouterDisassociatedFromVpnNotification(routerId, vpnId);
1635             LOG.debug("notification upon disassociation of router {} from VPN {} published", routerId.getValue(),
1636                     vpnId.getValue());
1637         } catch (Exception e) {
1638             LOG.error("publishing of notification upon disassociation of router {} from VPN {} failed : ", routerId
1639                     .getValue(), vpnId.getValue(), e);
1640         }
1641     }
1642
1643     protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
1644         List<String> failedNwList = new ArrayList<>();
1645         List<Uuid> passedNwList = new ArrayList<>();
1646         if (!networks.isEmpty()) {
1647             // process corresponding subnets for VPN
1648             for (Uuid nw : networks) {
1649                 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1650                 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1651                 if (network == null) {
1652                     failedNwList.add(String.format("network %s not found", nw.getValue()));
1653                 } else if (vpnId != null) {
1654                     failedNwList.add(String.format("network %s already associated to another VPN %s", nw.getValue(),
1655                             vpnId.getValue()));
1656                 } else {
1657                     List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1658                     LOG.debug("Adding network subnets...{}", networkSubnets);
1659                     if (networkSubnets != null) {
1660                         for (Uuid subnet : networkSubnets) {
1661                             // check if subnet added as router interface to some router
1662                             Uuid subnetVpnId = NeutronvpnUtils.getVpnForSubnet(dataBroker, subnet);
1663                             if (subnetVpnId == null) {
1664                                 addSubnetToVpn(vpn, subnet);
1665                                 passedNwList.add(nw);
1666                             } else {
1667                                 failedNwList.add(String.format("subnet %s already added as router interface bound to " +
1668                                         "internal/external VPN %s", subnet.getValue (), subnetVpnId.getValue()));
1669                             }
1670                         }
1671                     }
1672                     if (NeutronvpnUtils.getIsExternal(network)) {
1673                         nvpnNatManager.addExternalNetworkToVpn(network, vpn);
1674                     }
1675                 }
1676             }
1677             updateVpnMaps(vpn, null, null, null, passedNwList);
1678         }
1679         return failedNwList;
1680     }
1681
1682     protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
1683         List<String> failedNwList = new ArrayList<>();
1684         List<Uuid> passedNwList = new ArrayList<>();
1685         if (networks != null && !networks.isEmpty()) {
1686             // process corresponding subnets for VPN
1687             for (Uuid nw : networks) {
1688                 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1689                 if (network == null) {
1690                     failedNwList.add(String.format("network %s not found", nw.getValue()));
1691                 } else {
1692                     Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1693                     if (vpn.equals(vpnId)) {
1694                         List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1695                         LOG.debug("Removing network subnets...");
1696                         if (networkSubnets != null) {
1697                             for (Uuid subnet : networkSubnets) {
1698                                 removeSubnetFromVpn(vpn, subnet);
1699                                 passedNwList.add(nw);
1700                             }
1701                         }
1702                     } else {
1703                         if (vpnId == null) {
1704                             failedNwList.add(String.format("input network %s not associated to any vpn yet", nw
1705                                     .getValue()));
1706                         } else {
1707                             failedNwList.add(String.format("input network %s associated to a another vpn %s instead " +
1708                                     "of the one given as input", nw.getValue(), vpnId.getValue()));
1709                         }
1710                     }
1711                     if (NeutronvpnUtils.getIsExternal(network)) {
1712                         nvpnNatManager.removeExternalNetworkFromVpn(network);
1713                     }
1714                 }
1715             }
1716             clearFromVpnMaps(vpn, null, passedNwList);
1717         }
1718         return failedNwList;
1719     }
1720
1721     /**
1722      * It handles the invocations to the neutronvpn:associateNetworks RPC method
1723      *
1724      * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#associateNetworks
1725      * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksInput)
1726      */
1727     @Override
1728     public Future<RpcResult<AssociateNetworksOutput>> associateNetworks(AssociateNetworksInput input) {
1729
1730         AssociateNetworksOutputBuilder opBuilder = new AssociateNetworksOutputBuilder();
1731         SettableFuture<RpcResult<AssociateNetworksOutput>> result = SettableFuture.create();
1732         LOG.debug("associateNetworks {}", input);
1733         StringBuilder returnMsg = new StringBuilder();
1734         Uuid vpnId = input.getVpnId();
1735
1736         try {
1737             if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1738                 List<Uuid> netIds = input.getNetworkId();
1739                 if (netIds != null && !netIds.isEmpty()) {
1740                     List<String> failed = associateNetworksToVpn(vpnId, netIds);
1741                     if (!failed.isEmpty()) {
1742                         returnMsg.append(failed);
1743                     }
1744                 }
1745             } else {
1746                 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1747             }
1748             if (returnMsg.length() != 0) {
1749                 String message = String.format("associate Networks to vpn %s failed due to %s",
1750                         vpnId.getValue(), returnMsg);
1751                 LOG.error(message);
1752                 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: %s",
1753                         message);
1754                 opBuilder.setResponse(errorResponse);
1755                 result.set(RpcResultBuilder.<AssociateNetworksOutput> success().withResult(opBuilder.build()).build());
1756             } else {
1757                 result.set(RpcResultBuilder.<AssociateNetworksOutput> success().build());
1758             }
1759         } catch (Exception ex) {
1760             String message = String.format("associate Networks to vpn %s failed due to %s",
1761                     input.getVpnId().getValue(), ex.getMessage());
1762             LOG.error(message, ex);
1763             result.set(RpcResultBuilder.<AssociateNetworksOutput> failed().withError(ErrorType.APPLICATION, message)
1764                     .build());
1765         }
1766         LOG.debug("associateNetworks returns..");
1767         return result;
1768     }
1769
1770     /**
1771      * It handles the invocations to the neutronvpn:associateRouter RPC method
1772      *
1773      * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#associateRouter
1774      * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateRouterInput)
1775      */
1776     @Override
1777     public Future<RpcResult<Void>> associateRouter(AssociateRouterInput input) {
1778
1779         SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1780         LOG.debug("associateRouter {}", input);
1781         StringBuilder returnMsg = new StringBuilder();
1782         Uuid vpnId = input.getVpnId();
1783         Uuid routerId = input.getRouterId();
1784         try {
1785             if (routerId != null && vpnId != null) {
1786                 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1787                 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, vpnId);
1788                 if (rtr != null && vpnMap != null) {
1789                     Uuid extVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1790                     if (vpnMap.getRouterId() != null) {
1791                         returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
1792                                 .append(vpnMap.getRouterId().getValue());
1793                     } else if (extVpnId != null) {
1794                         returnMsg.append("router ").append(routerId.getValue()).append(" already associated to " +
1795                                 "another VPN ").append(extVpnId.getValue());
1796                     } else {
1797                         associateRouterToVpn(vpnId, routerId);
1798                     }
1799                 } else {
1800                     returnMsg.append("router not found : ").append(routerId.getValue());
1801                 }
1802             } else {
1803                 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1804             }
1805             if (returnMsg.length() != 0) {
1806                 String message = String.format("associate router to vpn %s failed due to %s", routerId.getValue(),
1807                         returnMsg);
1808                 LOG.error(message);
1809                 result.set(RpcResultBuilder.<Void> failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1810                         .build());
1811             } else {
1812                 result.set(RpcResultBuilder.<Void> success().build());
1813             }
1814         } catch (Exception ex) {
1815             String message = String.format("associate router %s to vpn %s failed due to %s", routerId.getValue(),
1816                     vpnId.getValue(), ex.getMessage());
1817             LOG.error(message, ex);
1818             result.set(RpcResultBuilder.<Void> failed().withError(ErrorType.APPLICATION, message).build());
1819         }
1820         LOG.debug("associateRouter returns..");
1821         return result;
1822     }
1823
1824     /** It handles the invocations to the neutronvpn:getFixedIPsForNeutronPort RPC method
1825      *
1826      * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#getFixedIPsForNeutronPort
1827      * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInput)
1828      */
1829     @Override
1830     public Future<RpcResult<GetFixedIPsForNeutronPortOutput>> getFixedIPsForNeutronPort(GetFixedIPsForNeutronPortInput input) {
1831         GetFixedIPsForNeutronPortOutputBuilder opBuilder = new GetFixedIPsForNeutronPortOutputBuilder();
1832         SettableFuture<RpcResult<GetFixedIPsForNeutronPortOutput>> result = SettableFuture.create();
1833         Uuid portId = input.getPortId();
1834         StringBuilder returnMsg = new StringBuilder();
1835         try {
1836             List<String> fixedIPList = new ArrayList<>();
1837             Port port = NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1838             if (port != null) {
1839                 List<FixedIps> fixedIPs = port.getFixedIps();
1840                 for (FixedIps ip : fixedIPs) {
1841                     fixedIPList.add(ip.getIpAddress().getIpv4Address().getValue());
1842                 }
1843             } else {
1844                 returnMsg.append("neutron port: ").append(portId.getValue()).append(" not found");
1845             }
1846             if (returnMsg.length() != 0) {
1847                 String message = String.format("Retrieval of FixedIPList for neutron port failed due to %s", returnMsg);
1848                 LOG.error(message);
1849                 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> failed()
1850                         .withWarning(ErrorType.PROTOCOL, "invalid-value", message).build());
1851             } else {
1852                 opBuilder.setFixedIPs(fixedIPList);
1853                 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> success().withResult(opBuilder.build())
1854                         .build());
1855                 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> success().build());
1856             }
1857         } catch (Exception ex) {
1858             String message = String.format("Retrieval of FixedIPList for neutron port %s failed due to %s",
1859                     portId.getValue(), ex.getMessage());
1860             LOG.error(message, ex);
1861             result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> failed()
1862                     .withError(ErrorType.APPLICATION, message).build());
1863         }
1864         return result;
1865     }
1866
1867     /**
1868      * It handles the invocations to the neutronvpn:dissociateNetworks RPC method
1869      *
1870      * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1871      * .rev150602.NeutronvpnService#dissociateNetworks(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
1872      * .neutronvpn.rev150602.DissociateNetworksInput)
1873      */
1874     @Override
1875     public Future<RpcResult<DissociateNetworksOutput>> dissociateNetworks(DissociateNetworksInput input) {
1876
1877         DissociateNetworksOutputBuilder opBuilder = new DissociateNetworksOutputBuilder();
1878         SettableFuture<RpcResult<DissociateNetworksOutput>> result = SettableFuture.create();
1879
1880         LOG.debug("dissociateNetworks {}", input);
1881         StringBuilder returnMsg = new StringBuilder();
1882         Uuid vpnId = input.getVpnId();
1883
1884         try {
1885             if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1886                 List<Uuid> netIds = input.getNetworkId();
1887                 if (netIds != null && !netIds.isEmpty()) {
1888                     List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
1889                     if (!failed.isEmpty()) {
1890                         returnMsg.append(failed);
1891                     }
1892                 }
1893             } else {
1894                 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1895             }
1896             if (returnMsg.length() != 0) {
1897                 String message = String.format("dissociate Networks to vpn %s failed due to %s", vpnId.getValue(),
1898                         returnMsg);
1899                 LOG.error(message);
1900                 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1901                         + message);
1902                 opBuilder.setResponse(errorResponse);
1903                 result.set(RpcResultBuilder.<DissociateNetworksOutput> success().withResult(opBuilder.build()).build());
1904             } else {
1905                 result.set(RpcResultBuilder.<DissociateNetworksOutput> success().build());
1906             }
1907         } catch (Exception ex) {
1908             String message = String.format("dissociate Networks to vpn %s failed due to %s",
1909                     input.getVpnId().getValue(), ex.getMessage());
1910             LOG.error(message, ex);
1911             result.set(RpcResultBuilder.<DissociateNetworksOutput> failed().withError(ErrorType.APPLICATION, message)
1912                     .build());
1913         }
1914         LOG.debug("dissociateNetworks returns..");
1915         return result;
1916     }
1917
1918     /**
1919      * It handles the invocations to the neutronvpn:dissociateRouter RPC method.
1920      *
1921      * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1922      * .rev150602.NeutronvpnService#dissociateRouter(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1923      * .rev150602.DissociateRouterInput)
1924      */
1925     @Override
1926     public Future<RpcResult<Void>> dissociateRouter(DissociateRouterInput input) {
1927
1928         SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1929
1930         LOG.debug("dissociateRouter {}", input);
1931         StringBuilder returnMsg = new StringBuilder();
1932         Uuid vpnId = input.getVpnId();
1933         Uuid routerId = input.getRouterId();
1934         try {
1935             if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1936                 if (routerId != null) {
1937                     Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1938                     if (rtr != null) {
1939                         Uuid routerVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1940                         if (vpnId.equals(routerVpnId)) {
1941                             dissociateRouterFromVpn(vpnId, routerId);
1942                         } else {
1943                             if (routerVpnId == null) {
1944                                 returnMsg.append("input router ").append(routerId.getValue()).append(" not associated" +
1945                                         " to any vpn yet");
1946                             } else {
1947                                 returnMsg.append("input router ").append(routerId.getValue()).append(" associated to " +
1948                                         "vpn ").append(routerVpnId.getValue()).append("instead of the vpn given as " +
1949                                         "input");
1950                             }
1951                         }
1952                     } else {
1953                         returnMsg.append("router not found : ").append(routerId.getValue());
1954                     }
1955                 }
1956             } else {
1957                 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1958             }
1959             if (returnMsg.length() != 0) {
1960                 String message = String.format("dissociate router %s to vpn %s failed due to %s", routerId.getValue(),
1961                         vpnId.getValue(), returnMsg);
1962                 LOG.error(message);
1963                 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1964                         + message);
1965                 result.set(RpcResultBuilder.<Void> failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1966                         .build());
1967             } else {
1968                 result.set(RpcResultBuilder.<Void> success().build());
1969             }
1970         } catch (Exception ex) {
1971             String message = String.format("disssociate router %s to vpn %s failed due to %s", routerId.getValue(),
1972                     vpnId.getValue(), ex.getMessage());
1973             LOG.error(message, ex);
1974             result.set(RpcResultBuilder.<Void> failed().withError(ErrorType.APPLICATION, message).build());
1975         }
1976         LOG.debug("dissociateRouter returns..");
1977
1978         return result;
1979     }
1980
1981     protected void handleNeutronRouterDeleted(Uuid routerId, List<Uuid> routerSubnetIds) {
1982         // check if the router is associated to some VPN
1983         Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1984         if (vpnId != null) {
1985             // remove existing external vpn interfaces
1986             for (Uuid subnetId : routerSubnetIds) {
1987                 removeSubnetFromVpn(vpnId, subnetId);
1988             }
1989             clearFromVpnMaps(vpnId, routerId, null);
1990         } else {
1991             // remove existing internal vpn interfaces
1992             for (Uuid subnetId : routerSubnetIds) {
1993                 removeSubnetFromVpn(routerId, subnetId);
1994             }
1995         }
1996         // delete entire vpnMaps node for internal VPN
1997         deleteVpnMapsNode(routerId);
1998
1999         // delete vpn-instance for internal VPN
2000         deleteVpnInstance(routerId);
2001     }
2002
2003     protected Subnet getNeutronSubnet(Uuid subnetId){
2004         return NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
2005     }
2006
2007     protected IpAddress getNeutronSubnetGateway(Uuid subnetId) {
2008         Subnet sn = NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
2009         if (null != sn) {
2010             return sn.getGatewayIp();
2011         }
2012         return null;
2013     }
2014
2015
2016     protected Network getNeutronNetwork(Uuid networkId) {
2017         return NeutronvpnUtils.getNeutronNetwork(dataBroker, networkId);
2018     }
2019
2020     protected Port getNeutronPort(String name) {
2021         return NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(name));
2022     }
2023
2024     protected Port getNeutronPort(Uuid portId) {
2025         return NeutronvpnUtils.getNeutronPort(dataBroker, portId);
2026     }
2027
2028     protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
2029         List<Uuid> subnets = new ArrayList<>();
2030         // read subnetmaps
2031         InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
2032         Optional<Subnetmaps> subnetmaps = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
2033                 subnetmapsid);
2034         if (subnetmaps.isPresent() && subnetmaps.get().getSubnetmap() != null) {
2035             List<Subnetmap> subnetMapList = subnetmaps.get().getSubnetmap();
2036             for (Subnetmap subnetMap : subnetMapList) {
2037                 if (subnetMap.getVpnId() != null && subnetMap.getVpnId().equals(vpnid)) {
2038                     subnets.add(subnetMap.getId());
2039                 }
2040             }
2041         }
2042         return subnets;
2043     }
2044
2045     /**
2046      * Implementation of the "vpnservice:neutron-ports-show" Karaf CLI command
2047      *
2048      * @return a List of String to be printed on screen
2049      */
2050     public List<String> showNeutronPortsCLI() {
2051         List<String> result = new ArrayList<>();
2052         result.add(String.format(" %-36s  %-19s  %-13s  %-20s ", "Port ID", "Mac Address", "Prefix Length", "IP " +
2053                 "Address"));
2054         result.add("-------------------------------------------------------------------------------------------");
2055         InstanceIdentifier<Ports> portidentifier = InstanceIdentifier.create(Neutron.class).child(Ports.class);
2056         try {
2057             Optional<Ports> ports = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, portidentifier);
2058             if (ports.isPresent() && ports.get().getPort() != null) {
2059                 for (Port port : ports.get().getPort()) {
2060                     List<FixedIps> fixedIPs = port.getFixedIps();
2061                     try {
2062                         if (fixedIPs != null && !fixedIPs.isEmpty()) {
2063                             List<String> ipList = new ArrayList<>();
2064                             for (FixedIps fixedIp : fixedIPs) {
2065                                 IpAddress ipAddress = fixedIp.getIpAddress();
2066                                 if (ipAddress.getIpv4Address() != null) {
2067                                     ipList.add(ipAddress.getIpv4Address().getValue());
2068                                 } else {
2069                                     ipList.add((ipAddress.getIpv6Address().getValue()));
2070                                 }
2071                             }
2072                             result.add(String.format(" %-36s  %-19s  %-13s  %-20s ", port.getUuid().getValue(), port
2073                                     .getMacAddress().getValue(), NeutronvpnUtils.getIPPrefixFromPort(dataBroker, port),
2074                                     ipList.toString()));
2075                         } else {
2076                             result.add(String.format(" %-36s  %-19s  %-13s  %-20s ", port.getUuid().getValue(), port
2077                                     .getMacAddress().getValue(), "Not Assigned", "Not " + "Assigned"));
2078                         }
2079                     } catch (Exception e) {
2080                         LOG.error("Failed to retrieve neutronPorts info for port {}: ", port.getUuid().getValue(),
2081                                 e);
2082                         System.out.println("Failed to retrieve neutronPorts info for port: " + port.getUuid()
2083                                 .getValue() + ": " + e.getMessage());
2084                     }
2085                 }
2086             }
2087         } catch (Exception e) {
2088             LOG.error("Failed to retrieve neutronPorts info : ", e);
2089             System.out.println("Failed to retrieve neutronPorts info : " + e.getMessage());
2090         }
2091         return result;
2092     }
2093
2094     /**
2095      * Implementation of the "vpnservice:l3vpn-config-show" karaf CLI command
2096      *
2097      * @param vpnuuid Uuid of the VPN whose config must be shown
2098      * @return
2099      */
2100     public List<String> showVpnConfigCLI(Uuid vpnuuid) {
2101         List<String> result = new ArrayList<>();
2102         if (vpnuuid == null) {
2103             System.out.println("");
2104             System.out.println("Displaying VPN config for all VPNs");
2105             System.out.println("To display VPN config for a particular VPN, use the following syntax");
2106             System.out.println(getshowVpnConfigCLIHelp());
2107         }
2108         try {
2109             RpcResult<GetL3VPNOutput> rpcResult = getL3VPN(new GetL3VPNInputBuilder().setId(vpnuuid).build()).get();
2110             if (rpcResult.isSuccessful()) {
2111                 result.add("");
2112                 result.add(String.format(" %-37s %-37s %-7s ", "VPN ID", "Tenant ID", "RD"));
2113                 result.add("");
2114                 result.add(String.format(" %-80s ", "Import-RTs"));
2115                 result.add("");
2116                 result.add(String.format(" %-80s ", "Export-RTs"));
2117                 result.add("");
2118                 result.add(String.format(" %-76s ", "Subnet IDs"));
2119                 result.add("");
2120                 result.add("------------------------------------------------------------------------------------");
2121                 result.add("");
2122                 List<L3vpnInstances> VpnList = rpcResult.getResult().getL3vpnInstances();
2123                 for (L3vpnInstance Vpn : VpnList) {
2124                     String tenantId = Vpn.getTenantId() != null ? Vpn.getTenantId().getValue()
2125                             : "\"                 " + "                  \"";
2126                     result.add(String.format(" %-37s %-37s %-7s ", Vpn.getId().getValue(), tenantId,
2127                             Vpn.getRouteDistinguisher()));
2128                     result.add("");
2129                     result.add(String.format(" %-80s ", Vpn.getImportRT()));
2130                     result.add("");
2131                     result.add(String.format(" %-80s ", Vpn.getExportRT()));
2132                     result.add("");
2133
2134                     Uuid vpnid = Vpn.getId();
2135                     List<Uuid> subnetList = getSubnetsforVpn(vpnid);
2136                     if (!subnetList.isEmpty()) {
2137                         for (Uuid subnetuuid : subnetList) {
2138                             result.add(String.format(" %-76s ", subnetuuid.getValue()));
2139                         }
2140                     } else {
2141                         result.add(String.format(" %-76s ", "\"                                    \""));
2142                     }
2143                     result.add("");
2144                     result.add("----------------------------------------");
2145                     result.add("");
2146                 }
2147             } else {
2148                 String errortag = rpcResult.getErrors().iterator().next().getTag();
2149                 if (errortag == "") {
2150                     System.out.println("");
2151                     System.out.println("No VPN has been configured yet");
2152                 } else if (errortag == "invalid-value") {
2153                     System.out.println("");
2154                     System.out.println("VPN " + vpnuuid.getValue() + " is not present");
2155                 } else {
2156                     System.out.println("error getting VPN info : " + rpcResult.getErrors());
2157                     System.out.println(getshowVpnConfigCLIHelp());
2158                 }
2159             }
2160         } catch (InterruptedException | ExecutionException e) {
2161             LOG.error("error getting VPN info : ", e);
2162             System.out.println("error getting VPN info : " + e.getMessage());
2163         }
2164         return result;
2165     }
2166
2167     private String getshowVpnConfigCLIHelp() {
2168         StringBuilder help = new StringBuilder("Usage:");
2169         help.append("display vpn-config [-vid/--vpnid <id>]");
2170         return help.toString();
2171     }
2172
2173     private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName,
2174                                                       Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2175         SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
2176
2177         LOG.info("publish notification called");
2178
2179         builder.setSubnetId(subnetId);
2180         builder.setSubnetIp(subnetIp);
2181         builder.setVpnName(vpnName);
2182         builder.setExternalVpn(isExternalvpn);
2183         builder.setElanTag(elanTag);
2184
2185         notificationPublishService.putNotification(builder.build());
2186     }
2187
2188     private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName,
2189                                                       Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2190         SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
2191
2192         LOG.info("publish notification called");
2193
2194         builder.setSubnetId(subnetId);
2195         builder.setSubnetIp(subnetIp);
2196         builder.setVpnName(vpnName);
2197         builder.setExternalVpn(isExternalvpn);
2198         builder.setElanTag(elanTag);
2199
2200         notificationPublishService.putNotification(builder.build());
2201     }
2202
2203     private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName,
2204                                                       Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2205         SubnetUpdatedInVpnBuilder builder = new SubnetUpdatedInVpnBuilder();
2206
2207         LOG.info("publish notification called");
2208
2209         builder.setSubnetId(subnetId);
2210         builder.setSubnetIp(subnetIp);
2211         builder.setVpnName(vpnName);
2212         builder.setExternalVpn(isExternalvpn);
2213         builder.setElanTag(elanTag);
2214
2215         notificationPublishService.putNotification(builder.build());
2216     }
2217
2218     private void checkAndPublishRouterAssociatedtoVpnNotification(Uuid routerId, Uuid vpnId) throws
2219             InterruptedException {
2220         RouterAssociatedToVpn routerAssociatedToVpn = new RouterAssociatedToVpnBuilder().setRouterId(routerId)
2221                 .setVpnId(vpnId).build();
2222         LOG.info("publishing notification upon association of router to VPN");
2223         notificationPublishService.putNotification(routerAssociatedToVpn);
2224     }
2225
2226     private void checkAndPublishRouterDisassociatedFromVpnNotification(Uuid routerId, Uuid vpnId) throws
2227             InterruptedException {
2228         RouterDisassociatedFromVpn routerDisassociatedFromVpn = new RouterDisassociatedFromVpnBuilder().setRouterId
2229                 (routerId).setVpnId(vpnId).build();
2230         LOG.info("publishing notification upon disassociation of router from VPN");
2231         notificationPublishService.putNotification(routerDisassociatedFromVpn);
2232     }
2233
2234     protected void dissociatefixedIPFromFloatingIP(String fixedNeutronPortName) {
2235         floatingIpMapListener.dissociatefixedIPFromFloatingIP(fixedNeutronPortName);
2236     }
2237 }