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