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 java.util.Collections;
12 import java.util.List;
14 import java.util.concurrent.Future;
16 import javax.annotation.Nullable;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.groupbasedpolicy.api.EndpointAugmentor;
22 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
23 import org.opendaylight.groupbasedpolicy.util.EndpointUtils;
24 import org.opendaylight.groupbasedpolicy.util.IidFactory;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.ParentEndpointChoice;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpoint;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpointBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpointKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpointBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpointKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnreg;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.ContainmentEndpointUnreg;
48 import org.opendaylight.yangtools.yang.binding.Augmentation;
49 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
50 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
51 import org.opendaylight.yangtools.yang.common.RpcResult;
52 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
56 import com.google.common.base.Function;
57 import com.google.common.base.Optional;
58 import com.google.common.base.Preconditions;
59 import com.google.common.util.concurrent.Futures;
60 import com.google.common.util.concurrent.ListenableFuture;
61 import com.google.common.util.concurrent.MoreExecutors;
63 public class BaseEndpointServiceImpl implements BaseEndpointService, AutoCloseable {
65 private static final Logger LOG = LoggerFactory.getLogger(BaseEndpointServiceImpl.class);
66 private final DataBroker dataProvider;
67 private final EndpointAugmentorRegistryImpl epAugRegistry;
69 private static final Function<Void, RpcResult<Void>> TO_SUCCESS_RPC_RESULT =
70 input -> RpcResultBuilder.<Void>success().build();
72 public BaseEndpointServiceImpl(DataBroker dataProvider, EndpointAugmentorRegistryImpl epAugRegistry) {
73 this.epAugRegistry = Preconditions.checkNotNull(epAugRegistry);
74 this.dataProvider = Preconditions.checkNotNull(dataProvider);
78 * Register a new endpoint into the registry. If there is already an existing
79 * endpoint with the same keys, they will be overwritten with the new information.
81 * @param input Endpoint to register
84 public Future<RpcResult<Void>> registerEndpoint(RegisterEndpointInput input) {
85 long timestamp = System.currentTimeMillis();
87 ReadWriteTransaction t = dataProvider.newReadWriteTransaction();
89 ListenableFuture<RpcResult<Void>> failResult =
90 RegisterEndpointInputVerificator.verifyRegisterEndpointInput(input, t);
91 if (failResult != null) {
96 List<ContainmentEndpointReg> endpoints = input.getContainmentEndpointReg();
97 for (ContainmentEndpointReg ce : nullToEmpty(endpoints)) {
98 long stamp = (ce.getTimestamp() == null || ce.getTimestamp() == 0) ? timestamp : ce.getTimestamp();
99 ContainmentEndpoint endpoint = buildContainmentEndpoint(ce).setTimestamp(stamp).build();
100 t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.containmentEndpointIid(endpoint.getKey()), endpoint,
102 addContainmentEndpointToChilds(t, endpoint);
105 List<AddressEndpointReg> addressEndpoints = input.getAddressEndpointReg();
106 for (AddressEndpointReg ae : nullToEmpty(addressEndpoints)) {
107 long stamp = (ae.getTimestamp() == null || ae.getTimestamp() == 0) ? timestamp : ae.getTimestamp();
108 AddressEndpoint endpoint = buildAddressEndpoint(ae).setTimestamp(stamp).build();
109 t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(endpoint.getKey()), endpoint, true);
110 addAddressEndpointToChilds(t, endpoint);
111 addAddressEndpointToParents(t, endpoint);
114 return Futures.transform(t.submit(), TO_SUCCESS_RPC_RESULT, MoreExecutors.directExecutor());
117 private void addContainmentEndpointToChilds(ReadWriteTransaction t, ContainmentEndpoint endpoint) {
118 ParentContainmentEndpoint epAsParent = new ParentContainmentEndpointBuilder(endpoint).build();
119 for (ChildEndpoint child : nullToEmpty(endpoint.getChildEndpoint())) {
120 InstanceIdentifier<AddressEndpoint> childIid =
121 IidFactory.addressEndpointIid(EndpointUtils.createAddressEndpointKey(child));
122 Optional<AddressEndpoint> childAddrEpOptional =
123 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, childIid, t);
124 if (childAddrEpOptional.isPresent()) {
125 KeyedInstanceIdentifier<ParentContainmentEndpoint, ParentContainmentEndpointKey> parentInChildIid =
126 childIid.child(ParentContainmentEndpoint.class, epAsParent.getKey());
127 t.put(LogicalDatastoreType.OPERATIONAL, parentInChildIid, epAsParent, true);
132 private void addAddressEndpointToChilds(ReadWriteTransaction t, AddressEndpoint endpoint) {
133 ParentEndpoint epAsParent = new ParentEndpointBuilder(endpoint).build();
134 for (ChildEndpoint child : nullToEmpty(endpoint.getChildEndpoint())) {
135 InstanceIdentifier<AddressEndpoint> childIid =
136 IidFactory.addressEndpointIid(EndpointUtils.createAddressEndpointKey(child));
137 Optional<AddressEndpoint> childAddrEpOptional =
138 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, childIid, t);
139 if (childAddrEpOptional.isPresent()) {
140 KeyedInstanceIdentifier<ParentEndpoint, ParentEndpointKey> parentInChildIid =
141 childIid.child(ParentEndpoint.class, epAsParent.getKey());
142 t.put(LogicalDatastoreType.OPERATIONAL, parentInChildIid, epAsParent, true);
147 private void addAddressEndpointToParents(ReadWriteTransaction t, AddressEndpoint endpoint) {
148 ChildEndpoint epAsChild = new ChildEndpointBuilder(endpoint).build();
149 for (ParentEndpoint parent : EndpointUtils.getParentEndpoints(endpoint.getParentEndpointChoice())) {
150 InstanceIdentifier<AddressEndpoint> parentIid =
151 IidFactory.addressEndpointIid(EndpointUtils.createAddressEndpointKey(parent));
152 Optional<AddressEndpoint> parentAddrEpOptional =
153 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, parentIid, t);
154 if (parentAddrEpOptional.isPresent()) {
155 KeyedInstanceIdentifier<ChildEndpoint, ChildEndpointKey> childInParentIid =
156 parentIid.child(ChildEndpoint.class, epAsChild.getKey());
157 t.put(LogicalDatastoreType.OPERATIONAL, childInParentIid, epAsChild, true);
160 for (ParentContainmentEndpoint parent : EndpointUtils.getParentContainmentEndpoints(endpoint.getParentEndpointChoice())) {
161 InstanceIdentifier<ContainmentEndpoint> parentIid = IidFactory
162 .containmentEndpointIid(new ContainmentEndpointKey(parent.getContextId(), parent.getContextType()));
163 Optional<ContainmentEndpoint> parentContEpOptional =
164 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, parentIid, t);
165 if (parentContEpOptional.isPresent()) {
166 KeyedInstanceIdentifier<ChildEndpoint, ChildEndpointKey> childInParentIid =
167 parentIid.child(ChildEndpoint.class, epAsChild.getKey());
168 t.put(LogicalDatastoreType.OPERATIONAL, childInParentIid, epAsChild, true);
173 private ContainmentEndpointBuilder buildContainmentEndpoint(ContainmentEndpointReg input) {
175 ContainmentEndpointBuilder eb = new ContainmentEndpointBuilder().setChildEndpoint(input.getChildEndpoint())
176 .setCondition(input.getCondition())
177 .setContextType(input.getContextType())
178 .setContextId(input.getContextId())
179 .setEndpointGroup(input.getEndpointGroup())
180 .setKey(new ContainmentEndpointKey(input.getContextId(), input.getContextType()))
181 .setNetworkContainment(input.getNetworkContainment())
182 .setTenant(input.getTenant())
183 .setTimestamp(input.getTimestamp())
184 .setChildEndpoint(input.getChildEndpoint());
186 for (EndpointAugmentor epAugmentor : epAugRegistry.getEndpointAugmentors()) {
188 Map.Entry<Class<? extends Augmentation<ContainmentEndpoint>>, Augmentation<ContainmentEndpoint>> augmentationEntry =
189 epAugmentor.buildContainmentEndpointAugmentation(input);
190 if (augmentationEntry != null) {
191 eb.addAugmentation(augmentationEntry.getKey(), augmentationEntry.getValue());
193 } catch (Exception e) {
194 LOG.warn("AddressEndpoint Augmentation error while {} was processing {}",
195 epAugmentor.getClass().getSimpleName(), input, e);
201 private AddressEndpointBuilder buildAddressEndpoint(AddressEndpointReg ae) {
202 AddressEndpointBuilder builder = new AddressEndpointBuilder().setTenant(ae.getTenant())
203 .setNetworkContainment(ae.getNetworkContainment())
204 .setEndpointGroup(ae.getEndpointGroup())
205 .setAddress(ae.getAddress())
206 .setAddressType(ae.getAddressType())
207 .setChildEndpoint(ae.getChildEndpoint())
208 .setCondition(ae.getCondition())
209 .setKey(new AddressEndpointKey(ae.getAddress(), ae.getAddressType(), ae.getContextId(),
210 ae.getContextType()))
211 .setParentEndpointChoice(ae.getParentEndpointChoice())
212 .setTimestamp(ae.getTimestamp())
213 .setContextId(ae.getContextId())
214 .setContextType(ae.getContextType())
215 .setTenant(ae.getTenant());
217 for (EndpointAugmentor epAugmentor : epAugRegistry.getEndpointAugmentors()) {
219 Map.Entry<Class<? extends Augmentation<AddressEndpoint>>, Augmentation<AddressEndpoint>> augmentationEntry =
220 epAugmentor.buildAddressEndpointAugmentation(ae);
221 if (augmentationEntry != null) {
222 builder.addAugmentation(augmentationEntry.getKey(), augmentationEntry.getValue());
224 } catch (Exception e) {
225 LOG.warn("AddressEndpoint Augmentation error while {} was processing {}",
226 epAugmentor.getClass().getSimpleName(), ae, e);
233 * Unregister an endpoint or endpoints from the registry.
235 * @param input Endpoint/endpoints to unregister
238 public Future<RpcResult<Void>> unregisterEndpoint(UnregisterEndpointInput input) {
239 ReadWriteTransaction t = dataProvider.newReadWriteTransaction();
241 List<AddressEndpointUnreg> addrEndpoints = input.getAddressEndpointUnreg();
242 for (AddressEndpointUnreg aeUnreg : nullToEmpty(addrEndpoints)) {
243 AddressEndpointKey key = new AddressEndpointKey(aeUnreg.getAddress(), aeUnreg.getAddressType(),
244 aeUnreg.getContextId(), aeUnreg.getContextType());
245 Optional<AddressEndpoint> aeOptional = DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
246 IidFactory.addressEndpointIid(key), t);
247 if (aeOptional.isPresent()) {
248 deleteAddressEndpointFromParents(t, aeOptional.get());
249 deleteAddressEndpointFromChilds(t, aeOptional.get());
253 List<ContainmentEndpointUnreg> contEndpoints = input.getContainmentEndpointUnreg();
254 for (ContainmentEndpointUnreg ceUnreg : nullToEmpty(contEndpoints)) {
255 ContainmentEndpointKey key = new ContainmentEndpointKey(ceUnreg.getContextId(), ceUnreg.getContextType());
256 Optional<ContainmentEndpoint> ceOptional = DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
257 IidFactory.containmentEndpointIid(key), t);
258 if (ceOptional.isPresent()) {
259 deleteContainmentEndpointFromChilds(t, ceOptional.get());
263 ListenableFuture<Void> r = t.submit();
264 return Futures.transform(r, TO_SUCCESS_RPC_RESULT, MoreExecutors.directExecutor());
267 private void deleteAddressEndpointFromParents(ReadWriteTransaction t, AddressEndpoint endpoint) {
268 ParentEndpointChoice parentEndpointChoice = endpoint.getParentEndpointChoice();
269 for (ParentEndpoint parentEndpoint : EndpointUtils.getParentEndpoints(parentEndpointChoice)) {
270 KeyedInstanceIdentifier<ChildEndpoint, ChildEndpointKey> childEp =
271 IidFactory.addressEndpointIid(EndpointUtils.createAddressEndpointKey(parentEndpoint)).child(ChildEndpoint.class,
272 new ChildEndpointKey(endpoint.getAddress(), endpoint.getAddressType(),
273 endpoint.getContextId(), endpoint.getContextType()));
274 DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL, childEp, t);
276 for (ParentContainmentEndpoint parentContEndpoint : EndpointUtils.getParentContainmentEndpoints(parentEndpointChoice)) {
277 KeyedInstanceIdentifier<ChildEndpoint, ChildEndpointKey> childEp = IidFactory
278 .containmentEndpointIid(new ContainmentEndpointKey(parentContEndpoint.getContextId(),
279 parentContEndpoint.getContextType()))
280 .child(ChildEndpoint.class, new ChildEndpointKey(endpoint.getAddress(), endpoint.getAddressType(),
281 endpoint.getContextId(), endpoint.getContextType()));
282 DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL, childEp, t);
286 private void deleteAddressEndpointFromChilds(ReadWriteTransaction t, AddressEndpoint endpoint) {
287 for (ChildEndpoint childEndpoint : nullToEmpty(endpoint.getChildEndpoint())) {
288 KeyedInstanceIdentifier<ParentEndpoint, ParentEndpointKey> parentEp =
289 IidFactory.addressEndpointIid(EndpointUtils.createAddressEndpointKey(childEndpoint)).child(ParentEndpoint.class,
290 new ParentEndpointKey(endpoint.getAddress(), endpoint.getAddressType(),
291 endpoint.getContextId(), endpoint.getContextType()));
292 DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL, parentEp, t);
296 private void deleteContainmentEndpointFromChilds(ReadWriteTransaction t, ContainmentEndpoint endpoint) {
297 for (ChildEndpoint child : nullToEmpty(endpoint.getChildEndpoint())) {
298 AddressEndpointKey aeKey = new AddressEndpointKey(child.getAddress(), child.getAddressType(),
299 child.getContextId(), child.getContextType());
300 KeyedInstanceIdentifier<ParentContainmentEndpoint, ParentContainmentEndpointKey> parentEp =
301 IidFactory.addressEndpointIid(aeKey).child(ParentContainmentEndpoint.class,
302 new ParentContainmentEndpointKey(endpoint.getContextId(), endpoint.getContextType()));
303 DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL, parentEp, t);
308 public void close() {
311 private <T> List<T> nullToEmpty(@Nullable List<T> list) {
312 return list == null ? Collections.emptyList() : list;