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.util.concurrent.CheckedFuture;
13 import com.google.common.util.concurrent.FutureCallback;
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.WriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
20 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
21 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
22 import org.opendaylight.groupbasedpolicy.api.BaseEndpointRendererAugmentation;
23 import org.opendaylight.groupbasedpolicy.api.BaseEndpointRendererAugmentationRegistry;
24 import org.opendaylight.groupbasedpolicy.util.IidFactory;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.*;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnreg;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.ContainmentEndpointUnreg;
36 import org.opendaylight.yangtools.yang.binding.Augmentation;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.opendaylight.yangtools.yang.common.RpcResult;
39 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 import javax.annotation.Nullable;
44 import java.util.Collections;
45 import java.util.List;
47 import java.util.concurrent.ConcurrentHashMap;
48 import java.util.concurrent.ConcurrentMap;
49 import java.util.concurrent.Future;
51 public class BaseEndpointRpcRegistry
52 implements BaseEndpointService, BaseEndpointRendererAugmentationRegistry, AutoCloseable {
54 static final ConcurrentMap<String, BaseEndpointRendererAugmentation> registeredRenderers = new ConcurrentHashMap<>();
55 private static final Logger LOG = LoggerFactory.getLogger(BaseEndpointRpcRegistry.class);
56 private final DataBroker dataProvider;
57 private final BindingAwareBroker.RpcRegistration<BaseEndpointService> rpcRegistration;
59 private Function<Void, RpcResult<Void>> futureTrans = new Function<Void, RpcResult<Void>>() {
62 public RpcResult<Void> apply(Void input) {
63 return RpcResultBuilder.<Void>success().build();
67 public BaseEndpointRpcRegistry(DataBroker dataProvider, RpcProviderRegistry rpcRegistry) {
68 this.dataProvider = dataProvider;
70 if (rpcRegistry != null) {
71 rpcRegistration = rpcRegistry.addRpcImplementation(BaseEndpointService.class, this);
72 LOG.debug("Added Endpoints RPC Implementation Correctly");
74 rpcRegistration = null;
77 if (dataProvider != null) {
78 InstanceIdentifier<Endpoints> iid = InstanceIdentifier.builder(Endpoints.class).build();
79 WriteTransaction t = this.dataProvider.newWriteOnlyTransaction();
80 t.put(LogicalDatastoreType.OPERATIONAL, iid, new EndpointsBuilder().build());
81 CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();
82 Futures.addCallback(f, new FutureCallback<Void>() {
85 public void onFailure(Throwable t) {
86 LOG.error("Could not write Endpoints base container", t);
90 public void onSuccess(Void result) {
91 LOG.info("Endpoints container write successful");
98 * Registers renderer's endpoints augmentation.
100 * @param baseEndpointRendererAugmentation cannot be {@code null}
101 * @throws NullPointerException
104 public void register(BaseEndpointRendererAugmentation baseEndpointRendererAugmentation) {
105 if (baseEndpointRendererAugmentation != null) {
106 registeredRenderers.putIfAbsent(baseEndpointRendererAugmentation.getClass().getName(),
107 baseEndpointRendererAugmentation);
108 LOG.info("Registered {}", baseEndpointRendererAugmentation.getClass().getName());
113 * Unregisters renderer's endpoints augmentation.
115 * @param baseEndpointRendererAugmentation cannot be {@code null}
116 * @throws NullPointerException
119 public void unregister(BaseEndpointRendererAugmentation baseEndpointRendererAugmentation) {
120 if (baseEndpointRendererAugmentation == null
121 || !registeredRenderers.containsKey(baseEndpointRendererAugmentation.getClass().getName())) {
124 registeredRenderers.remove(baseEndpointRendererAugmentation.getClass().getName());
125 LOG.info("Unregistered {}", baseEndpointRendererAugmentation.getClass().getName());
129 * Register a new endpoint into the registry. If there is already an existing
130 * endpoint with the same keys, they will be overwritten with the new information.
132 * @param input Endpoint to register
135 public Future<RpcResult<Void>> registerEndpoint(RegisterEndpointInput input) {
136 long timestamp = System.currentTimeMillis();
138 WriteTransaction t = dataProvider.newWriteOnlyTransaction();
140 List<ContainmentEndpointReg> endpoints = input.getContainmentEndpointReg();
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,
148 List<AddressEndpointReg> addressEndpoints = input.getAddressEndpointReg();
149 for (AddressEndpointReg ae : nullToEmpty(addressEndpoints)) {
150 long stamp = (ae.getTimestamp() == null || ae.getTimestamp() == 0) ? timestamp : ae.getTimestamp();
151 AddressEndpoint endpoint = buildAddressEndpoint(ae).setTimestamp(stamp).build();
152 t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(endpoint.getKey()), endpoint, true);
155 ListenableFuture<Void> r = t.submit();
156 return Futures.transform(r, futureTrans);
159 private ContainmentEndpointBuilder buildContainmentEndpoint(ContainmentEndpointReg input) {
160 ContainmentEndpointBuilder eb = new ContainmentEndpointBuilder().setChildEndpoint(input.getChildEndpoint())
161 .setCondition(input.getCondition())
162 .setContextType(input.getContextType())
163 .setContextId(input.getContextId())
164 .setEndpointGroup(input.getEndpointGroup())
165 .setKey(new ContainmentEndpointKey(input.getContextId(), input.getContextType()))
166 .setNetworkContainment(input.getNetworkContainment())
167 .setTenant(input.getTenant())
168 .setTimestamp(input.getTimestamp());
170 for (Map.Entry<String, BaseEndpointRendererAugmentation> entry : registeredRenderers.entrySet()) {
172 Map.Entry<Class<? extends Augmentation<ContainmentEndpoint>>, Augmentation<ContainmentEndpoint>> augmentationEntry =
173 entry.getValue().buildContainmentEndpointAugmentation(input);
174 if (augmentationEntry != null) {
175 eb.addAugmentation(augmentationEntry.getKey(), augmentationEntry.getValue());
177 } catch (Exception e) {
178 LOG.warn("AddressEndpoint Augmentation error while processing " + entry.getKey() + ". Reason: ", e);
184 private AddressEndpointBuilder buildAddressEndpoint(AddressEndpointReg ae) {
185 AddressEndpointBuilder builder = new AddressEndpointBuilder().setTenant(ae.getTenant())
186 .setNetworkContainment(ae.getNetworkContainment())
187 .setEndpointGroup(ae.getEndpointGroup())
188 .setAddress(ae.getAddress())
189 .setAddressType(ae.getAddressType())
190 .setChildEndpoint(ae.getChildEndpoint())
191 .setCondition(ae.getCondition())
192 .setKey(new AddressEndpointKey(ae.getAddress(), ae.getAddressType(), ae.getContextId(),
193 ae.getContextType()))
194 .setParentEndpointChoice(ae.getParentEndpointChoice())
195 .setTimestamp(ae.getTimestamp())
196 .setContextId(ae.getContextId())
197 .setContextType(ae.getContextType())
198 .setTenant(ae.getTenant());
200 for (Map.Entry<String, BaseEndpointRendererAugmentation> entry : registeredRenderers.entrySet()) {
202 Map.Entry<Class<? extends Augmentation<AddressEndpoint>>, Augmentation<AddressEndpoint>> augmentationEntry =
203 entry.getValue().buildAddressEndpointAugmentation(ae);
204 if (augmentationEntry != null) {
205 builder.addAugmentation(augmentationEntry.getKey(), augmentationEntry.getValue());
207 } catch (Exception e) {
208 LOG.warn("AddressEndpoint Augmentation error while processing " + entry.getKey() + ". Reason: ", e);
215 * Unregister an endpoint or endpoints from the registry.
217 * @param input Endpoint/endpoints to unregister
220 public Future<RpcResult<Void>> unregisterEndpoint(UnregisterEndpointInput input) {
221 WriteTransaction t = dataProvider.newWriteOnlyTransaction();
223 List<AddressEndpointUnreg> addressEndpoints = input.getAddressEndpointUnreg();
224 for (AddressEndpointUnreg ae : nullToEmpty(addressEndpoints)) {
225 AddressEndpointKey key = new AddressEndpointKey(ae.getAddress(), ae.getAddressType(), ae.getContextId(),
226 ae.getContextType());
227 t.delete(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(key));
230 List<ContainmentEndpointUnreg> endpoints = input.getContainmentEndpointUnreg();
231 for (ContainmentEndpointUnreg ce : nullToEmpty(endpoints)) {
232 ContainmentEndpointKey key = new ContainmentEndpointKey(ce.getContextId(), ce.getContextType());
233 t.delete(LogicalDatastoreType.OPERATIONAL, IidFactory.containmentEndpointIid(key));
236 ListenableFuture<Void> r = t.submit();
237 return Futures.transform(r, futureTrans);
241 public void close() throws Exception {
242 if (rpcRegistration != null) {
243 rpcRegistration.close();
247 private <T> List<T> nullToEmpty(@Nullable List<T> list) {
248 return list == null ? Collections.emptyList() : list;