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.base_endpoint;
11 import com.google.common.base.Function;
12 import com.google.common.base.Optional;
13 import com.google.common.base.Preconditions;
14 import com.google.common.util.concurrent.Futures;
15 import com.google.common.util.concurrent.ListenableFuture;
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.ReadTransaction;
19 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
22 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
23 import org.opendaylight.groupbasedpolicy.api.BaseEndpointRendererAugmentation;
24 import org.opendaylight.groupbasedpolicy.api.BaseEndpointRendererAugmentationRegistry;
25 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
26 import org.opendaylight.groupbasedpolicy.util.IidFactory;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.ParentEndpointChoice;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentContainmentEndpointCase;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentContainmentEndpointCaseBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentEndpointCase;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentEndpointCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpoint;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpointBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpointBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointRegKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnreg;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.ContainmentEndpointUnreg;
53 import org.opendaylight.yangtools.yang.binding.Augmentation;
54 import org.opendaylight.yangtools.yang.common.RpcError;
55 import org.opendaylight.yangtools.yang.common.RpcResult;
56 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
60 import java.util.ArrayList;
61 import java.util.Collections;
62 import java.util.List;
64 import java.util.concurrent.ConcurrentHashMap;
65 import java.util.concurrent.ConcurrentMap;
66 import java.util.concurrent.Future;
68 import javax.annotation.Nullable;
70 public class BaseEndpointRpcRegistry
71 implements BaseEndpointService, BaseEndpointRendererAugmentationRegistry, AutoCloseable {
73 static final ConcurrentMap<String, BaseEndpointRendererAugmentation> registeredRenderers =
74 new ConcurrentHashMap<>();
75 private static final Logger LOG = LoggerFactory.getLogger(BaseEndpointRpcRegistry.class);
76 private final DataBroker dataProvider;
77 private final BindingAwareBroker.RpcRegistration<BaseEndpointService> rpcRegistration;
79 private Function<Void, RpcResult<Void>> futureTrans = new Function<Void, RpcResult<Void>>() {
82 public RpcResult<Void> apply(Void input) {
83 return RpcResultBuilder.<Void>success().build();
87 public BaseEndpointRpcRegistry(DataBroker dataProvider, RpcProviderRegistry rpcRegistry) {
88 Preconditions.checkNotNull(dataProvider);
89 Preconditions.checkNotNull(rpcRegistry);
91 this.dataProvider = dataProvider;
92 this.rpcRegistration = rpcRegistry.addRpcImplementation(BaseEndpointService.class, this);
96 * Registers renderer's endpoints augmentation.
98 * @param baseEndpointRendererAugmentation cannot be {@code null}
99 * @throws NullPointerException
102 public void register(BaseEndpointRendererAugmentation baseEndpointRendererAugmentation) {
103 if (baseEndpointRendererAugmentation != null) {
104 registeredRenderers.putIfAbsent(baseEndpointRendererAugmentation.getClass().getName(),
105 baseEndpointRendererAugmentation);
106 LOG.info("Registered {}", baseEndpointRendererAugmentation.getClass().getName());
111 * Unregisters renderer's endpoints augmentation.
113 * @param baseEndpointRendererAugmentation cannot be {@code null}
114 * @throws NullPointerException
117 public void unregister(BaseEndpointRendererAugmentation baseEndpointRendererAugmentation) {
118 if (baseEndpointRendererAugmentation == null
119 || !registeredRenderers.containsKey(baseEndpointRendererAugmentation.getClass().getName())) {
122 registeredRenderers.remove(baseEndpointRendererAugmentation.getClass().getName());
123 LOG.info("Unregistered {}", baseEndpointRendererAugmentation.getClass().getName());
127 * Register a new endpoint into the registry. If there is already an existing
128 * endpoint with the same keys, they will be overwritten with the new information.
130 * @param input Endpoint to register
133 public Future<RpcResult<Void>> registerEndpoint(RegisterEndpointInput input) {
134 long timestamp = System.currentTimeMillis();
136 WriteTransaction t = dataProvider.newWriteOnlyTransaction();
138 List<ContainmentEndpointReg> endpoints = input.getContainmentEndpointReg();
139 ListenableFuture<RpcResult<Void>> failResult = verifyRegisterEndpointInput(input);
140 if (failResult == null) {
141 for (ContainmentEndpointReg ce : nullToEmpty(endpoints)) {
142 long stamp = (ce.getTimestamp() == null || ce.getTimestamp() == 0) ? timestamp : ce.getTimestamp();
143 ContainmentEndpoint endpoint = buildContainmentEndpoint(ce).setTimestamp(stamp).build();
144 t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.containmentEndpointIid(endpoint.getKey()), endpoint,
147 updateContainmentEndpointRegChilds(t, endpoint);
150 List<AddressEndpointReg> addressEndpoints = input.getAddressEndpointReg();
151 for (AddressEndpointReg ae : nullToEmpty(addressEndpoints)) {
152 long stamp = (ae.getTimestamp() == null || ae.getTimestamp() == 0) ? timestamp : ae.getTimestamp();
153 AddressEndpoint endpoint = buildAddressEndpoint(ae).setTimestamp(stamp).build();
154 t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(endpoint.getKey()), endpoint,
157 updateAddressEndpointRegChilds(t, endpoint);
159 updateAddressEndpointRegParents(t, endpoint);
165 ListenableFuture<Void> r = t.submit();
166 return Futures.transform(r, futureTrans);
169 private void updateContainmentEndpointRegChilds(WriteTransaction t, ContainmentEndpoint containmentEndpoint) {
170 ReadOnlyTransaction readTransaction = dataProvider.newReadOnlyTransaction();
172 for (ChildEndpoint child : nullToEmpty(containmentEndpoint.getChildEndpoint())) {
173 AddressEndpointKey key = new AddressEndpointKey(child.getAddress(), child.getAddressType(),
174 child.getContextId(), child.getContextType());
175 Optional<AddressEndpoint> addressEndpointOptional = DataStoreHelper
176 .readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(key), readTransaction);
178 if (addressEndpointOptional.isPresent()) {
179 ParentEndpointChoice parentEndpointChoice = addressEndpointOptional.get().getParentEndpointChoice();
180 List<ParentContainmentEndpoint> parentContainmentEndpoints =
181 getParentContainmentEndpoints(parentEndpointChoice);
183 ParentContainmentEndpoint parentContainmentEndpoint =
184 new ParentContainmentEndpointBuilder().setContextId(containmentEndpoint.getContextId())
185 .setContextType(containmentEndpoint.getContextType())
188 if (!nullToEmpty(parentContainmentEndpoints).contains(parentContainmentEndpoint)) {
189 parentContainmentEndpoints.add(parentContainmentEndpoint);
190 AddressEndpoint updatedAddressEndpoint = new AddressEndpointBuilder(addressEndpointOptional.get())
191 .setParentEndpointChoice(new ParentContainmentEndpointCaseBuilder()
192 .setParentContainmentEndpoint(parentContainmentEndpoints).build())
195 t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(key), updatedAddressEndpoint);
201 private ListenableFuture<RpcResult<Void>> verifyRegisterEndpointInput(RegisterEndpointInput input) {
202 ListenableFuture<RpcResult<Void>> result;
203 List<AddressEndpointReg> addressEndpointRegs = nullToEmpty(input.getAddressEndpointReg());
204 List<ContainmentEndpointReg> containmentEndpointRegs = nullToEmpty(input.getContainmentEndpointReg());
206 for (AddressEndpointReg addressEndpointReg : nullToEmpty(addressEndpointRegs)) {
207 result = verifyAddressEndpointChilds(addressEndpointRegs, addressEndpointReg);
208 if (result != null) {
212 result = verifyAddressEndpointParents(addressEndpointRegs, addressEndpointReg);
213 if (result != null) {
218 result = verifyContainmentEndpointChilds(addressEndpointRegs, containmentEndpointRegs);
219 if (result != null) {
226 private ListenableFuture<RpcResult<Void>> verifyContainmentEndpointChilds(
227 List<AddressEndpointReg> addressEndpointRegs, List<ContainmentEndpointReg> containmentEndpointRegs) {
228 for (ContainmentEndpointReg containmentEndpointReg : nullToEmpty(containmentEndpointRegs)) {
229 for (ChildEndpoint childEndpoint : nullToEmpty(containmentEndpointReg.getChildEndpoint())) {
230 AddressEndpointRegKey key = new AddressEndpointRegKey(childEndpoint.getAddress(),
231 childEndpoint.getAddressType(), childEndpoint.getContextId(), childEndpoint.getContextType());
232 AddressEndpointReg addressEndpointRegChild = findAddressEndpointReg(key, addressEndpointRegs);
233 if (addressEndpointRegChild == null) {
234 // todo this can be optimized if we move this to
235 // updateContainmentEndpointRegChilds and verify child in one step with update.
236 Optional<AddressEndpoint> addressEndpointOptional =
237 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
238 IidFactory.addressEndpointIid(new AddressEndpointKey(key.getAddress(),
239 key.getAddressType(), key.getContextId(), key.getContextType())),
240 dataProvider.newReadOnlyTransaction());
241 if (!addressEndpointOptional.isPresent()) {
242 LOG.debug("Child AddressEndpoint {} does not exist in RPC and DS.", childEndpoint);
243 return buildFailFeature(
244 String.format("Child AddressEndpoint %s does not exist in RPC and DS.", childEndpoint));
248 if (!containmentEndpointReg.getKey().equals(new ContainmentEndpointRegKey(
249 addressEndpointRegChild.getContextId(), addressEndpointRegChild.getContextType()))) {
251 "Child AddressEndpoint {} in ContainmentEndpoint->ChildEndpoints does not contain a valid ContainmentEndpointRegKey.",
252 addressEndpointRegChild);
253 return buildFailFeature(String
254 .format("AddressEndpoint in ContainmentEndpoint->ChildEndpoints does not contain a valid ContainmentEndpointRegKey."
255 + "\nChild element: %s", addressEndpointRegChild));
263 private ListenableFuture<RpcResult<Void>> verifyAddressEndpointParents(List<AddressEndpointReg> addressEndpointRegs,
264 AddressEndpointReg addressEndpointReg) {
265 ParentEndpointChoice parentEndpointChoice = addressEndpointReg.getParentEndpointChoice();
266 List<ParentEndpoint> parentEndpoints;
268 (parentEndpointChoice instanceof ParentEndpointCase) ? ((ParentEndpointCase) parentEndpointChoice)
269 .getParentEndpoint() : null;
271 for (ParentEndpoint parentEndpoint : nullToEmpty(parentEndpoints)) {
272 AddressEndpointRegKey key = new AddressEndpointRegKey(parentEndpoint.getAddress(),
273 parentEndpoint.getAddressType(), parentEndpoint.getContextId(), parentEndpoint.getContextType());
274 AddressEndpointReg addressEndpointRegParent = findAddressEndpointReg(key, addressEndpointRegs);
276 if (addressEndpointRegParent == null) {
277 // todo this can be optimized if we move this to updateAddressEndpointRegParents and
278 // verify child in one step with update.
279 Optional<AddressEndpoint> addressEndpointOptional =
280 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
281 IidFactory.addressEndpointIid(new AddressEndpointKey(key.getAddress(),
282 key.getAddressType(), key.getContextId(), key.getContextType())),
283 dataProvider.newReadOnlyTransaction());
284 if (!addressEndpointOptional.isPresent()) {
285 LOG.debug("Parent AddressEndpoint {} does not exist in RPC and DS.", parentEndpoint);
286 return buildFailFeature(
287 String.format("Parent AddressEndpoint %s does not exist in RPC and DS.", parentEndpoint));
291 List<ChildEndpoint> childEndpoints = addressEndpointRegParent.getChildEndpoint();
293 if (!nullToEmpty(childEndpoints).contains(new ChildEndpointBuilder(addressEndpointReg).build())) {
294 LOG.debug("Parent AddressEndpoint {} does not contain a valid child AddressEndpoint.",
295 addressEndpointRegParent);
296 return buildFailFeature(String.format(
297 "Parent AddressEndpoint does not contain a valid child AddressEndpoint."
298 + "\nParent AddressEndpoint: %s" + "\nChild AddressEndpoint: %s",
299 addressEndpointRegParent, addressEndpointReg));
306 private ListenableFuture<RpcResult<Void>> verifyAddressEndpointChilds(List<AddressEndpointReg> addressEndpointRegs,
307 AddressEndpointReg addressEndpointReg) {
308 for (ChildEndpoint childEndpoint : nullToEmpty(addressEndpointReg.getChildEndpoint())) {
309 AddressEndpointRegKey key = new AddressEndpointRegKey(childEndpoint.getAddress(),
310 childEndpoint.getAddressType(), childEndpoint.getContextId(), childEndpoint.getContextType());
311 AddressEndpointReg addressEndpointRegChild = findAddressEndpointReg(key, addressEndpointRegs);
312 if (addressEndpointRegChild == null) {
313 // todo this can be optimized if we move this to updateAddressEndpointRegChilds and
314 // verify child in one step with update.
315 Optional<AddressEndpoint> addressEndpointOptional =
316 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
317 IidFactory.addressEndpointIid(new AddressEndpointKey(key.getAddress(),
318 key.getAddressType(), key.getContextId(), key.getContextType())),
319 dataProvider.newReadOnlyTransaction());
320 if (!addressEndpointOptional.isPresent()) {
321 LOG.debug("Child AddressEndpoint {} does not exist in RPC and DS.", childEndpoint);
322 return buildFailFeature(
323 String.format("Child AddressEndpoint %s does not exist in RPC and DS.", childEndpoint));
327 ParentEndpointChoice parentEndpointChoice = addressEndpointRegChild.getParentEndpointChoice();
329 if (!(parentEndpointChoice instanceof ParentEndpointCase)) {
330 LOG.debug("Child AddressEndpoint {} does not contain list of parent elements.", childEndpoint);
331 return buildFailFeature(String.format(
332 "Child AddressEndpoint does not contain list of parent elements." + "\nChild element: %s",
336 List<ParentEndpoint> parentEndpoints =
337 nullToEmpty(((ParentEndpointCase) parentEndpointChoice).getParentEndpoint());
338 if (!parentEndpoints.contains(new ParentEndpointBuilder(addressEndpointReg).build())) {
339 LOG.debug("Child AddressEndpoint {} does not contain a valid parent AddressEndpoint.",
340 addressEndpointRegChild);
341 return buildFailFeature(String.format(
342 "Child AddressEndpoint does not contain a valid parent AddressEndpoint."
343 + "\nChild element: %s" + "\nparent AddressEndpoint: %s",
344 addressEndpointRegChild, addressEndpointReg));
351 private AddressEndpointReg findAddressEndpointReg(AddressEndpointRegKey key, List<AddressEndpointReg> addressEndpointRegs) {
352 for (AddressEndpointReg addressEndpointReg : addressEndpointRegs) {
353 if (addressEndpointReg.getKey().equals(key)) {
354 return addressEndpointReg;
360 private void updateAddressEndpointRegParents(WriteTransaction t, AddressEndpoint endpoint) {
361 ParentEndpointCase parentEndpointCase = (ParentEndpointCase) endpoint.getParentEndpointChoice();
362 List<ParentEndpoint> parentEndpoints;
363 ReadOnlyTransaction readTransaction = dataProvider.newReadOnlyTransaction();
365 parentEndpoints = getParentEndpoints(parentEndpointCase);
367 for (ParentEndpoint parent : nullToEmpty(parentEndpoints)) {
368 Optional<AddressEndpoint> addressEndpointOptional =
369 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
370 IidFactory.addressEndpointIid(new AddressEndpointKey(parent.getAddress(),
371 parent.getAddressType(), parent.getContextId(), parent.getContextType())),
374 if (addressEndpointOptional.isPresent()) {
376 List<ChildEndpoint> childEndpoints;
378 childEndpoints = (addressEndpointOptional.get() == null || addressEndpointOptional.get()
379 .getChildEndpoint() == null) ? new ArrayList<>() : addressEndpointOptional.get().getChildEndpoint();
381 ChildEndpoint childEndpoint = new ChildEndpointBuilder(endpoint).build();
382 if (!childEndpoints.contains(childEndpoint)) {
383 childEndpoints.add(childEndpoint);
384 AddressEndpoint parentAddressEndpoint = new AddressEndpointBuilder(addressEndpointOptional.get())
385 .setChildEndpoint(childEndpoints).build();
386 t.put(LogicalDatastoreType.OPERATIONAL,
387 IidFactory.addressEndpointIid(parentAddressEndpoint.getKey()), parentAddressEndpoint);
393 private void updateAddressEndpointRegChilds(WriteTransaction t, AddressEndpoint endpoint) {
394 ReadTransaction readTransaction = dataProvider.newReadOnlyTransaction();
396 for (ChildEndpoint child : nullToEmpty(endpoint.getChildEndpoint())) {
397 Optional<AddressEndpoint> addressEndpointOptional =
398 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
399 IidFactory.addressEndpointIid(new AddressEndpointKey(child.getAddress(),
400 child.getAddressType(), child.getContextId(), child.getContextType())),
403 if (addressEndpointOptional.isPresent()) {
404 ParentEndpointCase parentEndpointCase =
405 (ParentEndpointCase) addressEndpointOptional.get().getParentEndpointChoice();
406 List<ParentEndpoint> parentEndpoints;
408 parentEndpoints = getParentEndpoints(parentEndpointCase);
410 ParentEndpoint parentEndpoint = new ParentEndpointBuilder(endpoint).build();
411 if (!parentEndpoints.contains(parentEndpoint)) {
412 parentEndpoints.add(parentEndpoint);
413 AddressEndpoint childAddressEndpoint =
414 new AddressEndpointBuilder(addressEndpointOptional.get())
415 .setParentEndpointChoice(
416 new ParentEndpointCaseBuilder().setParentEndpoint(parentEndpoints).build())
418 t.put(LogicalDatastoreType.OPERATIONAL,
419 IidFactory.addressEndpointIid(childAddressEndpoint.getKey()), childAddressEndpoint);
425 private ContainmentEndpointBuilder buildContainmentEndpoint(ContainmentEndpointReg input) {
427 ContainmentEndpointBuilder eb = new ContainmentEndpointBuilder().setChildEndpoint(input.getChildEndpoint())
428 .setCondition(input.getCondition())
429 .setContextType(input.getContextType())
430 .setContextId(input.getContextId())
431 .setEndpointGroup(input.getEndpointGroup())
432 .setKey(new ContainmentEndpointKey(input.getContextId(), input.getContextType()))
433 .setNetworkContainment(input.getNetworkContainment())
434 .setTenant(input.getTenant())
435 .setTimestamp(input.getTimestamp())
436 .setChildEndpoint(input.getChildEndpoint());
438 for (Map.Entry<String, BaseEndpointRendererAugmentation> entry : registeredRenderers.entrySet()) {
440 Map.Entry<Class<? extends Augmentation<ContainmentEndpoint>>, Augmentation<ContainmentEndpoint>> augmentationEntry =
441 entry.getValue().buildContainmentEndpointAugmentation(input);
442 if (augmentationEntry != null) {
443 eb.addAugmentation(augmentationEntry.getKey(), augmentationEntry.getValue());
445 } catch (Exception e) {
446 LOG.warn("AddressEndpoint Augmentation error while processing " + entry.getKey() + ". Reason: ", e);
452 private AddressEndpointBuilder buildAddressEndpoint(AddressEndpointReg ae) {
453 AddressEndpointBuilder builder = new AddressEndpointBuilder().setTenant(ae.getTenant())
454 .setNetworkContainment(ae.getNetworkContainment())
455 .setEndpointGroup(ae.getEndpointGroup())
456 .setAddress(ae.getAddress())
457 .setAddressType(ae.getAddressType())
458 .setChildEndpoint(ae.getChildEndpoint())
459 .setCondition(ae.getCondition())
460 .setKey(new AddressEndpointKey(ae.getAddress(), ae.getAddressType(), ae.getContextId(),
461 ae.getContextType()))
462 .setParentEndpointChoice(ae.getParentEndpointChoice())
463 .setTimestamp(ae.getTimestamp())
464 .setContextId(ae.getContextId())
465 .setContextType(ae.getContextType())
466 .setTenant(ae.getTenant());
468 for (Map.Entry<String, BaseEndpointRendererAugmentation> entry : registeredRenderers.entrySet()) {
470 Map.Entry<Class<? extends Augmentation<AddressEndpoint>>, Augmentation<AddressEndpoint>> augmentationEntry =
471 entry.getValue().buildAddressEndpointAugmentation(ae);
472 if (augmentationEntry != null) {
473 builder.addAugmentation(augmentationEntry.getKey(), augmentationEntry.getValue());
475 } catch (Exception e) {
476 LOG.warn("AddressEndpoint Augmentation error while processing " + entry.getKey() + ". Reason: ", e);
483 * Unregister an endpoint or endpoints from the registry.
485 * @param input Endpoint/endpoints to unregister
488 public Future<RpcResult<Void>> unregisterEndpoint(UnregisterEndpointInput input) {
489 WriteTransaction t = dataProvider.newWriteOnlyTransaction();
491 List<AddressEndpointUnreg> addressEndpoints = input.getAddressEndpointUnreg();
492 for (AddressEndpointUnreg ae : nullToEmpty(addressEndpoints)) {
493 AddressEndpointKey key = new AddressEndpointKey(ae.getAddress(), ae.getAddressType(), ae.getContextId(),
494 ae.getContextType());
495 t.delete(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(key));
497 updateAddressEndpointUnregChilds(t, ae);
499 updateAddressEndpointUnregParents(t, ae);
502 List<ContainmentEndpointUnreg> endpoints = input.getContainmentEndpointUnreg();
503 for (ContainmentEndpointUnreg ce : nullToEmpty(endpoints)) {
504 ContainmentEndpointKey key = new ContainmentEndpointKey(ce.getContextId(), ce.getContextType());
505 t.delete(LogicalDatastoreType.OPERATIONAL, IidFactory.containmentEndpointIid(key));
507 updateContainmentEndpointUnregChilds(t, ce);
510 ListenableFuture<Void> r = t.submit();
511 return Futures.transform(r, futureTrans);
514 private void updateAddressEndpointUnregParents(WriteTransaction t, AddressEndpointUnreg ae) {
515 ReadTransaction readTransaction = dataProvider.newReadOnlyTransaction();
517 Optional<AddressEndpoint> addressEndpointOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
518 IidFactory.addressEndpointIid(new AddressEndpointKey(ae.getAddress(), ae.getAddressType(),
519 ae.getContextId(), ae.getContextType())),
522 if (addressEndpointOptional.isPresent()) {
523 ParentEndpointCase parentEndpointCase =
524 (ParentEndpointCase) addressEndpointOptional.get().getParentEndpointChoice();
525 List<ParentEndpoint> parentEndpoints;
527 parentEndpoints = getParentEndpoints(parentEndpointCase);
529 for (ParentEndpoint parentEndpoint : parentEndpoints) {
530 Optional<AddressEndpoint> parentAddressEndpointOptional =
531 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
532 IidFactory.addressEndpointIid(new AddressEndpointKey(parentEndpoint.getAddress(),
533 parentEndpoint.getAddressType(), parentEndpoint.getContextId(),
534 parentEndpoint.getContextType())),
537 AddressEndpoint parent =
538 parentAddressEndpointOptional.isPresent() ? parentAddressEndpointOptional.get() : null;
540 ChildEndpoint endpointToRemove = new ChildEndpointBuilder(addressEndpointOptional.get()).build();
542 if (parent != null && nullToEmpty(parent.getChildEndpoint()).contains(endpointToRemove)) {
543 parent.getChildEndpoint().remove(endpointToRemove);
544 t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(parent.getKey()), parent);
551 private void updateAddressEndpointUnregChilds(WriteTransaction t, AddressEndpointUnreg ae) {
552 ReadTransaction readTransaction = dataProvider.newReadOnlyTransaction();
554 Optional<AddressEndpoint> addressEndpointOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
555 IidFactory.addressEndpointIid(new AddressEndpointKey(ae.getAddress(), ae.getAddressType(),
556 ae.getContextId(), ae.getContextType())),
559 if (addressEndpointOptional.isPresent()) {
560 AddressEndpoint endpoint = addressEndpointOptional.get();
561 List<ChildEndpoint> childEndpoints = endpoint.getChildEndpoint();
563 for (ChildEndpoint childEndpoint : nullToEmpty(childEndpoints)) {
564 Optional<AddressEndpoint> childAddressEndpointOptional =
565 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
566 IidFactory.addressEndpointIid(new AddressEndpointKey(childEndpoint.getAddress(),
567 childEndpoint.getAddressType(), childEndpoint.getContextId(),
568 childEndpoint.getContextType())),
571 AddressEndpoint child =
572 childAddressEndpointOptional.isPresent() ? childAddressEndpointOptional.get() : null;
573 ParentEndpointCase parentEndpointCase =
574 (child != null) ? (ParentEndpointCase) child.getParentEndpointChoice() : null;
575 List<ParentEndpoint> parentEndpoints;
577 parentEndpoints = getParentEndpoints(parentEndpointCase);
579 ParentEndpoint endpointToRemove = new ParentEndpointBuilder(endpoint).build();
581 if (child != null && nullToEmpty(parentEndpoints).contains(endpointToRemove)) {
582 parentEndpoints.remove(endpointToRemove);
583 AddressEndpoint newChild =
584 new AddressEndpointBuilder(child)
585 .setParentEndpointChoice(
586 new ParentEndpointCaseBuilder().setParentEndpoint(parentEndpoints).build())
589 t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(newChild.getKey()), newChild);
595 private void updateContainmentEndpointUnregChilds(WriteTransaction t,
596 ContainmentEndpointUnreg containmentEndpointUnreg) {
597 ReadOnlyTransaction readTransaction = dataProvider.newReadOnlyTransaction();
599 ContainmentEndpointKey key = new ContainmentEndpointKey(containmentEndpointUnreg.getContextId(),
600 containmentEndpointUnreg.getContextType());
601 Optional<ContainmentEndpoint> containmentEndpointOptional = DataStoreHelper
602 .readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.containmentEndpointIid(key), readTransaction);
604 if (!containmentEndpointOptional.isPresent()) {
608 for (ChildEndpoint child : nullToEmpty(containmentEndpointOptional.get().getChildEndpoint())) {
609 AddressEndpointKey aeKey = new AddressEndpointKey(child.getAddress(), child.getAddressType(),
610 child.getContextId(), child.getContextType());
611 Optional<AddressEndpoint> addressEndpointOptional = DataStoreHelper
612 .readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(aeKey), readTransaction);
614 if (addressEndpointOptional.isPresent()) {
615 ParentEndpointChoice parentEndpointChoice = addressEndpointOptional.get().getParentEndpointChoice();
616 List<ParentContainmentEndpoint> parentContainmentEndpoints;
617 parentContainmentEndpoints = getParentContainmentEndpoints(parentEndpointChoice);
619 ParentContainmentEndpoint parentContainmentEndpoint =
620 new ParentContainmentEndpointBuilder().setContextId(containmentEndpointUnreg.getContextId())
621 .setContextType(containmentEndpointUnreg.getContextType())
623 if (nullToEmpty(parentContainmentEndpoints).contains(parentContainmentEndpoint)) {
624 t.delete(LogicalDatastoreType.OPERATIONAL,
625 IidFactory.parentContainmentEndpointIid(aeKey, parentContainmentEndpoint.getKey()));
631 private List<ParentContainmentEndpoint> getParentContainmentEndpoints(ParentEndpointChoice parentEndpointChoice) {
632 return (parentEndpointChoice instanceof ParentContainmentEndpointCase) ? ((ParentContainmentEndpointCase) parentEndpointChoice)
633 .getParentContainmentEndpoint() : new ArrayList<>();
636 private List<ParentEndpoint> getParentEndpoints(ParentEndpointCase parentEndpointCase) {
637 return (parentEndpointCase == null
638 || parentEndpointCase.getParentEndpoint() == null) ? new ArrayList<>() : parentEndpointCase
639 .getParentEndpoint();
642 private ListenableFuture<RpcResult<Void>> buildFailFeature(String message) {
644 .immediateFuture(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.PROTOCOL, message).build());
648 public void close() throws Exception {
649 if (rpcRegistration != null) {
650 rpcRegistration.close();
654 private <T> List<T> nullToEmpty(@Nullable List<T> list) {
655 return list == null ? Collections.emptyList() : list;