Introduced DomainSpecificRegistry service
[groupbasedpolicy.git] / groupbasedpolicy / src / main / java / org / opendaylight / groupbasedpolicy / base_endpoint / RegisterEndpointInputVerificator.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.base_endpoint;
10
11 import java.util.Collections;
12 import java.util.List;
13
14 import javax.annotation.Nullable;
15
16 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
19 import org.opendaylight.groupbasedpolicy.util.EndpointUtils;
20 import org.opendaylight.groupbasedpolicy.util.IidFactory;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.ParentEndpointChoice;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpoint;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpointBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpointBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointRegKey;
37 import org.opendaylight.yangtools.yang.common.RpcError;
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;
42
43 import com.google.common.base.Optional;
44 import com.google.common.util.concurrent.Futures;
45 import com.google.common.util.concurrent.ListenableFuture;
46
47 public class RegisterEndpointInputVerificator {
48
49     private static final Logger LOG = LoggerFactory.getLogger(RegisterEndpointInputVerificator.class);
50
51     public static ListenableFuture<RpcResult<Void>> verifyRegisterEndpointInput(RegisterEndpointInput input,
52             ReadTransaction rTx) {
53         ListenableFuture<RpcResult<Void>> result;
54         List<AddressEndpointReg> addressEndpointRegs = nullToEmpty(input.getAddressEndpointReg());
55         List<ContainmentEndpointReg> containmentEndpointRegs = nullToEmpty(input.getContainmentEndpointReg());
56
57         for (AddressEndpointReg addressEndpointReg : addressEndpointRegs) {
58             result = verifyAddressEndpointChilds(addressEndpointRegs, addressEndpointReg, rTx);
59             if (result != null) {
60                 return result;
61             }
62
63             result = verifyAddressEndpointParents(addressEndpointRegs, containmentEndpointRegs, addressEndpointReg,
64                     rTx);
65             if (result != null) {
66                 return result;
67             }
68         }
69
70         result = verifyContainmentEndpointChilds(addressEndpointRegs, containmentEndpointRegs, rTx);
71         if (result != null) {
72             return result;
73         }
74
75         return null;
76     }
77
78     private static ListenableFuture<RpcResult<Void>> verifyAddressEndpointChilds(
79             List<AddressEndpointReg> addressEndpointRegs, AddressEndpointReg addressEndpointReg, ReadTransaction rTx) {
80         for (ChildEndpoint childEndpoint : nullToEmpty(addressEndpointReg.getChildEndpoint())) {
81             AddressEndpointRegKey key = new AddressEndpointRegKey(childEndpoint.getAddress(),
82                     childEndpoint.getAddressType(), childEndpoint.getContextId(), childEndpoint.getContextType());
83             AddressEndpointReg addressEndpointRegChild = findAddressEndpointReg(key, addressEndpointRegs);
84             if (addressEndpointRegChild == null) {
85                 Optional<AddressEndpoint> addressEndpointOptional =
86                         DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
87                                 IidFactory.addressEndpointIid(new AddressEndpointKey(key.getAddress(),
88                                         key.getAddressType(), key.getContextId(), key.getContextType())),
89                                 rTx);
90                 if (!addressEndpointOptional.isPresent()) {
91                     LOG.debug("Child AddressEndpoint {} does not exist in RPC and DS.", childEndpoint.getKey());
92                     return buildFailFeature(String.format("Child AddressEndpoint %s does not exist in RPC and DS.",
93                             childEndpoint.getKey()));
94                 }
95             } else {
96                 ParentEndpointChoice parentEndpointChoice = addressEndpointRegChild.getParentEndpointChoice();
97                 List<ParentEndpoint> parentEndpoints = EndpointUtils.getParentEndpoints(parentEndpointChoice);
98                 if (!parentEndpoints.contains(new ParentEndpointBuilder(addressEndpointReg).build())) {
99                     LOG.debug("Child AddressEndpoint {} does not contain a parent AddressEndpoint {}.\nChild: {}",
100                             addressEndpointRegChild.getKey(), addressEndpointReg.getKey(), addressEndpointRegChild);
101                     return buildFailFeature(String.format(
102                             "Child AddressEndpoint does not contain a parent AddressEndpoint."
103                                     + "\nChild AddressEndpoint: %s" + "\nParent AddressEndpoint: %s",
104                             addressEndpointRegChild.getKey(), addressEndpointReg.getKey()));
105                 }
106             }
107         }
108         return null;
109     }
110
111     private static ListenableFuture<RpcResult<Void>> verifyAddressEndpointParents(
112             List<AddressEndpointReg> addressEndpointRegs, List<ContainmentEndpointReg> containmentEndpointRegs,
113             AddressEndpointReg addressEndpointReg, ReadTransaction rTx) {
114         ParentEndpointChoice parentEndpointChoice = addressEndpointReg.getParentEndpointChoice();
115         for (ParentEndpoint parentEndpoint : EndpointUtils.getParentEndpoints(parentEndpointChoice)) {
116             AddressEndpointRegKey key = new AddressEndpointRegKey(parentEndpoint.getAddress(),
117                     parentEndpoint.getAddressType(), parentEndpoint.getContextId(), parentEndpoint.getContextType());
118             AddressEndpointReg addressEndpointRegParent = findAddressEndpointReg(key, addressEndpointRegs);
119             if (addressEndpointRegParent == null) {
120                 Optional<AddressEndpoint> addressEndpointOptional =
121                         DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
122                                 IidFactory.addressEndpointIid(new AddressEndpointKey(key.getAddress(),
123                                         key.getAddressType(), key.getContextId(), key.getContextType())),
124                                 rTx);
125                 if (!addressEndpointOptional.isPresent()) {
126                     LOG.debug("Parent AddressEndpoint {} does not exist in RPC and DS.", parentEndpoint.getKey());
127                     return buildFailFeature(String.format("Parent AddressEndpoint %s does not exist in RPC and DS.",
128                             parentEndpoint.getKey()));
129                 }
130             } else {
131                 List<ChildEndpoint> childEndpoints = addressEndpointRegParent.getChildEndpoint();
132                 if (!nullToEmpty(childEndpoints).contains(new ChildEndpointBuilder(addressEndpointReg).build())) {
133                     LOG.debug("Parent AddressEndpoint {} does not contain a child AddressEndpoint {}.\nParent: {}",
134                             addressEndpointRegParent.getKey(), addressEndpointReg.getKey(), addressEndpointRegParent);
135                     return buildFailFeature(String.format(
136                             "Parent AddressEndpoint does not contain a child AddressEndpoint."
137                                     + "\nParent AddressEndpoint: %s" + "\nChild AddressEndpoint: %s",
138                             addressEndpointRegParent.getKey(), addressEndpointReg.getKey()));
139                 }
140             }
141         }
142         for (ParentContainmentEndpoint parentEndpoint : EndpointUtils
143             .getParentContainmentEndpoints(parentEndpointChoice)) {
144             ContainmentEndpointRegKey key =
145                     new ContainmentEndpointRegKey(parentEndpoint.getContextId(), parentEndpoint.getContextType());
146             ContainmentEndpointReg containmentEndpointRegParent =
147                     findContainmentEndpointReg(key, containmentEndpointRegs);
148             if (containmentEndpointRegParent == null) {
149                 Optional<ContainmentEndpoint> containmentEndpointOptional =
150                         DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.containmentEndpointIid(
151                                 new ContainmentEndpointKey(key.getContextId(), key.getContextType())), rTx);
152                 if (!containmentEndpointOptional.isPresent()) {
153                     LOG.debug("Parent ContainmentEndpoint {} does not exist in RPC and DS.", parentEndpoint.getKey());
154                     return buildFailFeature(String.format("Parent ContainmentEndpoint %s does not exist in RPC and DS.",
155                             parentEndpoint.getKey()));
156                 }
157             } else {
158                 List<ChildEndpoint> childEndpoints = containmentEndpointRegParent.getChildEndpoint();
159                 if (!nullToEmpty(childEndpoints).contains(new ChildEndpointBuilder(addressEndpointReg).build())) {
160                     LOG.debug("Parent ContainmentEndpoint {} does not contain a child AddressEndpoint {}.\nParent: {}",
161                             containmentEndpointRegParent.getKey(), addressEndpointReg.getKey(),
162                             containmentEndpointRegParent);
163                     return buildFailFeature(String.format(
164                             "Parent ContainmentEndpoint does not contain a child AddressEndpoint."
165                                     + "\nParent ContainmentEndpoint: %s" + "\nChild AddressEndpoint: %s",
166                             containmentEndpointRegParent.getKey(), addressEndpointReg.getKey()));
167                 }
168             }
169         }
170         return null;
171     }
172
173     private static ListenableFuture<RpcResult<Void>> verifyContainmentEndpointChilds(
174             List<AddressEndpointReg> addressEndpointRegs, List<ContainmentEndpointReg> containmentEndpointRegs,
175             ReadTransaction rTx) {
176         for (ContainmentEndpointReg containmentEndpointReg : nullToEmpty(containmentEndpointRegs)) {
177             for (ChildEndpoint childEndpoint : nullToEmpty(containmentEndpointReg.getChildEndpoint())) {
178                 AddressEndpointRegKey key = new AddressEndpointRegKey(childEndpoint.getAddress(),
179                         childEndpoint.getAddressType(), childEndpoint.getContextId(), childEndpoint.getContextType());
180                 AddressEndpointReg addressEndpointRegChild = findAddressEndpointReg(key, addressEndpointRegs);
181                 if (addressEndpointRegChild == null) {
182                     Optional<AddressEndpoint> addressEndpointOptional =
183                             DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
184                                     IidFactory.addressEndpointIid(new AddressEndpointKey(key.getAddress(),
185                                             key.getAddressType(), key.getContextId(), key.getContextType())),
186                                     rTx);
187                     if (!addressEndpointOptional.isPresent()) {
188                         LOG.debug("Child AddressEndpoint {} does not exist in RPC and DS.", childEndpoint.getKey());
189                         return buildFailFeature(String.format("Child AddressEndpoint %s does not exist in RPC and DS.",
190                                 childEndpoint.getKey()));
191                     }
192                 } else {
193                     List<ParentContainmentEndpoint> parentContainmentEndpoints = EndpointUtils
194                         .getParentContainmentEndpoints(addressEndpointRegChild.getParentEndpointChoice());
195                     if (!parentContainmentEndpoints
196                         .contains(new ParentContainmentEndpointBuilder(containmentEndpointReg).build())) {
197                         LOG.debug(
198                                 "Child AddressEndpoint {} does not contain a parent ContainmentEndpoint {}.\nChild: {}",
199                                 addressEndpointRegChild.getKey(), containmentEndpointReg.getKey(),
200                                 addressEndpointRegChild);
201                         return buildFailFeature(String.format(
202                                 "Child AddressEndpoint does not contain a parent ContainmentEndpoint."
203                                         + "\nChild AddressEndpoint: %s" + "\nParent ContainmentEndpoint: %s",
204                                 addressEndpointRegChild.getKey(), containmentEndpointReg.getKey()));
205                     }
206                 }
207             }
208         }
209         return null;
210     }
211
212     private static AddressEndpointReg findAddressEndpointReg(AddressEndpointRegKey key,
213             List<AddressEndpointReg> addressEndpointRegs) {
214         for (AddressEndpointReg addressEndpointReg : addressEndpointRegs) {
215             if (addressEndpointReg.getKey().equals(key)) {
216                 return addressEndpointReg;
217             }
218         }
219         return null;
220     }
221
222     private static ContainmentEndpointReg findContainmentEndpointReg(ContainmentEndpointRegKey key,
223             List<ContainmentEndpointReg> addressEndpointRegs) {
224         for (ContainmentEndpointReg containmentEndpointReg : addressEndpointRegs) {
225             if (containmentEndpointReg.getKey().equals(key)) {
226                 return containmentEndpointReg;
227             }
228         }
229         return null;
230     }
231
232     private static ListenableFuture<RpcResult<Void>> buildFailFeature(String message) {
233         return Futures
234             .immediateFuture(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.PROTOCOL, message).build());
235     }
236
237     private static <T> List<T> nullToEmpty(@Nullable List<T> list) {
238         return list == null ? Collections.emptyList() : list;
239     }
240 }