Merge "BGPManager FIXMEs fixed"
[netvirt.git] / vpnservice / fibmanager / fibmanager-impl / src / main / java / org / opendaylight / netvirt / fibmanager / FibUtil.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.netvirt.fibmanager;
10
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import com.google.common.util.concurrent.FutureCallback;
14 import com.google.common.util.concurrent.Futures;
15
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
21 import org.opendaylight.genius.mdsalutil.MDSALUtil;
22 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.*;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data
33         .VpnInstanceOpDataEntry;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data
35         .VpnInstanceOpDataEntryKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
37
38
39
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311
41         .InterVpnLinkStates;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinks;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn
44         .link.states.InterVpnLinkState;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn
46         .link.states.InterVpnLinkStateKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn
48         .links.InterVpnLink;
49 import org.opendaylight.yangtools.yang.binding.DataObject;
50 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
51 import org.opendaylight.yangtools.yang.common.RpcResult;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import java.math.BigInteger;
56 import java.util.ArrayList;
57 import java.util.List;
58 import java.util.concurrent.ExecutionException;
59 import java.util.concurrent.Future;
60
61 public class FibUtil {
62     private static final Logger LOG = LoggerFactory.getLogger(FibUtil.class);
63     public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
64                                                           InstanceIdentifier<T> path) {
65
66         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
67
68         Optional<T> result = Optional.absent();
69         try {
70             result = tx.read(datastoreType, path).get();
71         } catch (Exception e) {
72             throw new RuntimeException(e);
73         }
74
75         return result;
76     }
77
78     static <T extends DataObject> void asyncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
79                                                   InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
80         WriteTransaction tx = broker.newWriteOnlyTransaction();
81         tx.merge(datastoreType, path, data, true);
82         Futures.addCallback(tx.submit(), callback);
83     }
84
85     static <T extends DataObject> void syncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
86                                                  InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
87         WriteTransaction tx = broker.newWriteOnlyTransaction();
88         tx.put(datastoreType, path, data, true);
89         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
90         try {
91             futures.get();
92         } catch (InterruptedException | ExecutionException e) {
93             LOG.error("Error writing to datastore (path, data) : ({}, {})", path, data);
94             throw new RuntimeException(e.getMessage());
95         }
96     }
97
98     static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
99         WriteTransaction tx = broker.newWriteOnlyTransaction();
100         tx.delete(datastoreType, path);
101         Futures.addCallback(tx.submit(), DEFAULT_CALLBACK);
102     }
103
104     static InstanceIdentifier<Adjacency> getAdjacencyIdentifier(String vpnInterfaceName, String ipAddress) {
105         return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces.class)
106                 .child(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface.class, new org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey(vpnInterfaceName)).augmentation(
107                         org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies.class)
108                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey(ipAddress)).build();
109     }
110
111     static InstanceIdentifier<Adjacencies> getAdjListPath(String vpnInterfaceName) {
112         return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces.class)
113                 .child(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface.class, new org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey(vpnInterfaceName)).augmentation(
114                         org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies.class).build();
115     }
116
117     static InstanceIdentifier<Prefixes> getPrefixToInterfaceIdentifier(long vpnId, String ipPrefix) {
118         return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface.class)
119                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
120                         .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.VpnIdsKey(vpnId)).child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes.class,
121                         new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey(ipPrefix)).build();
122     }
123
124     static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
125         return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces.class)
126                 .child(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface.class, new org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey(vpnInterfaceName)).build();
127     }
128
129     public static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
130         return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData.class)
131                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey(rd))
132                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey(dpnId)).build();
133     }
134
135     static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroute.vpn.Extraroute> getVpnToExtrarouteIdentifier(String vrfId, String ipPrefix) {
136         return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnToExtraroute.class)
137                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroute.Vpn
138                         .class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to
139                         .extraroute.VpnKey(vrfId)).child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn
140                         .rev130911.vpn.to.extraroute.vpn.Extraroute.class,
141                         new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroute.vpn.ExtrarouteKey(ipPrefix)).build();
142     }
143
144     static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String rd) {
145         return InstanceIdentifier.builder(VpnInstanceOpData.class)
146                 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd)).build();
147     }
148
149     static Optional<VpnInstanceOpDataEntry> getVpnInstanceOpData(DataBroker broker, String rd) {
150         InstanceIdentifier<VpnInstanceOpDataEntry> id = getVpnInstanceOpDataIdentifier(rd);
151         return read(broker, LogicalDatastoreType.OPERATIONAL, id);
152     }
153
154     static String getNextHopLabelKey(String rd, String prefix){
155         String key = rd + FibConstants.SEPARATOR + prefix;
156         return key;
157     }
158
159     static void releaseId(IdManagerService idManager, String poolName, String idKey) {
160         ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
161         try {
162             Future<RpcResult<Void>> result = idManager.releaseId(idInput);
163             RpcResult<Void> rpcResult = result.get();
164             if(!rpcResult.isSuccessful()) {
165                 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
166             }
167         } catch (InterruptedException | ExecutionException e) {
168             LOG.warn("Exception when getting Unique Id for key {}", idKey, e);
169         }
170     }
171
172     static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
173     getVpnInstanceToVpnIdIdentifier(String vpnName) {
174         return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
175                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance.class,
176                         new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
177     }
178
179     public static long getVpnId(DataBroker broker, String vpnName) {
180
181         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
182                 .VpnInstance> id
183                 = getVpnInstanceToVpnIdIdentifier(vpnName);
184         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
185                 .VpnInstance> vpnInstance
186                 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
187
188         long vpnId = -1;
189         if(vpnInstance.isPresent()) {
190             vpnId = vpnInstance.get().getVpnId();
191         }
192         return vpnId;
193     }
194
195     /**
196      * Retrieves the VpnInstance name (typically the VPN Uuid) out from the route-distinguisher
197      *
198      * @param broker
199      * @param rd
200      * @return
201      */
202     public static Optional<String> getVpnNameFromRd(DataBroker broker, String rd) {
203         Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = getVpnInstanceOpData(broker, rd);
204         return Optional.fromNullable(vpnInstanceOpData.isPresent() ? vpnInstanceOpData.get().getVpnInstanceName()
205                 : null);
206     }
207
208     static List<InterVpnLink> getAllInterVpnLinks(DataBroker broker) {
209         InstanceIdentifier<InterVpnLinks> interVpnLinksIid = InstanceIdentifier.builder(InterVpnLinks.class).build();
210
211         Optional<InterVpnLinks> interVpnLinksOpData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
212                 interVpnLinksIid);
213
214         return ( interVpnLinksOpData.isPresent() ) ? interVpnLinksOpData.get().getInterVpnLink()
215                 : new ArrayList<InterVpnLink>();
216     }
217
218     /**
219      * Returns the instance identifier for a given vpnLinkName
220      *
221      * @param vpnLinkName
222      * @return
223      */
224     public static InstanceIdentifier<InterVpnLinkState> getInterVpnLinkStateIid(String vpnLinkName) {
225         return InstanceIdentifier.builder(InterVpnLinkStates.class).child(InterVpnLinkState.class, new InterVpnLinkStateKey(vpnLinkName)).build();
226     }
227
228     /**
229      * Checks if the InterVpnLink is in Active state
230      *
231      * @param broker
232      * @param vpnLinkName
233      * @return
234      */
235     public static boolean isInterVpnLinkActive(DataBroker broker, String vpnLinkName) {
236         Optional<InterVpnLinkState> interVpnLinkState = getInterVpnLinkState(broker, vpnLinkName);
237         if ( !interVpnLinkState.isPresent() ) {
238             LOG.warn("Could not find Operative State for InterVpnLink {}", vpnLinkName);
239             return false;
240         }
241
242         return interVpnLinkState.get().getState().equals(InterVpnLinkState.State.Active);
243     }
244
245     /**
246      * Checks if the state of the interVpnLink
247      *
248      * @param broker
249      * @param vpnLinkName
250      * @return
251      */
252     public static Optional<InterVpnLinkState> getInterVpnLinkState(DataBroker broker, String vpnLinkName) {
253         InstanceIdentifier<InterVpnLinkState> vpnLinkStateIid = getInterVpnLinkStateIid(vpnLinkName);
254         return read(broker, LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid);
255     }
256
257     /**
258      * Retrieves the InterVpnLink in which the VPN, represented by its Uuid,
259      * participates
260      *
261      * @param dataBroker
262      * @param vpnUuid
263      * @return The InterVpnLink or Optional.absent() if the VPN does not
264      *         participate in an InterVpnLink
265      */
266     public static Optional<InterVpnLink> getInterVpnLinkByVpnUuid(DataBroker dataBroker, String vpnUuid) {
267         List<InterVpnLink> interVpnLinkList = getAllInterVpnLinks(dataBroker);
268         for (InterVpnLink interVpnLink : interVpnLinkList) {
269             if (interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(vpnUuid)
270                     || interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(vpnUuid)) {
271                 LOG.debug("InterVpnLink found for VPN {}. Details: vpn1=( uuid={} endpoint={})  vpn2=( uuid={} endpoint={} ))",
272                         vpnUuid, interVpnLink.getFirstEndpoint().getVpnUuid(),
273                         interVpnLink.getFirstEndpoint().getIpAddress(), interVpnLink.getSecondEndpoint().getVpnUuid(),
274                         interVpnLink.getSecondEndpoint().getIpAddress());
275                 return Optional.fromNullable(interVpnLink);
276             }
277         }
278         LOG.debug("Could not find a suitable InterVpnLink for VpnUuid={}", vpnUuid);
279         return Optional.absent();
280     }
281
282     /**
283      * Retrieves the InterVpnLink in which the VPN, represented by its
284      * Route-Distinguisher, participates.
285      *
286      * @param dataBroker
287      * @param rd
288      * @return The InterVpnLink or Optional.absent() if the VPN does not
289      *         participate in an InterVpnLink
290      */
291     public static Optional<InterVpnLink> getInterVpnLinkByRd(DataBroker dataBroker, String rd) {
292         Optional<String> vpnId = getVpnNameFromRd(dataBroker, rd);
293         if ( !vpnId.isPresent() ) {
294             LOG.debug("Could not find vpnId for RouteDistinguisher {}", rd);
295             return Optional.absent();
296         }
297
298         return getInterVpnLinkByVpnUuid(dataBroker, vpnId.get());
299     }
300
301     /**
302      * Checks if the route-distinguisher is involved in any inter-vpn-link, which is returned if its found.
303      *
304      * @param dataBroker
305      * @param rd
306      * @return
307      */
308     public static Optional<InterVpnLink> getActiveInterVpnLinkFromRd(DataBroker dataBroker, String rd) {
309
310         Optional<InterVpnLink> interVpnLink = getInterVpnLinkByRd(dataBroker, rd);
311         if ( interVpnLink.isPresent() ) {
312             if ( isInterVpnLinkActive(dataBroker, interVpnLink.get().getName()) ) {
313                 return interVpnLink;
314             } else {
315                 LOG.warn("InterVpnLink for RouteDistinguisher {} exists, but it's in error state. InterVpnLink={}",
316                         rd, interVpnLink.get().getName());
317                 return Optional.absent();
318             }
319         }
320         return Optional.absent();
321     }
322
323     /**
324      * Checks if the route-distinguisher is involved in any inter-vpn-link. In that case, this method will return
325      * the endpoint of the other vpn involved in the inter-vpn-link.
326      *
327      * @param dataBroker
328      * @param rd
329      * @return
330      */
331     public static Optional<String> getInterVpnLinkOppositeEndPointIpAddress(DataBroker dataBroker, String rd) {
332         Optional<String> vpnId = getVpnNameFromRd(dataBroker, rd);
333         if ( !vpnId.isPresent() ) {
334             LOG.debug("Could not find the VpnName for RouteDistinguisher {}", rd);
335             return Optional.absent();
336         }
337         List<InterVpnLink> interVpnLinkList = getAllInterVpnLinks(dataBroker);
338         if (!interVpnLinkList.isEmpty()) {
339             for (InterVpnLink interVpnLink : interVpnLinkList) {
340                 if (interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(vpnId)) {
341                     return Optional.fromNullable(interVpnLink.getSecondEndpoint().getVpnUuid().getValue());
342                 } else if (interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(vpnId)) {
343                     return Optional.fromNullable(interVpnLink.getFirstEndpoint().getIpAddress().getValue());
344                 }
345             }
346         }
347         return Optional.absent();
348     }
349
350     /**
351      * Obtains the route-distinguisher for a given vpn-name
352      *
353      * @param broker
354      * @param vpnName
355      * @return
356      */
357     public static String getVpnRd(DataBroker broker, String vpnName) {
358         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
359                 .VpnInstance> id
360                 = getVpnInstanceToVpnIdIdentifier(vpnName);
361         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
362                 .VpnInstance> vpnInstance
363                 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
364
365         String rd = null;
366         if(vpnInstance.isPresent()) {
367             rd = vpnInstance.get().getVrfId();
368         }
369         return rd;
370     }
371
372     /**
373      * Returns a boolean value which indicates if the endpoint's IP received as parameter belongs to any InterVpnLink.
374      *
375      * @param broker
376      * @param endpointIp IP to serch for.
377      * @return
378      */
379     public static boolean getInterVpnLinkByEndpointIp(DataBroker broker, String endpointIp) {
380         List<InterVpnLink> allInterVpnLinks = getAllInterVpnLinks(broker);
381         for (InterVpnLink interVpnLink : allInterVpnLinks) {
382             if (interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(endpointIp)
383                     || interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(endpointIp)) {
384                 return true;
385             }
386         }
387         return false;
388     }
389
390     public static int getUniqueId(IdManagerService idManager, String poolName, String idKey) {
391         AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
392
393         try {
394             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
395             RpcResult<AllocateIdOutput> rpcResult = result.get();
396             if (rpcResult.isSuccessful()) {
397                 return rpcResult.getResult().getIdValue().intValue();
398             } else {
399                 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
400             }
401         } catch (InterruptedException | ExecutionException e) {
402             LOG.warn("Exception when getting Unique Id", e);
403         }
404         return 0;
405     }
406
407     static final FutureCallback<Void> DEFAULT_CALLBACK =
408             new FutureCallback<Void>() {
409                 @Override
410                 public void onSuccess(Void result) {
411                     LOG.debug("Success in Datastore operation");
412                 }
413
414                 @Override
415                 public void onFailure(Throwable error) {
416                     LOG.error("Error in Datastore operation", error);
417                 };
418             };
419
420     public static String getVpnNameFromId(DataBroker broker, long vpnId) {
421
422         InstanceIdentifier<VpnIds> id
423                 = getVpnIdToVpnInstanceIdentifier(vpnId);
424         Optional<VpnIds> vpnInstance
425                 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
426
427         String vpnName = null;
428         if (vpnInstance.isPresent()) {
429             vpnName = vpnInstance.get().getVpnInstanceName();
430         }
431         return vpnName;
432     }
433
434     static InstanceIdentifier<VpnIds>
435     getVpnIdToVpnInstanceIdentifier(long vpnId) {
436         return InstanceIdentifier.builder(VpnIdToVpnInstance.class)
437                 .child(VpnIds.class, new VpnIdsKey(Long.valueOf(vpnId))).build();
438     }
439     
440     public static <T extends DataObject> void syncUpdate(DataBroker broker, LogicalDatastoreType datastoreType,
441                                                          InstanceIdentifier<T> path, T data) {
442         WriteTransaction tx = broker.newWriteOnlyTransaction();
443         tx.put(datastoreType, path, data, true);
444         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
445         try {
446             futures.get();
447         } catch (InterruptedException | ExecutionException e) {
448             LOG.error("Error writing to datastore (path, data) : ({}, {})", path, data);
449             throw new RuntimeException(e.getMessage());
450         }
451     }
452
453 }