SubnetRoute enhancements to VPN Service models
[vpnservice.git] / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / vpnservice / 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.vpnservice.neutronvpn;
9
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.SettableFuture;
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
14 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
17 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
18 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
19 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
20 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets;
21 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargetsBuilder;
22 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
23 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets
24         .VpnTargetBuilder;
25 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetKey;
26 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
27 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
28 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
29 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance
30         .Ipv4FamilyBuilder;
31 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
32 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
33 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.AdjacenciesBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.l3.attributes.Routes;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInstances;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockManagerService;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.*;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.createl3vpn.input.L3vpn;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.getl3vpn.output.L3vpnInstances;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.getl3vpn.output
59         .L3vpnInstancesBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.Subnetmap;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.SubnetmapBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMap;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMapBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMapKey;
66 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
67 import org.opendaylight.yangtools.concepts.ListenerRegistration;
68 import org.opendaylight.yangtools.yang.common.RpcError;
69 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
70 import org.opendaylight.yangtools.yang.common.RpcResult;
71 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
72 import java.util.EventListener;
73 import org.slf4j.Logger;
74 import org.slf4j.LoggerFactory;
75 import java.util.ArrayList;
76 import java.util.Arrays;
77 import java.util.List;
78 import java.util.concurrent.ExecutionException;
79 import java.util.concurrent.Future;
80
81 public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , EventListener{
82
83     private static final Logger logger = LoggerFactory.getLogger(NeutronvpnManager.class);
84     private final DataBroker broker;
85     private LockManagerService lockManager;
86     IMdsalApiManager mdsalUtil;
87     private NotificationPublishService notificationPublishService;
88     private NotificationService notificationService;
89     Boolean isExternalVpn;
90
91     /**
92      * @param db           - dataBroker reference
93      * @param mdsalManager - MDSAL Util API access
94      */
95     public NeutronvpnManager(final DataBroker db, IMdsalApiManager mdsalManager,NotificationPublishService notiPublishService,
96                              NotificationService notiService) {
97         broker = db;
98         mdsalUtil = mdsalManager;
99         notificationPublishService = notiPublishService;
100         notificationService = notiService;
101     }
102
103     public void setLockManager(LockManagerService lockManager) {
104         this.lockManager = lockManager;
105     }
106
107     @Override
108     public void close() throws Exception {
109         logger.info("Neutron VPN Manager Closed");
110     }
111
112     protected Subnetmap updateSubnetNode(Uuid subnetId, String subnetIp, Uuid tenantId, Uuid networkId, Uuid routerId,
113                                          Uuid vpnId, Uuid portId) {
114         Subnetmap subnetmap = null;
115         SubnetmapBuilder builder = null;
116         boolean isLockAcquired = false;
117         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).
118                 child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
119         try {
120             Optional<Subnetmap> sn = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, id);
121             logger.debug("updating Subnet :read: ");
122             if (sn.isPresent()) {
123                 builder = new SubnetmapBuilder(sn.get());
124                 logger.debug("updating Subnet :existing: ");
125             } else {
126                 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
127                 logger.debug("updating Subnet :new: ");
128             }
129
130             if (subnetIp != null) {
131                 builder.setSubnetIp(subnetIp);
132             }
133             if (routerId != null) {
134                 builder.setRouterId(routerId);
135             }
136             if (networkId != null) {
137                 builder.setNetworkId(networkId);
138             }
139             if (vpnId != null) {
140                 builder.setVpnId(vpnId);
141             }
142             if (tenantId != null) {
143                 builder.setTenantId(tenantId);
144             }
145
146             if (portId != null) {
147                 List<Uuid> portList = builder.getPortList();
148                 if (portList == null) {
149                     portList = new ArrayList<Uuid>();
150                 }
151                 portList.add(portId);
152                 builder.setPortList(portList);
153             }
154
155             subnetmap = builder.build();
156             isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
157             logger.debug("Creating/Updating subnetMap node: {} ", subnetId.getValue());
158             MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
159         } catch (Exception e) {
160             logger.error("Updation of subnetMap failed for node: {}", subnetId.getValue());
161         } finally {
162             if (isLockAcquired) {
163                 NeutronvpnUtils.unlock(lockManager, subnetId.getValue());
164             }
165         }
166         return subnetmap;
167     }
168
169     protected Subnetmap removeFromSubnetNode(Uuid subnetId, Uuid networkId, Uuid routerId, Uuid vpnId, Uuid portId) {
170         Subnetmap subnetmap = null;
171         boolean isLockAcquired = false;
172         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).
173                 child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
174         try {
175             Optional<Subnetmap> sn = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, id);
176             if (sn.isPresent()) {
177                 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
178                 if (routerId != null) {
179                     builder.setRouterId(null);
180                 }
181                 if (networkId != null) {
182                     builder.setNetworkId(null);
183                 }
184                 if (vpnId != null) {
185                     builder.setVpnId(null);
186                 }
187                 if (portId != null && builder.getPortList() != null) {
188                     List<Uuid> portList = builder.getPortList();
189                     portList.remove(portId);
190                     builder.setPortList(portList);
191                 }
192
193                 subnetmap = builder.build();
194                 isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
195                 logger.debug("Removing from existing subnetmap node: {} ", subnetId.getValue());
196                 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
197             } else {
198                 logger.warn("removing from non-existing subnetmap node: {} ", subnetId.getValue());
199             }
200         } catch (Exception e) {
201             logger.error("Removal from subnetmap failed for node: {}", subnetId.getValue());
202         } finally {
203             if (isLockAcquired) {
204                 NeutronvpnUtils.unlock(lockManager, subnetId.getValue());
205             }
206         }
207         return subnetmap;
208     }
209
210     protected void deleteSubnetMapNode(Uuid subnetId) {
211         boolean isLockAcquired = false;
212         InstanceIdentifier<Subnetmap> subnetMapIdentifier = InstanceIdentifier.builder(Subnetmaps.class)
213                 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
214         logger.debug("removing subnetMap node: {} ", subnetId.getValue());
215         try {
216             isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
217             MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, subnetMapIdentifier);
218         } catch (Exception e) {
219             logger.error("Delete subnetMap node failed for subnet : {} ", subnetId.getValue());
220         } finally {
221             if (isLockAcquired) {
222                 NeutronvpnUtils.unlock(lockManager, subnetId.getValue());
223             }
224         }
225     }
226
227     private void updateVpnInstanceNode(String vpnName, List<String> rd, List<String> irt, List<String> ert) {
228
229         VpnInstanceBuilder builder = null;
230         List<VpnTarget> vpnTargetList = new ArrayList<VpnTarget>();
231         boolean isLockAcquired = false;
232         InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class).
233                 child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
234         try {
235             Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
236                     vpnIdentifier);
237             logger.debug("Creating/Updating a new vpn-instance node: {} ", vpnName);
238             if (optionalVpn.isPresent()) {
239                 builder = new VpnInstanceBuilder(optionalVpn.get());
240                 logger.debug("updating existing vpninstance node");
241             } else {
242                 builder = new VpnInstanceBuilder().setKey(new VpnInstanceKey(vpnName)).setVpnInstanceName(vpnName);
243             }
244             if (irt != null && !irt.isEmpty()) {
245                 if (ert != null && !ert.isEmpty()) {
246                     List<String> commonRT = new ArrayList<String>(irt);
247                     commonRT.retainAll(ert);
248
249                     for (String common : commonRT) {
250                         irt.remove(common);
251                         ert.remove(common);
252                         VpnTarget vpnTarget = new VpnTargetBuilder().setKey(new VpnTargetKey(common)).setVrfRTValue
253                                 (common).setVrfRTType(VpnTarget.VrfRTType.Both).build();
254                         vpnTargetList.add(vpnTarget);
255                     }
256                 }
257                 for (String importRT : irt) {
258                     VpnTarget vpnTarget = new VpnTargetBuilder().setKey(new VpnTargetKey(importRT)).setVrfRTValue
259                             (importRT).setVrfRTType(VpnTarget.VrfRTType.ImportExtcommunity).build();
260                     vpnTargetList.add(vpnTarget);
261                 }
262             }
263
264             if (ert != null && !ert.isEmpty()) {
265                 for (String exportRT : ert) {
266                     VpnTarget vpnTarget = new VpnTargetBuilder().setKey(new VpnTargetKey(exportRT)).setVrfRTValue
267                             (exportRT).setVrfRTType(VpnTarget.VrfRTType.ExportExtcommunity).build();
268                     vpnTargetList.add(vpnTarget);
269                 }
270             }
271
272             VpnTargets vpnTargets = new VpnTargetsBuilder().setVpnTarget(vpnTargetList).build();
273
274             Ipv4FamilyBuilder ipv4vpnBuilder = new Ipv4FamilyBuilder().setVpnTargets(vpnTargets);
275
276             if (rd != null && !rd.isEmpty()) {
277                 ipv4vpnBuilder.setRouteDistinguisher(rd.get(0));
278             }
279
280             VpnInstance newVpn = builder.setIpv4Family(ipv4vpnBuilder.build()).build();
281             isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnName);
282             logger.debug("Creating/Updating vpn-instance for {} ", vpnName);
283             MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier, newVpn);
284         } catch (Exception e) {
285             logger.error("Update VPN Instance node failed for node: {} {} {} {}", vpnName, rd, irt, ert);
286         } finally {
287             if (isLockAcquired) {
288                 NeutronvpnUtils.unlock(lockManager, vpnName);
289             }
290         }
291     }
292
293     private void deleteVpnMapsNode(Uuid vpnid) {
294         boolean isLockAcquired = false;
295         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
296                 .child(VpnMap.class, new VpnMapKey(vpnid)).build();
297         logger.debug("removing vpnMaps node: {} ", vpnid.getValue());
298         try {
299             isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnid.getValue());
300             MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
301         } catch (Exception e) {
302             logger.error("Delete vpnMaps node failed for vpn : {} ", vpnid.getValue());
303         } finally {
304             if (isLockAcquired) {
305                 NeutronvpnUtils.unlock(lockManager, vpnid.getValue());
306             }
307         }
308     }
309
310     private void updateVpnMaps(Uuid vpnId, String name, Uuid router, Uuid tenantId, List<Uuid> networks) {
311         VpnMapBuilder builder;
312         boolean isLockAcquired = false;
313         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
314                 .child(VpnMap.class, new VpnMapKey(vpnId)).build();
315         try {
316             Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
317                     vpnMapIdentifier);
318             if (optionalVpnMap.isPresent()) {
319                 builder = new VpnMapBuilder(optionalVpnMap.get());
320             } else {
321                 builder = new VpnMapBuilder().setKey(new VpnMapKey(vpnId)).setVpnId(vpnId);
322             }
323
324             if (name != null) {
325                 builder.setName(name);
326             }
327             if (tenantId != null) {
328                 builder.setTenantId(tenantId);
329             }
330             if (router != null) {
331                 builder.setRouterId(router);
332             }
333             if (networks != null) {
334                 List<Uuid> nwList = builder.getNetworkIds();
335                 if (nwList == null) {
336                     nwList = new ArrayList<Uuid>();
337                 }
338                 nwList.addAll(networks);
339                 builder.setNetworkIds(nwList);
340             }
341
342             isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnId.getValue());
343             logger.debug("Creating/Updating vpnMaps node: {} ", vpnId.getValue());
344             MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier, builder.build());
345             logger.debug("VPNMaps DS updated for VPN {} ", vpnId.getValue());
346         } catch (Exception e) {
347             logger.error("UpdateVpnMaps failed for node: {} ", vpnId.getValue());
348         } finally {
349             if (isLockAcquired) {
350                 NeutronvpnUtils.unlock(lockManager, vpnId.getValue());
351             }
352         }
353     }
354
355     private void clearFromVpnMaps(Uuid vpnId, Uuid routerId, List<Uuid> networkIds) {
356         boolean isLockAcquired = false;
357         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
358                 .child(VpnMap.class, new VpnMapKey(vpnId)).build();
359         Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
360                 vpnMapIdentifier);
361         if (optionalVpnMap.isPresent()) {
362             VpnMap vpnMap = optionalVpnMap.get();
363             VpnMapBuilder vpnMapBuilder = new VpnMapBuilder(vpnMap);
364             if (routerId != null) {
365                 if (vpnMap.getNetworkIds() == null && routerId.equals(vpnMap.getVpnId())) {
366                     try {
367                         // remove entire node in case of internal VPN
368                         isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnId.getValue());
369                         logger.debug("removing vpnMaps node: {} ", vpnId);
370                         MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
371                     } catch (Exception e) {
372                         logger.error("Deletion of vpnMaps node failed for vpn {}", vpnId.getValue());
373                     } finally {
374                         if (isLockAcquired) {
375                             NeutronvpnUtils.unlock(lockManager, vpnId.getValue());
376                         }
377                     }
378                     return;
379                 }
380                 vpnMapBuilder.setRouterId(null);
381             }
382             if (networkIds != null) {
383                 List<Uuid> vpnNw = vpnMap.getNetworkIds();
384                 for (Uuid nw : networkIds) {
385                     vpnNw.remove(nw);
386                 }
387                 if (vpnNw.isEmpty()) {
388                     logger.debug("setting networks null in vpnMaps node: {} ", vpnId.getValue());
389                     vpnMapBuilder.setNetworkIds(null);
390                 } else {
391                     vpnMapBuilder.setNetworkIds(vpnNw);
392                 }
393             }
394
395             try {
396                 isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnId.getValue());
397                 logger.debug("clearing from vpnMaps node: {} ", vpnId.getValue());
398                 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier, vpnMapBuilder.build
399                         ());
400             } catch (Exception e) {
401                 logger.error("Clearing from vpnMaps node failed for vpn {}", vpnId.getValue());
402             } finally {
403                 if (isLockAcquired) {
404                     NeutronvpnUtils.unlock(lockManager, vpnId.getValue());
405                 }
406             }
407         } else {
408             logger.error("VPN : {} not found", vpnId.getValue());
409         }
410         logger.debug("Clear from VPNMaps DS successful for VPN {} ", vpnId.getValue());
411     }
412
413     private void deleteVpnInstance(Uuid vpnId) {
414         boolean isLockAcquired = false;
415         InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class).
416                 child(VpnInstance.class, new VpnInstanceKey(vpnId.getValue())).build();
417         try {
418             isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnId.getValue());
419             logger.debug("Deleting vpnInstance {}", vpnId.getValue());
420             MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
421         } catch (Exception e) {
422             logger.error("Deletion of VPNInstance node failed for VPN {}", vpnId.getValue());
423         } finally {
424             if (isLockAcquired) {
425                 NeutronvpnUtils.unlock(lockManager, vpnId.getValue());
426             }
427         }
428     }
429
430     protected void createVpnInterface(Uuid vpnId, Port port) {
431         boolean isLockAcquired = false;
432         if (vpnId == null || port == null) {
433             return;
434         }
435         String infName = port.getUuid().getValue();
436         List<Adjacency> adjList = new ArrayList<Adjacency>();
437         InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
438
439         // find router associated to vpn
440         Uuid routerId = NeutronvpnUtils.getRouterforVpn(broker, vpnId);
441         Router rtr = null;
442         if (routerId != null) {
443             rtr = NeutronvpnUtils.getNeutronRouter(broker, routerId);
444         }
445         // find all subnets to which this port is associated
446         List<FixedIps> ips = port.getFixedIps();
447         // create adjacency list
448         for (FixedIps ip : ips) {
449             // create vm adjacency
450             StringBuilder IpPrefixBuild = new StringBuilder(ip.getIpAddress().getIpv4Address().getValue());
451             String IpPrefix = IpPrefixBuild.append("/32").toString();
452             Adjacency vmAdj = new AdjacencyBuilder().setKey(new AdjacencyKey(IpPrefix)).setIpAddress(IpPrefix)
453                     .setMacAddress(port.getMacAddress()).build();
454             adjList.add(vmAdj);
455             // create extra route adjacency
456             if (rtr != null && rtr.getRoutes() != null) {
457                 List<Routes> routeList = rtr.getRoutes();
458                 List<Adjacency> erAdjList = addAdjacencyforExtraRoute(routeList, false, infName);
459                 if (erAdjList != null && !erAdjList.isEmpty()) {
460                     adjList.addAll(erAdjList);
461                 }
462             }
463         }
464         // create vpn-interface on this neutron port
465         Adjacencies adjs = new AdjacenciesBuilder().setAdjacency(adjList).build();
466         VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName)).
467                 setName(infName).setVpnInstanceName(vpnId.getValue()).addAugmentation(Adjacencies.class, adjs);
468         VpnInterface vpnIf = vpnb.build();
469
470         try {
471             isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
472             logger.debug("Creating vpn interface {}", vpnIf);
473             MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
474         } catch (Exception ex) {
475             logger.error("Creation of vpninterface {} failed due to {}", infName, ex);
476         } finally {
477             if (isLockAcquired) {
478                 NeutronvpnUtils.unlock(lockManager, infName);
479             }
480         }
481     }
482
483     protected void deleteVpnInterface(Port port) {
484
485         if (port != null) {
486             boolean isLockAcquired = false;
487             String infName = port.getUuid().getValue();
488             InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
489
490             try {
491                 isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
492                 logger.debug("Deleting vpn interface {}", infName);
493                 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
494             } catch (Exception ex) {
495                 logger.error("Deletion of vpninterface {} failed due to {}", infName, ex);
496             } finally {
497                 if (isLockAcquired) {
498                     NeutronvpnUtils.unlock(lockManager, infName);
499                 }
500             }
501         }
502     }
503
504     protected void updateVpnInterface(Uuid vpnId, Port port) {
505         if (vpnId == null || port == null) {
506             return;
507         }
508         boolean isLockAcquired = false;
509         String infName = port.getUuid().getValue();
510         InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
511         try {
512             Optional<VpnInterface> optionalVpnInterface = NeutronvpnUtils.read(broker, LogicalDatastoreType
513                     .CONFIGURATION, vpnIfIdentifier);
514             if (optionalVpnInterface.isPresent()) {
515                 VpnInterfaceBuilder vpnIfBuilder = new VpnInterfaceBuilder(optionalVpnInterface.get());
516                 VpnInterface vpnIf = vpnIfBuilder.setVpnInstanceName(vpnId.getValue()).build();
517                 isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
518                 logger.debug("Updating vpn interface {}", vpnIf);
519                 MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
520             } else {
521                 logger.error("VPN Interface {} not found", infName);
522             }
523         } catch (Exception ex) {
524             logger.error("Updation of vpninterface {} failed due to {}", infName, ex);
525         } finally {
526             if (isLockAcquired) {
527                 NeutronvpnUtils.unlock(lockManager, infName);
528             }
529         }
530     }
531
532     public void createL3Vpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt, List<String> ert,
533                             Uuid router, List<Uuid> networks) {
534
535         // Update VPN Instance node
536         updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
537
538         // Update local vpn-subnet DS
539         updateVpnMaps(vpn, name, router, tenant, networks);
540
541         if (router != null) {
542             associateRouterToVpn(vpn, router);
543         }
544         if (networks != null) {
545             associateNetworksToVpn(vpn, networks);
546         }
547     }
548
549     @Override
550     public Future<RpcResult<CreateL3VPNOutput>> createL3VPN(CreateL3VPNInput input) {
551
552         CreateL3VPNOutputBuilder opBuilder = new CreateL3VPNOutputBuilder();
553         SettableFuture<RpcResult<CreateL3VPNOutput>> result = SettableFuture.create();
554         List<RpcError> errorList = new ArrayList<RpcError>();
555         int failurecount = 0;
556         int warningcount = 0;
557
558         List<L3vpn> vpns = input.getL3vpn();
559         for (L3vpn vpn : vpns) {
560             RpcError error = null;
561             String msg;
562             if (vpn.getRouteDistinguisher() == null || vpn.getImportRT() == null || vpn.getExportRT() == null) {
563                 msg = String.format("Creation of L3VPN failed for VPN %s due to absence of RD/iRT/eRT input",
564                         vpn.getId().getValue());
565                 logger.warn(msg);
566                 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
567                 errorList.add(error);
568                 warningcount++;
569                 continue;
570             }
571             if (vpn.getRouteDistinguisher().size() > 1) {
572                 msg = String.format("Creation of L3VPN failed for VPN %s due to multiple RD input %s",
573                         vpn.getId().getValue(), vpn.getRouteDistinguisher());
574                 logger.warn(msg);
575                 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
576                 errorList.add(error);
577                 warningcount++;
578                 continue;
579             }
580             if (vpn.getRouterId() != null) {
581                 if (NeutronvpnUtils.getNeutronRouter(broker, vpn.getRouterId()) == null) {
582                     msg = String.format("Creation of L3VPN failed for VPN %s due to router not found %s",
583                             vpn.getId().getValue(), vpn.getRouterId().getValue());
584                     logger.warn(msg);
585                     error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
586                     errorList.add(error);
587                     warningcount++;
588                     continue;
589                 }
590                 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, vpn.getRouterId(), true);
591                 if (vpnId != null) {
592                     msg = String.format("Creation of L3VPN failed for VPN %s due to router %s already associated to " +
593                             "another VPN %s", vpn.getId().getValue(), vpn.getRouterId().getValue(), vpnId.getValue());
594                     logger.warn(msg);
595                     error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
596                     errorList.add(error);
597                     warningcount++;
598                     continue;
599                 }
600             }
601             if (vpn.getNetworkIds() != null) {
602                 for (Uuid nw : vpn.getNetworkIds()) {
603                     Network network = NeutronvpnUtils.getNeutronNetwork(broker, nw);
604                     Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(broker, nw);
605                     if (network == null) {
606                         msg = String.format("Creation of L3VPN failed for VPN %s due to network not found %s",
607                                 vpn.getId().getValue(), nw.getValue());
608                         logger.warn(msg);
609                         error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
610                         errorList.add(error);
611                         warningcount++;
612                     } else if (vpnId != null) {
613                         msg = String.format("Creation of L3VPN failed for VPN %s due to network %s already associated" +
614                                 " to another VPN %s", vpn.getId().getValue(), nw.getValue(), vpnId.getValue());
615                         logger.warn(msg);
616                         error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
617                         errorList.add(error);
618                         warningcount++;
619                     }
620                 }
621                 if (error != null) {
622                     continue;
623                 }
624             }
625             try {
626                 createL3Vpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), vpn.getRouteDistinguisher(),
627                         vpn.getImportRT(), vpn.getExportRT(), vpn.getRouterId(), vpn.getNetworkIds());
628             } catch (Exception ex) {
629                 msg = String.format("Creation of L3VPN failed for VPN %s", vpn.getId().getValue());
630                 logger.error(msg, ex);
631                 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
632                 errorList.add(error);
633                 failurecount++;
634             }
635         }
636         // if at least one succeeds; result is success
637         // if none succeeds; result is failure
638         if (failurecount + warningcount == vpns.size()) {
639             result.set(RpcResultBuilder.<CreateL3VPNOutput>failed().withRpcErrors(errorList).build());
640         } else {
641             List<String> errorResponseList = new ArrayList<>();
642             if (!errorList.isEmpty()) {
643                 for (RpcError rpcError : errorList) {
644                     String errorResponse = String.format("ErrorType: " + rpcError.getErrorType() + ", " + "ErrorTag: " +
645                             rpcError.getTag() + ", " + "ErrorMessage: " + rpcError.getMessage());
646                     errorResponseList.add(errorResponse);
647                 }
648             } else {
649                 errorResponseList.add("Operation successful with no errors");
650             }
651             opBuilder.setResponse(errorResponseList);
652             result.set(RpcResultBuilder.<CreateL3VPNOutput>success().withResult(opBuilder.build()).build());
653         }
654         return result;
655     }
656
657     @Override
658     public Future<RpcResult<GetL3VPNOutput>> getL3VPN(GetL3VPNInput input) {
659
660         GetL3VPNOutputBuilder opBuilder = new GetL3VPNOutputBuilder();
661         SettableFuture<RpcResult<GetL3VPNOutput>> result = SettableFuture.create();
662         Uuid inputVpnId = input.getId();
663         List<VpnInstance> vpns = new ArrayList<VpnInstance>();
664
665         try {
666             if (inputVpnId == null) {
667                 // get all vpns
668                 InstanceIdentifier<VpnInstances> vpnsIdentifier =
669                         InstanceIdentifier.builder(VpnInstances.class).build();
670                 Optional<VpnInstances> optionalVpns = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
671                         vpnsIdentifier);
672                 if (optionalVpns.isPresent() && optionalVpns.get().getVpnInstance() != null) {
673                     for (VpnInstance vpn : optionalVpns.get().getVpnInstance()) {
674                         // eliminating internal VPNs from getL3VPN output
675                         if (vpn.getIpv4Family().getRouteDistinguisher() != null) {
676                             vpns.add(vpn);
677                         }
678                     }
679                 } else {
680                     // No VPN present
681                     result.set(RpcResultBuilder.<GetL3VPNOutput>failed()
682                             .withWarning(ErrorType.PROTOCOL, "", "No VPN is present").build());
683                     return result;
684                 }
685             } else {
686                 String name = inputVpnId.getValue();
687                 InstanceIdentifier<VpnInstance> vpnIdentifier =
688                         InstanceIdentifier.builder(VpnInstances.class)
689                                 .child(VpnInstance.class, new VpnInstanceKey(name)).build();
690                 // read VpnInstance Info
691                 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
692                         vpnIdentifier);
693                 if (optionalVpn.isPresent()) {
694                     vpns.add(optionalVpn.get());
695                 } else {
696                     String message = String.format("GetL3VPN failed because VPN %s is not present", name);
697                     logger.error(message);
698                     result.set(RpcResultBuilder.<GetL3VPNOutput>failed()
699                             .withWarning(ErrorType.PROTOCOL, "invalid-value", message).build());
700                 }
701             }
702             List<L3vpnInstances> l3vpnList = new ArrayList<L3vpnInstances>();
703             for (VpnInstance vpnInstance : vpns) {
704                 Uuid vpnId = new Uuid(vpnInstance.getVpnInstanceName());
705                 // create VpnMaps id
706                 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap
707                         .class, new VpnMapKey(vpnId)).build();
708                 L3vpnInstancesBuilder l3vpn = new L3vpnInstancesBuilder();
709
710                 List<String> rd = Arrays.asList(vpnInstance.getIpv4Family().getRouteDistinguisher().split(","));
711                 List<VpnTarget> vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
712
713                 List<String> ertList = new ArrayList<String>();
714                 List<String> irtList = new ArrayList<String>();
715
716                 for (VpnTarget vpnTarget : vpnTargetList) {
717                     if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
718                         ertList.add(vpnTarget.getVrfRTValue());
719                     }
720                     if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ImportExtcommunity) {
721                         irtList.add(vpnTarget.getVrfRTValue());
722                     }
723                     if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.Both) {
724                         ertList.add(vpnTarget.getVrfRTValue());
725                         irtList.add(vpnTarget.getVrfRTValue());
726                     }
727                 }
728
729                 l3vpn.setId(vpnId).setRouteDistinguisher(rd).setImportRT(irtList).setExportRT(ertList);
730                 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
731                         vpnMapIdentifier);
732                 if (optionalVpnMap.isPresent()) {
733                     VpnMap vpnMap = optionalVpnMap.get();
734                     l3vpn.setRouterId(vpnMap.getRouterId()).setNetworkIds(vpnMap.getNetworkIds())
735                             .setTenantId(vpnMap.getTenantId()).setName(vpnMap.getName());
736                 }
737                 l3vpnList.add(l3vpn.build());
738             }
739
740             opBuilder.setL3vpnInstances(l3vpnList);
741             result.set(RpcResultBuilder.<GetL3VPNOutput>success().withResult(opBuilder.build()).build());
742
743         } catch (Exception ex) {
744             String message = String.format("GetL3VPN failed due to %s", ex.getMessage());
745             logger.error(message, ex);
746             result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withError(ErrorType.APPLICATION, message).build());
747         }
748         return result;
749     }
750
751     @Override
752     public Future<RpcResult<DeleteL3VPNOutput>> deleteL3VPN(DeleteL3VPNInput input) {
753
754         DeleteL3VPNOutputBuilder opBuilder = new DeleteL3VPNOutputBuilder();
755         SettableFuture<RpcResult<DeleteL3VPNOutput>> result = SettableFuture.create();
756         List<RpcError> errorList = new ArrayList<RpcError>();
757
758         int failurecount = 0;
759         int warningcount = 0;
760         List<Uuid> vpns = input.getId();
761         for (Uuid vpn : vpns) {
762             RpcError error;
763             String msg;
764             try {
765                 InstanceIdentifier<VpnInstance> vpnIdentifier =
766                         InstanceIdentifier.builder(VpnInstances.class)
767                                 .child(VpnInstance.class, new VpnInstanceKey(vpn.getValue())).build();
768                 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
769                         vpnIdentifier);
770                 if (optionalVpn.isPresent()) {
771                     removeL3Vpn(vpn);
772                 } else {
773                     msg = String.format("VPN with vpnid: %s does not exist", vpn.getValue());
774                     logger.warn(msg);
775                     error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-value", msg);
776                     errorList.add(error);
777                     warningcount++;
778                 }
779             } catch (Exception ex) {
780                 msg = String.format("Deletion of L3VPN failed when deleting for uuid %s", vpn.getValue());
781                 logger.error(msg, ex);
782                 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
783                 errorList.add(error);
784                 failurecount++;
785             }
786         }
787         // if at least one succeeds; result is success
788         // if none succeeds; result is failure
789         if (failurecount + warningcount == vpns.size()) {
790             result.set(RpcResultBuilder.<DeleteL3VPNOutput>failed().withRpcErrors(errorList).build());
791         } else {
792             List<String> errorResponseList = new ArrayList<>();
793             if (!errorList.isEmpty()) {
794                 for (RpcError rpcError : errorList) {
795                     String errorResponse = String.format("ErrorType: " + rpcError.getErrorType() + ", " + "ErrorTag: " +
796                             rpcError.getTag() + ", " + "ErrorMessage: " + rpcError.getMessage());
797                     errorResponseList.add(errorResponse);
798                 }
799             } else {
800                 errorResponseList.add("Operation successful with no errors");
801             }
802             opBuilder.setResponse(errorResponseList);
803             result.set(RpcResultBuilder.<DeleteL3VPNOutput>success().withResult(opBuilder.build()).build());
804         }
805         return result;
806     }
807
808     protected void addSubnetToVpn(Uuid vpnId, Uuid subnet) {
809         logger.debug("Adding subnet {} to vpn {}", subnet.getValue(), vpnId.getValue());
810         Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId, null);
811         boolean isLockAcquired = false;
812         String lockName = vpnId.getValue() + subnet.getValue();
813         String elanInstanceName = sn.getNetworkId().getValue();
814         InstanceIdentifier<ElanInstance>elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
815         Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
816         long elanTag = elanInstance.get().getElanTag();
817         if(vpnId.equals(NeutronvpnUtils.getVpnMap(broker,vpnId).getRouterId())){isExternalVpn = false;}
818         else {isExternalVpn = true;}
819         try {
820             isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
821             checkAndPublishSubnetAddNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn, elanTag);
822             logger.debug("Subnet added to Vpn notification sent");
823         }catch (Exception e){
824             logger.error("Subnet added to Vpn notification failed",e);
825         }finally {
826             if (isLockAcquired) {
827                 NeutronvpnUtils.unlock(lockManager, lockName);
828             }
829         }
830         // Check if there are ports on this subnet and add corresponding vpn-interfaces
831         List<Uuid> portList = sn.getPortList();
832         if (portList != null) {
833             for (Uuid port : sn.getPortList()) {
834                 logger.debug("adding vpn-interface for port {}", port.getValue());
835                 createVpnInterface(vpnId, NeutronvpnUtils.getNeutronPort(broker, port));
836             }
837         }
838     }
839
840     protected void updateVpnForSubnet(Uuid vpnId, Uuid subnet, boolean isBeingAssociated) {
841         logger.debug("Updating VPN {} for subnet {}", vpnId.getValue(), subnet.getValue());
842         Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId, null);
843         boolean isLockAcquired = false;
844         String lockName = vpnId.getValue() + subnet.getValue();
845         String elanInstanceName = sn.getNetworkId().getValue();
846         InstanceIdentifier<ElanInstance>elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
847         Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
848         long elanTag = elanInstance.get().getElanTag();
849         try {
850             isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
851             checkAndPublishSubnetUpdNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isBeingAssociated, elanTag);
852             logger.debug("Subnet updated in Vpn notification sent");
853         }catch (Exception e){
854             logger.error("Subnet updated in Vpn notification failed",e);
855         }finally {
856             if (isLockAcquired) {
857                 NeutronvpnUtils.unlock(lockManager, lockName);
858             }
859         }
860         // Check for ports on this subnet and update association of corresponding vpn-interfaces to external vpn
861         List<Uuid> portList = sn.getPortList();
862         if (portList != null) {
863             for (Uuid port : sn.getPortList()) {
864                 logger.debug("Updating vpn-interface for port {}", port.getValue());
865                 updateVpnInterface(vpnId, NeutronvpnUtils.getNeutronPort(broker, port));
866             }
867         }
868     }
869
870     protected List<Adjacency> addAdjacencyforExtraRoute(List<Routes> routeList, boolean rtrUp, String vpnifname) {
871         List<Adjacency> adjList = new ArrayList<Adjacency>();
872         for (Routes route : routeList) {
873             if (route != null && route.getNexthop() != null && route.getDestination() != null) {
874                 boolean isLockAcquired = false;
875                 String nextHop = String.valueOf(route.getNexthop().getValue());
876                 String destination = String.valueOf(route.getDestination().getValue());
877
878                 String infName = NeutronvpnUtils.getNeutronPortNamefromPortFixedIp(broker, nextHop);
879                 logger.trace("Adding extra route with nexthop {}, destination {}, infName {}", nextHop,
880                         destination, infName);
881                 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIp(nextHop).setKey
882                         (new AdjacencyKey(destination)).build();
883                 if (rtrUp == false) {
884                     if (infName.equals(vpnifname)) {
885                         adjList.add(erAdj);
886                     }
887                     continue;
888                 }
889                 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
890                         child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
891                 try {
892                     Optional<VpnInterface> optionalVpnInterface = NeutronvpnUtils.read(broker, LogicalDatastoreType
893                             .CONFIGURATION, vpnIfIdentifier);
894                     if (optionalVpnInterface.isPresent()) {
895                         Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(erAdj)).build();
896                         VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
897                                 .addAugmentation(Adjacencies.class, erAdjs).build();
898                         isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
899                         logger.debug("Adding extra route {}", route);
900                         MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
901                     } else {
902                         logger.error("VM adjacency for interface {} not present ; cannot add extra route adjacency",
903                                 infName);
904                     }
905                 } catch (Exception e) {
906                     logger.error("exception in adding extra route: {}" + e);
907                 } finally {
908                     if (isLockAcquired) {
909                         NeutronvpnUtils.unlock(lockManager, infName);
910                     }
911                 }
912             } else {
913                 logger.error("Incorrect input received for extra route. {}", route);
914             }
915         }
916         return adjList;
917     }
918
919     protected void removeAdjacencyforExtraRoute(List<Routes> routeList) {
920         for (Routes route : routeList) {
921             if (route != null && route.getNexthop() != null && route.getDestination() != null) {
922                 boolean isLockAcquired = false;
923                 String nextHop = String.valueOf(route.getNexthop().getValue());
924                 String destination = String.valueOf(route.getDestination().getValue());
925
926                 String infName = NeutronvpnUtils.getNeutronPortNamefromPortFixedIp(broker, nextHop);
927                 logger.trace("Removing extra route with nexthop {}, destination {}, infName {}", nextHop,
928                         destination, infName);
929                 InstanceIdentifier<Adjacency> adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
930                         child(VpnInterface.class, new VpnInterfaceKey(infName)).augmentation(Adjacencies.class)
931                         .child(Adjacency.class, new AdjacencyKey(destination)).build();
932                 try {
933                     isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
934                     MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
935                     logger.trace("extra route {} deleted successfully", route);
936                 } catch (Exception e) {
937                     logger.error("exception in deleting extra route: {}" + e);
938                 } finally {
939                     if (isLockAcquired) {
940                         NeutronvpnUtils.unlock(lockManager, infName);
941                     }
942                 }
943             } else {
944                 logger.error("Incorrect input received for extra route. {}", route);
945             }
946         }
947     }
948
949     protected void removeL3Vpn(Uuid id) {
950         // read VPNMaps
951         VpnMap vpnMap = NeutronvpnUtils.getVpnMap(broker, id);
952         Uuid router = vpnMap.getRouterId();
953         // dissociate router
954         if (router != null) {
955             dissociateRouterFromVpn(id, router);
956         }
957         // dissociate networks
958         if (!id.equals(router)) {
959             dissociateNetworksFromVpn(id, vpnMap.getNetworkIds());
960         }
961         // remove entire vpnMaps node
962         deleteVpnMapsNode(id);
963
964         // remove vpn-instance
965         deleteVpnInstance(id);
966     }
967
968     protected void removeSubnetFromVpn(Uuid vpnId, Uuid subnet) {
969         logger.debug("Removing subnet {} from vpn {}", subnet.getValue(), vpnId.getValue());
970         Subnetmap sn = NeutronvpnUtils.getSubnetmap(broker, subnet);
971         boolean isLockAcquired = false;
972         String lockName = vpnId.getValue() + subnet.getValue();
973         String elanInstanceName = sn.getNetworkId().getValue();
974         InstanceIdentifier<ElanInstance>elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
975         Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
976         long elanTag = elanInstance.get().getElanTag();
977         if(vpnId.equals(NeutronvpnUtils.getVpnMap(broker,vpnId).getRouterId())){isExternalVpn = false;}
978         else {isExternalVpn = true;}
979         try {
980             isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
981             checkAndPublishSubnetDelNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn, elanTag);
982             logger.debug("Subnet removed from Vpn notification sent");
983         }catch (Exception e){
984             logger.error("Subnet removed from Vpn notification failed",e);
985         }finally {
986             if (isLockAcquired) {
987                 NeutronvpnUtils.unlock(lockManager, lockName);
988             }
989         }
990         if (sn != null) {
991             // Check if there are ports on this subnet; remove corresponding vpn-interfaces
992             List<Uuid> portList = sn.getPortList();
993             if (portList != null) {
994                 for (Uuid port : sn.getPortList()) {
995                     logger.debug("removing vpn-interface for port {}", port.getValue());
996                     deleteVpnInterface(NeutronvpnUtils.getNeutronPort(broker, port));
997                 }
998             }
999             // update subnet-vpn association
1000             removeFromSubnetNode(subnet, null, null, vpnId, null);
1001         } else {
1002             logger.warn("Subnetmap for subnet {} not found", subnet.getValue());
1003         }
1004     }
1005
1006     protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
1007         updateVpnMaps(vpnId, null, routerId, null, null);
1008         List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId);
1009         if (!vpnId.equals(routerId)) {
1010             logger.debug("Updating association of subnets to external vpn {}", vpnId.getValue());
1011             if (routerSubnets != null) {
1012                 for (Uuid subnetId : routerSubnets) {
1013                     updateVpnForSubnet(vpnId, subnetId,true);
1014                 }
1015             }
1016         } else {
1017             logger.debug("Adding subnets to internal vpn {}", vpnId.getValue());
1018             for (Uuid subnet : routerSubnets) {
1019                 addSubnetToVpn(vpnId, subnet);
1020             }
1021         }
1022     }
1023
1024     protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
1025
1026         List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId);
1027         if (routerSubnets != null) {
1028             for (Uuid subnetId : routerSubnets) {
1029                 logger.debug("Updating association of subnets to internal vpn {}", routerId.getValue());
1030                 updateVpnForSubnet(routerId, subnetId,false);
1031             }
1032         }
1033         clearFromVpnMaps(vpnId, routerId, null);
1034     }
1035
1036     protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
1037         List<String> failed = new ArrayList<String>();
1038         if (!networks.isEmpty()) {
1039             // store in Data Base
1040             updateVpnMaps(vpn, null, null, null, networks);
1041             // process corresponding subnets for VPN
1042             for (Uuid nw : networks) {
1043                 if (NeutronvpnUtils.getNeutronNetwork(broker, nw) == null) {
1044                     failed.add(nw.getValue());
1045                 } else {
1046                     List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(broker, nw);
1047                     logger.debug("Adding network subnets...");
1048                     if (networkSubnets != null) {
1049                         for (Uuid subnet : networkSubnets) {
1050                             addSubnetToVpn(vpn, subnet);
1051                         }
1052                     }
1053                 }
1054             }
1055         }
1056         return failed;
1057     }
1058
1059     protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
1060         List<String> failed = new ArrayList<String>();
1061         if (networks != null && !networks.isEmpty()) {
1062             // store in Data Base
1063             clearFromVpnMaps(vpn, null, networks);
1064             // process corresponding subnets for VPN
1065             for (Uuid nw : networks) {
1066                 if (NeutronvpnUtils.getNeutronNetwork(broker, nw) == null) {
1067                     failed.add(nw.getValue());
1068                 } else {
1069                     List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(broker, nw);
1070                     logger.debug("Removing network subnets...");
1071                     if (networkSubnets != null) {
1072                         for (Uuid subnet : networkSubnets) {
1073                             removeSubnetFromVpn(vpn, subnet);
1074                         }
1075                     }
1076                 }
1077             }
1078         }
1079         return failed;
1080     }
1081
1082     @Override
1083     public Future<RpcResult<AssociateNetworksOutput>> associateNetworks(AssociateNetworksInput input) {
1084
1085         AssociateNetworksOutputBuilder opBuilder = new AssociateNetworksOutputBuilder();
1086         SettableFuture<RpcResult<AssociateNetworksOutput>> result = SettableFuture.create();
1087         logger.debug("associateNetworks {}", input);
1088         StringBuilder returnMsg = new StringBuilder();
1089         Uuid vpnId = input.getVpnId();
1090
1091         try {
1092             if (NeutronvpnUtils.getVpnMap(broker, vpnId) != null) {
1093                 List<Uuid> netIds = input.getNetworkId();
1094                 if (netIds != null && !netIds.isEmpty()) {
1095                     List<String> failed = associateNetworksToVpn(vpnId, netIds);
1096                     if (!failed.isEmpty()) {
1097                         returnMsg.append("network(s) not found : ").append(failed);
1098                     }
1099                 }
1100             } else {
1101                 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1102             }
1103             if (returnMsg.length() != 0) {
1104                 String message = String.format("associate Networks to vpn %s failed due to %s", vpnId.getValue(),
1105                         returnMsg);
1106                 logger.error(message);
1107                 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: " +
1108                         message);
1109                 opBuilder.setResponse(errorResponse);
1110                 result.set(RpcResultBuilder.<AssociateNetworksOutput>success().withResult(opBuilder.build()).build());
1111             } else {
1112                 result.set(RpcResultBuilder.<AssociateNetworksOutput>success().build());
1113             }
1114         } catch (Exception ex) {
1115             String message = String.format("associate Networks to vpn %s failed due to %s", input.getVpnId().getValue(),
1116                     ex.getMessage());
1117             logger.error(message, ex);
1118             result.set(RpcResultBuilder.<AssociateNetworksOutput>failed().withError(ErrorType.APPLICATION, message)
1119                     .build());
1120         }
1121         logger.debug("associateNetworks returns..");
1122         return result;
1123     }
1124
1125     @Override
1126     public Future<RpcResult<Void>> associateRouter(AssociateRouterInput input) {
1127
1128         SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1129         logger.debug("associateRouter {}", input);
1130         StringBuilder returnMsg = new StringBuilder();
1131         Uuid vpnId = input.getVpnId();
1132         Uuid routerId = input.getRouterId();
1133         try {
1134             if (routerId != null && vpnId != null) {
1135                 Router rtr = NeutronvpnUtils.getNeutronRouter(broker, routerId);
1136                 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(broker, vpnId);
1137                 if (rtr != null && vpnMap != null) {
1138                     if (vpnMap.getRouterId() != null) {
1139                         returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
1140                                 .append(vpnMap.getRouterId().getValue());
1141                     } else {
1142                         associateRouterToVpn(vpnId, routerId);
1143                     }
1144                 } else {
1145                     returnMsg.append("router not found : ").append(routerId.getValue());
1146                 }
1147             } else {
1148                 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1149             }
1150             if (returnMsg.length() != 0) {
1151                 String message = String.format("associate router to vpn %s failed due to %s", routerId.getValue(),
1152                         returnMsg);
1153                 logger.error(message);
1154                 result.set(RpcResultBuilder.<Void>failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1155                         .build());
1156             } else {
1157                 result.set(RpcResultBuilder.<Void>success().build());
1158             }
1159         } catch (Exception ex) {
1160             String message = String.format("associate router %s to vpn %s failed due to %s", routerId.getValue(),
1161                     vpnId.getValue(), ex.getMessage());
1162             logger.error(message, ex);
1163             result.set(RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, message).build());
1164         }
1165         logger.debug("associateRouter returns..");
1166         return result;
1167     }
1168
1169     @Override
1170     public Future<RpcResult<DissociateNetworksOutput>> dissociateNetworks(DissociateNetworksInput input) {
1171
1172         DissociateNetworksOutputBuilder opBuilder = new DissociateNetworksOutputBuilder();
1173         SettableFuture<RpcResult<DissociateNetworksOutput>> result = SettableFuture.create();
1174
1175         logger.debug("dissociateNetworks {}", input);
1176         StringBuilder returnMsg = new StringBuilder();
1177         Uuid vpnId = input.getVpnId();
1178
1179         try {
1180             if (NeutronvpnUtils.getVpnMap(broker, vpnId) != null) {
1181                 List<Uuid> netIds = input.getNetworkId();
1182                 if (netIds != null && !netIds.isEmpty()) {
1183                     List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
1184                     if (!failed.isEmpty()) {
1185                         returnMsg.append("netowrk(s) not found : ").append(failed);
1186                     }
1187                 }
1188             } else {
1189                 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1190             }
1191             if (returnMsg.length() != 0) {
1192                 String message = String.format("dissociate Networks to vpn %s failed due to %s", vpnId.getValue(),
1193                         returnMsg);
1194                 logger.error(message);
1195                 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: " +
1196                         message);
1197                 opBuilder.setResponse(errorResponse);
1198                 result.set(RpcResultBuilder.<DissociateNetworksOutput>success().withResult(opBuilder.build()).build());
1199             } else {
1200                 result.set(RpcResultBuilder.<DissociateNetworksOutput>success().build());
1201             }
1202         } catch (Exception ex) {
1203             String message = String.format("dissociate Networks to vpn %s failed due to %s", input.getVpnId().
1204                     getValue(), ex.getMessage());
1205             logger.error(message, ex);
1206             result.set(RpcResultBuilder.<DissociateNetworksOutput>failed().withError(ErrorType.APPLICATION, message)
1207                     .build());
1208         }
1209         logger.debug("dissociateNetworks returns..");
1210         return result;
1211     }
1212
1213     @Override
1214     public Future<RpcResult<Void>> dissociateRouter(DissociateRouterInput input) {
1215
1216         SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1217
1218         logger.debug("dissociateRouter {}", input);
1219         StringBuilder returnMsg = new StringBuilder();
1220         Uuid vpnId = input.getVpnId();
1221         Uuid routerId = input.getRouterId();
1222         try {
1223             if (NeutronvpnUtils.getVpnMap(broker, vpnId) != null) {
1224                 if (routerId != null) {
1225                     Router rtr = NeutronvpnUtils.getNeutronRouter(broker, routerId);
1226                     if (rtr != null) {
1227                         dissociateRouterFromVpn(vpnId, routerId);
1228                     } else {
1229                         returnMsg.append("router not found : ").append(routerId.getValue());
1230                     }
1231                 }
1232             } else {
1233                 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1234             }
1235             if (returnMsg.length() != 0) {
1236                 String message = String.format("dissociate router %s to vpn %s failed due to %s", routerId.getValue(),
1237                         vpnId.getValue(), returnMsg);
1238                 logger.error(message);
1239                 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: " +
1240                         message);
1241                 result.set(RpcResultBuilder.<Void>failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1242                         .build());
1243             } else {
1244                 result.set(RpcResultBuilder.<Void>success().build());
1245             }
1246         } catch (Exception ex) {
1247             String message = String.format("disssociate router %s to vpn %s failed due to %s", routerId.getValue(),
1248                     vpnId.getValue(), ex.getMessage());
1249             logger.error(message, ex);
1250             result.set(RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, message).build());
1251         }
1252         logger.debug("dissociateRouter returns..");
1253
1254         return result;
1255     }
1256
1257     @Override
1258     public Future<RpcResult<GetFixedIPsForNeutronPortOutput>> getFixedIPsForNeutronPort(GetFixedIPsForNeutronPortInput
1259                                                                                                 input) {
1260         GetFixedIPsForNeutronPortOutputBuilder opBuilder = new GetFixedIPsForNeutronPortOutputBuilder();
1261         SettableFuture<RpcResult<GetFixedIPsForNeutronPortOutput>> result = SettableFuture.create();
1262         Uuid portId = input.getPortId();
1263         StringBuilder returnMsg = new StringBuilder();
1264         try {
1265             List<String> fixedIPList = new ArrayList<>();
1266             Port port = NeutronvpnUtils.getNeutronPort(broker, portId);
1267             if (port != null) {
1268                 List<FixedIps> fixedIPs = port.getFixedIps();
1269                 for (FixedIps ip : fixedIPs) {
1270                     fixedIPList.add(ip.getIpAddress().getIpv4Address().getValue());
1271                 }
1272             } else {
1273                 returnMsg.append("neutron port: ").append(portId.getValue()).append(" not found");
1274             }
1275             if (returnMsg.length() != 0) {
1276                 String message = String.format("Retrieval of FixedIPList for neutron port failed due to %s", returnMsg);
1277                 logger.error(message);
1278                 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>failed().withWarning(ErrorType.PROTOCOL,
1279                         "invalid-value", message).build());
1280             } else {
1281                 opBuilder.setFixedIPs(fixedIPList);
1282                 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>success().withResult(opBuilder.build())
1283                         .build());
1284                 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>success().build());
1285             }
1286         } catch (Exception ex) {
1287             String message = String.format("Retrieval of FixedIPList for neutron port %s failed due to %s", portId
1288                     .getValue(), ex.getMessage());
1289             logger.error(message, ex);
1290             result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>failed().withError(ErrorType.APPLICATION,
1291                     message).build());
1292         }
1293         return result;
1294     }
1295
1296     protected void handleNeutronRouterDeleted(Uuid routerId, List<Uuid> routerSubnetIds) {
1297         // check if the router is associated to some VPN
1298         Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
1299         if (vpnId != null) {
1300             // remove existing external vpn interfaces
1301             for (Uuid subnetId : routerSubnetIds) {
1302                 removeSubnetFromVpn(vpnId, subnetId);
1303             }
1304             clearFromVpnMaps(vpnId, routerId, null);
1305         } else {
1306             // remove existing internal vpn interfaces
1307             for (Uuid subnetId : routerSubnetIds) {
1308                 removeSubnetFromVpn(routerId, subnetId);
1309             }
1310         }
1311         // delete entire vpnMaps node for internal VPN
1312         deleteVpnMapsNode(routerId);
1313
1314         // delete vpn-instance for internal VPN
1315         deleteVpnInstance(routerId);
1316     }
1317
1318     protected Subnet getNeutronSubnet(Uuid subnetId) {
1319         InstanceIdentifier<Subnet> inst = InstanceIdentifier.create(Neutron.class).
1320                 child(Subnets.class).child(Subnet.class, new SubnetKey(subnetId));
1321         Optional<Subnet> sn = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, inst);
1322
1323         if (sn.isPresent()) {
1324             return sn.get();
1325         }
1326         return null;
1327     }
1328
1329     protected IpAddress getNeutronSubnetGateway(Uuid subnetId) {
1330         Subnet sn = getNeutronSubnet(subnetId);
1331         if (null != sn) {
1332             return sn.getGatewayIp();
1333         }
1334         return null;
1335     }
1336
1337     protected Port getNeutronPort(String name) {
1338         return NeutronvpnUtils.getNeutronPort(broker, new Uuid(name));
1339     }
1340
1341     protected Port getNeutronPort(Uuid portId) {
1342         return NeutronvpnUtils.getNeutronPort(broker, portId);
1343     }
1344
1345     protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
1346         List<Uuid> subnets = new ArrayList<Uuid>();
1347         //read subnetmaps
1348         InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
1349         Optional<Subnetmaps> subnetmaps = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
1350                 subnetmapsid);
1351         if (subnetmaps.isPresent() && subnetmaps.get().getSubnetmap() != null) {
1352             List<Subnetmap> subnetMapList = subnetmaps.get().getSubnetmap();
1353             for (Subnetmap subnetMap : subnetMapList) {
1354                 if (subnetMap.getVpnId() != null && subnetMap.getVpnId().equals(vpnid)) {
1355                     subnets.add(subnetMap.getId());
1356                 }
1357             }
1358         }
1359         return subnets;
1360     }
1361
1362     public List<String> showNeutronPortsCLI() {
1363         List<String> result = new ArrayList<String>();
1364         result.add(String.format(" %-34s  %-22s  %-22s  %-6s ", "PortName", "Mac Address", "IP Address",
1365                 "Prefix Length"));
1366         result.add("---------------------------------------------------------------------------------------");
1367         InstanceIdentifier<Ports> portidentifier = InstanceIdentifier.create(Neutron.class).child(Ports.class);
1368         try {
1369             Optional<Ports> ports = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, portidentifier);
1370             if (ports.isPresent() && ports.get().getPort() != null) {
1371                 List<Port> portList = ports.get().getPort();
1372                 for (Port port : portList) {
1373                     result.add(String.format(" %-34s  %-22s  %-22s  %-6s ", port.getUuid().getValue(), port
1374                             .getMacAddress(), port.getFixedIps().get(0).getIpAddress().getIpv4Address().getValue(),
1375                             NeutronvpnUtils.getIPPrefixFromPort(broker, port)));
1376                 }
1377             }
1378         } catch (Exception e) {
1379             logger.error("Failed to retrieve neutronPorts info : ", e);
1380             System.out.println("Failed to retrieve neutronPorts info : " + e.getMessage());
1381         }
1382         return result;
1383     }
1384
1385     public List<String> showVpnConfigCLI(Uuid vpnuuid) {
1386         List<String> result = new ArrayList<String>();
1387         if (vpnuuid == null) {
1388             System.out.println("");
1389             System.out.println("Displaying VPN config for all VPNs");
1390             System.out.println("To display VPN config for a particular VPN, use the following syntax");
1391             System.out.println(getshowVpnConfigCLIHelp());
1392         }
1393         try {
1394             RpcResult<GetL3VPNOutput> rpcResult = getL3VPN(new GetL3VPNInputBuilder().setId(vpnuuid).build()).get();
1395             if (rpcResult.isSuccessful()) {
1396                 result.add("");
1397                 result.add(String.format(" %-37s %-37s %-7s ", "VPN ID", "Tenant ID", "RD"));
1398                 result.add("");
1399                 result.add(String.format(" %-80s ", "Import-RTs"));
1400                 result.add("");
1401                 result.add(String.format(" %-80s ", "Export-RTs"));
1402                 result.add("");
1403                 result.add(String.format(" %-76s ", "Subnet IDs"));
1404                 result.add("");
1405                 result.add("------------------------------------------------------------------------------------");
1406                 result.add("");
1407                 List<L3vpnInstances> VpnList = rpcResult.getResult().getL3vpnInstances();
1408                 for (L3vpnInstance Vpn : VpnList) {
1409                     String tenantId = Vpn.getTenantId() != null ? Vpn.getTenantId().getValue() : "\"                 " +
1410                             "                  \"";
1411                     result.add(String.format(" %-37s %-37s %-7s ", Vpn.getId().getValue(), tenantId, Vpn
1412                             .getRouteDistinguisher()));
1413                     result.add("");
1414                     result.add(String.format(" %-80s ", Vpn.getImportRT()));
1415                     result.add("");
1416                     result.add(String.format(" %-80s ", Vpn.getExportRT()));
1417                     result.add("");
1418
1419                     Uuid vpnid = Vpn.getId();
1420                     List<Uuid> subnetList = getSubnetsforVpn(vpnid);
1421                     if (!subnetList.isEmpty()) {
1422                         for (Uuid subnetuuid : subnetList) {
1423                             result.add(String.format(" %-76s ", subnetuuid.getValue()));
1424                         }
1425                     } else {
1426                         result.add(String.format(" %-76s ", "\"                                    \""));
1427                     }
1428                     result.add("");
1429                     result.add("----------------------------------------");
1430                     result.add("");
1431                 }
1432             } else {
1433                 String errortag = rpcResult.getErrors().iterator().next().getTag();
1434                 if (errortag == "") {
1435                     System.out.println("");
1436                     System.out.println("No VPN has been configured yet");
1437                 } else if (errortag == "invalid-value") {
1438                     System.out.println("");
1439                     System.out.println("VPN " + vpnuuid.getValue() + " is not present");
1440                 } else {
1441                     System.out.println("error getting VPN info : " + rpcResult.getErrors());
1442                     System.out.println(getshowVpnConfigCLIHelp());
1443                 }
1444             }
1445         } catch (InterruptedException | ExecutionException e) {
1446             logger.error("error getting VPN info : ", e);
1447             System.out.println("error getting VPN info : " + e.getMessage());
1448         }
1449         return result;
1450     }
1451
1452     private String getshowVpnConfigCLIHelp() {
1453         StringBuilder help = new StringBuilder("Usage:");
1454         help.append("display vpn-config [-vid/--vpnid <id>]");
1455         return help.toString();
1456     }
1457
1458     private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
1459         SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
1460
1461         logger.info("publish notification called");
1462
1463         builder.setSubnetId(subnetId);
1464         builder.setSubnetIp(subnetIp);
1465         builder.setVpnName(vpnName);
1466         builder.setExternalVpn(isExternalvpn);
1467         builder.setElanTag(elanTag);
1468
1469         notificationPublishService.putNotification(builder.build());
1470     }
1471
1472     private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
1473         SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
1474
1475         logger.info("publish notification called");
1476
1477         builder.setSubnetId(subnetId);
1478         builder.setSubnetIp(subnetIp);
1479         builder.setVpnName(vpnName);
1480         builder.setExternalVpn(isExternalvpn);
1481         builder.setElanTag(elanTag);
1482
1483         notificationPublishService.putNotification(builder.build());
1484     }
1485
1486     private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
1487         SubnetUpdatedInVpnBuilder builder = new SubnetUpdatedInVpnBuilder();
1488
1489         logger.info("publish notification called");
1490
1491         builder.setSubnetId(subnetId);
1492         builder.setSubnetIp(subnetIp);
1493         builder.setVpnName(vpnName);
1494         builder.setExternalVpn(isExternalvpn);
1495         builder.setElanTag(elanTag);
1496
1497         notificationPublishService.putNotification(builder.build());
1498     }
1499
1500 }