2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.groupbasedpolicy.renderer.vpp.iface;
11 import static com.google.common.base.Preconditions.checkNotNull;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.List;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.locks.ReentrantLock;
20 import java.util.stream.Collectors;
22 import javax.annotation.Nonnull;
24 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
25 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
26 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
27 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
28 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
29 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
30 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
31 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
32 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
33 import org.opendaylight.groupbasedpolicy.renderer.util.AddressEndpointUtils;
34 import org.opendaylight.groupbasedpolicy.renderer.vpp.manager.VppNodeManager;
35 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.CloseOnFailTransactionChain;
36 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
37 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
38 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
39 import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
40 import org.opendaylight.groupbasedpolicy.util.EndpointUtils;
41 import org.opendaylight.groupbasedpolicy.util.IidFactory;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.Endpoints;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.AddressEndpoints;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocationBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.RelativeLocations;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.RelativeLocationsBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocation;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocationBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpointKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.ProviderName;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProvider;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProviderBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocation;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocationBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocationKey;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;
68 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
69 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
70 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
71 import org.slf4j.Logger;
72 import org.slf4j.LoggerFactory;
74 import com.google.common.annotations.VisibleForTesting;
75 import com.google.common.base.Function;
76 import com.google.common.base.Optional;
77 import com.google.common.util.concurrent.CheckedFuture;
78 import com.google.common.util.concurrent.FutureCallback;
79 import com.google.common.util.concurrent.Futures;
80 import com.google.common.util.concurrent.ListenableFuture;
82 public class VppEndpointLocationProvider extends DataTreeChangeHandler<AddressEndpoint> {
84 private static final Logger LOG = LoggerFactory.getLogger(VppEndpointLocationProvider.class);
85 public static final ProviderName VPP_ENDPOINT_LOCATION_PROVIDER =
86 new ProviderName("VPP endpoint location provider");
87 public static final long PROVIDER_PRIORITY = 10L;
88 private final BindingTransactionChain txChain;
89 private final Map<VppEndpointKey, VppEndpoint> vppEndpoints = new HashMap<>();
90 private final Map<VppEndpointKey, DataObjectModification<AddressEndpoint>> cachedVppEndpoints = new HashMap<>();
92 public static final ReentrantLock REENTRANT_LOCK = new ReentrantLock();
94 public VppEndpointLocationProvider(DataBroker dataProvider) {
96 LocationProvider locationProvider = new LocationProviderBuilder().setProvider(VPP_ENDPOINT_LOCATION_PROVIDER)
97 .setPriority(PROVIDER_PRIORITY)
99 txChain = checkNotNull(dataProvider)
100 .createTransactionChain(new CloseOnFailTransactionChain(VppEndpointLocationProvider.class.getSimpleName()));
101 WriteTransaction wTx = txChain.newWriteOnlyTransaction();
102 wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.locationProviderIid(VPP_ENDPOINT_LOCATION_PROVIDER),
103 locationProvider, true);
104 Futures.addCallback(wTx.submit(), new FutureCallback<Void>() {
107 public void onSuccess(Void result) {
108 LOG.debug("{} was created", VPP_ENDPOINT_LOCATION_PROVIDER.getValue());
112 public void onFailure(Throwable t) {
113 LOG.error("{} was NOT created", VPP_ENDPOINT_LOCATION_PROVIDER.getValue());
116 registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
117 InstanceIdentifier.builder(Endpoints.class).child(AddressEndpoints.class).child(AddressEndpoint.class).build()));
121 protected void onWrite(DataObjectModification<AddressEndpoint> rootNode,
122 InstanceIdentifier<AddressEndpoint> rootIdentifier) {
123 LOG.debug("onWrite triggered by {}", rootNode.getDataAfter());
125 if (EndpointUtils.isExternalEndpoint(dataProvider, rootNode.getDataAfter())) {
126 writeLocation(createRelativeAddressEndpointLocation(rootNode.getDataAfter().getKey(),
127 VppNodeManager.resolvePublicInterfaces(dataProvider))).get();
129 createAbsoluteAddressEndpointLocation(null, rootNode).get();
131 } catch (InterruptedException | ExecutionException e) {
132 LOG.error("Failed to write location for endpoint {}. {}", rootNode.getDataAfter().getKey(), e.getMessage());
137 protected void onDelete(DataObjectModification<AddressEndpoint> rootNode,
138 InstanceIdentifier<AddressEndpoint> rootIdentifier) {
139 LOG.debug("onDelete triggered by {}", rootNode.getDataBefore());
141 if (EndpointUtils.isExternalEndpoint(dataProvider, rootNode.getDataBefore())) {
142 deleteLocation(createProviderAddressEndpointLocationKey(rootNode.getDataBefore().getKey())).get();
144 createAbsoluteAddressEndpointLocation(null, rootNode).get();
146 } catch (InterruptedException | ExecutionException e) {
147 LOG.error("Failed to delete location for endpoint {}. {}", rootNode.getDataBefore().getKey(),
153 protected void onSubtreeModified(DataObjectModification<AddressEndpoint> rootNode,
154 InstanceIdentifier<AddressEndpoint> rootIdentifier) {
155 LOG.debug("onSubtreeModified triggered by change: before={} after={}", rootNode.getDataBefore(),
156 rootNode.getDataAfter());
157 if (rootNode.getDataBefore() != null) {
158 onDelete(rootNode, rootIdentifier);
160 if (rootNode.getDataAfter() != null) {
161 onWrite(rootNode, rootIdentifier);
165 public ListenableFuture<Void> createLocationForVppEndpoint(VppEndpoint vppEndpoint) {
166 return createAbsoluteAddressEndpointLocation(vppEndpoint, null);
169 public ListenableFuture<Void> deleteLocationForVppEndpoint(VppEndpoint vppEndpoint) {
170 // removing VPP EP from cache out of since block, it's not needed for the other thread.
171 vppEndpoints.remove(vppEndpoint.getKey());
172 return deleteLocation(createProviderAddressEndpointLocationKey(vppEndpoint));
176 * There are two inputs from which we need to resolve location - {@link AddressEndpoint} and {@link VppEndpoint}
177 * These data are delivered by different threads which meet here.
180 synchronized ListenableFuture<Void> createAbsoluteAddressEndpointLocation(VppEndpoint vppEndpoint,
181 DataObjectModification<AddressEndpoint> rootNode) {
182 if (vppEndpoint != null) {
183 LOG.debug("Saving VPP endpoint {}" + vppEndpoint.getKey());
184 vppEndpoints.put(vppEndpoint.getKey(), vppEndpoint);
185 if (cachedVppEndpoints.get(vppEndpoint.getKey()) != null) {
187 processAddrEp(cachedVppEndpoints.get(vppEndpoint.getKey())).get();
188 } catch (InterruptedException | ExecutionException e) {
189 LOG.error("Failed to resolve location for cached endpoint {}. {}", vppEndpoint.getKey(), e);
191 return Futures.immediateFuture(null);
193 } else if (rootNode != null) {
195 processAddrEp(rootNode).get();
196 } catch (InterruptedException | ExecutionException e) {
197 LOG.error("Failed to resolve location for changed endpoint before={} after={}. {}",
198 rootNode.getDataAfter(), rootNode.getDataAfter(), e);
200 return Futures.immediateFuture(null);
202 return Futures.immediateFuture(null);
205 private ListenableFuture<Void> processAddrEp(DataObjectModification<AddressEndpoint> rootNode) {
206 if (rootNode != null) {
207 AddressEndpointChange aec = new AddressEndpointChange(rootNode, txChain);
208 switch (rootNode.getModificationType()) {
210 case SUBTREE_MODIFIED: {
211 VppEndpoint vpp = vppEndpoints.get(vppEndpointKeyFrom(rootNode.getDataAfter().getKey()));
213 VppEndpointKey key = vppEndpointKeyFrom(rootNode.getDataAfter().getKey());
214 LOG.debug("Caching VPP endpoint {}" + key);
215 cachedVppEndpoints.put(key, rootNode);
216 return Futures.immediateFuture(null);
218 if (aec.hasMoreParents()) {
219 return aec.syncMultiparents();
224 if (aec.hasMoreParents()) {
225 return aec.syncMultiparents();
232 return Futures.immediateFuture(null);
235 private ProviderAddressEndpointLocation createAbsoluteLocationFromVppEndpoint(VppEndpoint vppEndpoint) {
236 InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(vppEndpoint.getVppNodeId());
237 String restIfacePath = VppPathMapper.interfaceToRestPath(vppEndpoint.getVppInterfaceName());
238 AbsoluteLocation absoluteLocation =
239 new AbsoluteLocationBuilder().setLocationType(new ExternalLocationCaseBuilder()
240 .setExternalNodeMountPoint(vppNodeIid).setExternalNodeConnector(restIfacePath).build()).build();
241 return new ProviderAddressEndpointLocationBuilder()
242 .setKey(createProviderAddressEndpointLocationKey(vppEndpoint))
243 .setAbsoluteLocation(absoluteLocation)
247 public ProviderAddressEndpointLocation createRelativeAddressEndpointLocation(@Nonnull AddressEndpointKey addrEp,
248 @Nonnull Map<NodeId, String> publicIntfNamesByNodes) {
249 RelativeLocations relLocations =
250 new RelativeLocationsBuilder()
251 .setExternalLocation(publicIntfNamesByNodes.keySet()
253 .filter(nodeId -> publicIntfNamesByNodes.get(nodeId) != null)
254 .map(nodeId -> new ExternalLocationBuilder()
255 .setExternalNodeMountPoint(VppIidFactory.getNetconfNodeIid(nodeId))
256 .setExternalNodeConnector(
257 VppPathMapper.interfaceToRestPath(publicIntfNamesByNodes.get(nodeId)))
259 .collect(Collectors.toList()))
261 return new ProviderAddressEndpointLocationBuilder().setKey(createProviderAddressEndpointLocationKey(addrEp))
262 .setRelativeLocations(relLocations)
266 public ListenableFuture<Void> writeLocation(ProviderAddressEndpointLocation location) {
267 REENTRANT_LOCK.lock();
268 WriteTransaction wTx = txChain.newWriteOnlyTransaction();
269 wTx.put(LogicalDatastoreType.CONFIGURATION,
270 IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER, location.getKey()),
272 CheckedFuture<Void, TransactionCommitFailedException> submit = wTx.submit();
273 REENTRANT_LOCK.unlock();
274 return Futures.transform(submit, new Function<Void, Void>() {
277 public Void apply(Void input) {
278 LOG.debug("{} provided location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), location);
284 public ListenableFuture<Void> deleteLocation(ProviderAddressEndpointLocationKey key) {
285 REENTRANT_LOCK.lock();
286 ReadWriteTransaction rwTx = txChain.newReadWriteTransaction();
287 LOG.debug("Deleting location for {}", key);
288 DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
289 IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER, key), rwTx);
290 CheckedFuture<Void, TransactionCommitFailedException> submit = rwTx.submit();
291 REENTRANT_LOCK.unlock();
292 return Futures.transform(submit, new Function<Void, Void>() {
295 public Void apply(Void input) {
296 LOG.debug("{} removed location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), key);
302 public ListenableFuture<Void> replaceLocationForEndpoint(@Nonnull ExternalLocationCase location, @Nonnull AddressEndpointWithLocationKey addrEpWithLocKey) {
303 InstanceIdentifier<ProviderAddressEndpointLocation> iid = IidFactory.providerAddressEndpointLocationIid(
304 VPP_ENDPOINT_LOCATION_PROVIDER, createProviderAddressEndpointLocationKey(addrEpWithLocKey));
305 ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
306 Optional<ProviderAddressEndpointLocation> optLoc = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, iid, rTx);
308 ProviderAddressEndpointLocationKey provAddrEpLocKey =
309 KeyFactory.providerAddressEndpointLocationKey(addrEpWithLocKey);
310 ProviderAddressEndpointLocationBuilder builder = new ProviderAddressEndpointLocationBuilder().setKey(provAddrEpLocKey);
311 if(optLoc.isPresent() && optLoc.get().getAbsoluteLocation() != null) {
312 AbsoluteLocation absoluteLocation = optLoc.get().getAbsoluteLocation();
313 builder.setAbsoluteLocation(new AbsoluteLocationBuilder(absoluteLocation).setLocationType(location).build());
314 } else if (optLoc.isPresent() && optLoc.get().getRelativeLocations() != null) {
315 ExternalLocation extLoc = new ExternalLocationBuilder().setExternalNode(location.getExternalNode())
316 .setExternalNodeConnector(location.getExternalNodeConnector())
317 .setExternalNodeMountPoint(location.getExternalNodeMountPoint())
319 List<ExternalLocation> externalLocation = optLoc.get()
320 .getRelativeLocations()
321 .getExternalLocation();
322 externalLocation.add(extLoc);
323 RelativeLocations relativeLocation = new RelativeLocationsBuilder(optLoc.get().getRelativeLocations()).setExternalLocation(externalLocation).build();
324 builder.setRelativeLocations(relativeLocation);
327 LOG.warn("Cannot replace location for endpoint {}", addrEpWithLocKey);
328 return Futures.immediateFuture(null);
330 ProviderAddressEndpointLocation providerLocation = builder.build();
331 REENTRANT_LOCK.lock();
332 WriteTransaction wTx = txChain.newWriteOnlyTransaction();
333 wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.providerAddressEndpointLocationIid(
334 VPP_ENDPOINT_LOCATION_PROVIDER, providerLocation.getKey()), providerLocation);
335 LOG.debug("Updating location for {}", builder.build().getKey());
336 CheckedFuture<Void, TransactionCommitFailedException> submit = wTx.submit();
337 REENTRANT_LOCK.unlock();
338 return Futures.transform(submit, new Function<Void, Void>() {
341 public Void apply(Void input) {
342 LOG.debug("{} replaced location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
343 providerLocation.getKey());
349 static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(VppEndpoint vpp) {
350 return new ProviderAddressEndpointLocationKey(vpp.getAddress(), vpp.getAddressType(), vpp.getContextId(),
351 vpp.getContextType());
354 static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(AddressEndpointKey key) {
355 return new ProviderAddressEndpointLocationKey(key.getAddress(), key.getAddressType(), key.getContextId(),
356 key.getContextType());
359 static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(AddressEndpointWithLocationKey key) {
360 return new ProviderAddressEndpointLocationKey(key.getAddress(), key.getAddressType(), key.getContextId(),
361 key.getContextType());
364 private static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(ParentEndpointKey key) {
365 return new ProviderAddressEndpointLocationKey(key.getAddress(), key.getAddressType(), key.getContextId(),
366 key.getContextType());
369 private VppEndpointKey vppEndpointKeyFrom(AddressEndpointKey key) {
370 return new VppEndpointKey(key.getAddress(), key.getAddressType(), key.getContextId(), key.getContextType());
373 private VppEndpointKey vppEndpointKeyFrom(ParentEndpointKey key) {
374 return new VppEndpointKey(key.getAddress(), key.getAddressType(), key.getContextId(), key.getContextType());
377 private VppEndpointKey vppEndpointKeyFrom(ChildEndpointKey key) {
378 return new VppEndpointKey(key.getAddress(), key.getAddressType(), key.getContextId(), key.getContextType());
382 public void close() {
383 super.closeRegisteredListener();
384 WriteTransaction wTx = txChain.newWriteOnlyTransaction();
385 wTx.delete(LogicalDatastoreType.CONFIGURATION, IidFactory.locationProviderIid(VPP_ENDPOINT_LOCATION_PROVIDER));
389 private class AddressEndpointChange {
391 private final AddressEndpoint before;
392 private final AddressEndpoint after;
393 private final BindingTransactionChain transactionChain;
395 public AddressEndpointChange(DataObjectModification<AddressEndpoint> addrEp, @Nonnull BindingTransactionChain txChain) {
396 this.before = addrEp.getDataBefore();
397 this.after = addrEp.getDataAfter();
398 this.transactionChain = txChain;
401 boolean hasMoreParents() {
402 return (before != null && EndpointUtils.getParentEndpoints(before.getParentEndpointChoice()).size() > 1)
403 || (after != null && EndpointUtils.getParentEndpoints(after.getParentEndpointChoice()).size() > 1);
406 ListenableFuture<Void> syncMultiparents() {
407 REENTRANT_LOCK.lock();
408 ReadWriteTransaction rwTx = transactionChain.newReadWriteTransaction();
409 if (before != null) {
410 for (ParentEndpoint pe : EndpointUtils.getParentEndpoints(before.getParentEndpointChoice())) {
411 InstanceIdentifier<ProviderAddressEndpointLocation> iid =
412 IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER,
413 createProviderAddressEndpointLocationKey(pe.getKey()));
414 DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, iid, rwTx);
418 for (ParentEndpoint pe : EndpointUtils.getParentEndpoints(after.getParentEndpointChoice())) {
419 VppEndpoint vppEndpoint = vppEndpoints.get(vppEndpointKeyFrom(after.getKey()));
420 InstanceIdentifier<ProviderAddressEndpointLocation> iid =
421 IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER,
422 createProviderAddressEndpointLocationKey(pe.getKey()));
424 List<ChildEndpoint> childs = abc(rwTx, pe);
425 List<VppEndpoint> vppEps = new ArrayList<>();
426 for (ChildEndpoint che : childs) {
427 VppEndpoint cheVppEp = vppEndpoints.get(vppEndpointKeyFrom(che.getKey()));
428 if (cheVppEp != null) {
429 vppEps.add(cheVppEp);
433 if (vppEps.size() > 1) {
434 ProviderAddressEndpointLocation location = createRelativeLocationFromVppEndpoint(
435 createProviderAddressEndpointLocationKey(pe.getKey()), vppEps);
436 rwTx.put(LogicalDatastoreType.CONFIGURATION, iid, location, true);
438 ProviderAddressEndpointLocation location = createAbsoluteLocationFromVppEndpoint(
439 new VppEndpointBuilder(vppEndpoint).setKey(vppEndpointKeyFrom(pe.getKey())).build());
440 rwTx.put(LogicalDatastoreType.CONFIGURATION, iid, location, true);
445 CheckedFuture<Void, TransactionCommitFailedException> submit = rwTx.submit();
446 REENTRANT_LOCK.unlock();
450 private List<ChildEndpoint> abc(ReadWriteTransaction rTx, ParentEndpoint pe) {
451 AddressEndpointKey addrEpKey = new AddressEndpointKey(AddressEndpointUtils.fromParentEndpointKey(pe.getKey()));
452 Optional<AddressEndpoint> optParent = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(addrEpKey), rTx);
453 return (optParent.isPresent()) ? optParent.get().getChildEndpoint() : Collections.emptyList();
456 private ProviderAddressEndpointLocation createRelativeLocationFromVppEndpoint(
457 ProviderAddressEndpointLocationKey key, List<VppEndpoint> vppEndpoints) {
458 List<ExternalLocation> extLocations = vppEndpoints.stream().map(vppEndpoint -> {
459 InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(vppEndpoint.getVppNodeId());
460 String restIfacePath = VppPathMapper.interfaceToRestPath(vppEndpoint.getVppInterfaceName());
461 return new ExternalLocationBuilder().setExternalNodeMountPoint(vppNodeIid)
462 .setExternalNodeConnector(restIfacePath)
464 }).collect(Collectors.toList());
465 RelativeLocations relativeLocations =
466 new RelativeLocationsBuilder().setExternalLocation(extLocations).build();
467 return new ProviderAddressEndpointLocationBuilder().setRelativeLocations(relativeLocations)
472 ListenableFuture<Void> write() {
473 VppEndpoint vpp = vppEndpoints.get(vppEndpointKeyFrom(after.getKey()));
474 WriteTransaction wTx = transactionChain.newWriteOnlyTransaction();
475 ProviderAddressEndpointLocation location =
476 createAbsoluteLocationFromVppEndpoint(vpp);
477 InstanceIdentifier<ProviderAddressEndpointLocation> iid = IidFactory.providerAddressEndpointLocationIid(
478 VPP_ENDPOINT_LOCATION_PROVIDER, createProviderAddressEndpointLocationKey(vpp));
479 wTx.put(LogicalDatastoreType.CONFIGURATION, iid, location, true);
483 ListenableFuture<Void> delete() {
484 ReadWriteTransaction rwTx = transactionChain.newReadWriteTransaction();
485 InstanceIdentifier<ProviderAddressEndpointLocation> iid = IidFactory.providerAddressEndpointLocationIid(
486 VPP_ENDPOINT_LOCATION_PROVIDER, createProviderAddressEndpointLocationKey(before.getKey()));
487 DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, iid, rwTx);
488 return rwTx.submit();