2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.so.client.aai;
23 import java.lang.reflect.InvocationTargetException;
25 import java.util.Optional;
27 import javax.ws.rs.NotFoundException;
28 import javax.ws.rs.core.GenericType;
29 import javax.ws.rs.core.Response;
30 import javax.ws.rs.core.Response.Status;
32 import org.onap.aai.domain.yang.Relationship;
33 import org.onap.so.client.RestClient;
34 import org.onap.so.client.RestProperties;
35 import org.onap.so.client.aai.entities.AAIEdgeLabel;
36 import org.onap.so.client.aai.entities.AAIResultWrapper;
37 import org.onap.so.client.aai.entities.uri.AAIResourceUri;
38 import org.onap.so.client.aai.entities.uri.AAIUri;
39 import org.onap.so.client.graphinventory.entities.uri.Depth;
41 public class AAIResourcesClient extends AAIClient {
43 public AAIResourcesClient() {
47 public AAIResourcesClient(AAIVersion version) {
49 this.version = version;
53 * creates a new object in A&AI
55 * @param obj - can be any object which will marshal into a valid A&AI payload
59 public void create(AAIResourceUri uri, Object obj) {
60 RestClient aaiRC = this.createClient(uri);
66 * creates a new object in A&AI with no payload body
71 public void createEmpty(AAIResourceUri uri) {
72 RestClient aaiRC = this.createClient(uri);
78 * returns false if the object does not exist in A&AI
83 public boolean exists(AAIResourceUri uri) {
84 AAIUri forceMinimal = this.addParams(Optional.of(Depth.ZERO), true, uri);
86 RestClient aaiRC = this.createClient(forceMinimal);
88 return aaiRC.get().getStatus() == Status.OK.getStatusCode();
89 } catch (NotFoundException e) {
95 * Adds a relationship between two objects in A&AI
100 public void connect(AAIResourceUri uriA, AAIResourceUri uriB) {
101 AAIResourceUri uriAClone = uriA.clone();
102 RestClient aaiRC = this.createClient(uriAClone.relationshipAPI());
103 aaiRC.put(this.buildRelationship(uriB));
108 * Adds a relationship between two objects in A&AI
109 * with a given edge label
115 public void connect(AAIResourceUri uriA, AAIResourceUri uriB, AAIEdgeLabel label) {
116 AAIResourceUri uriAClone = uriA.clone();
117 RestClient aaiRC = this.createClient(uriAClone.relationshipAPI());
118 aaiRC.put(this.buildRelationship(uriB, label));
123 * Removes relationship from two objects in A&AI
129 public void disconnect(AAIResourceUri uriA, AAIResourceUri uriB) {
130 AAIResourceUri uriAClone = uriA.clone();
131 RestClient aaiRC = this.createClient(uriAClone.relationshipAPI());
132 aaiRC.delete(this.buildRelationship(uriB));
137 * Deletes object from A&AI. Automatically handles resource-version.
142 public void delete(AAIResourceUri uri) {
143 AAIResourceUri clone = uri.clone();
144 RestClient aaiRC = this.createClient(clone);
145 Map<String, Object> result = aaiRC.get(new GenericType<Map<String, Object>>(){})
146 .orElseThrow(() -> new NotFoundException(clone.build() + " does not exist in A&AI"));
147 String resourceVersion = (String) result.get("resource-version");
148 aaiRC = this.createClient(clone.resourceVersion(resourceVersion));
154 * @param obj - can be any object which will marshal into a valid A&AI payload
158 public void update(AAIResourceUri uri, Object obj) {
159 RestClient aaiRC = this.createClient(uri);
165 * Retrieves an object from A&AI and unmarshalls it into the Class specified
170 public <T> Optional<T> get(Class<T> clazz, AAIResourceUri uri) {
172 return this.createClient(uri).get(clazz);
173 } catch (NotFoundException e) {
174 if (this.getRestProperties().mapNotFoundToEmpty()) {
175 return Optional.empty();
183 * Retrieves an object from A&AI and returns complete response
187 public Response getFullResponse(AAIResourceUri uri) {
189 return this.createClient(uri).get();
190 } catch (NotFoundException e) {
191 if (this.getRestProperties().mapNotFoundToEmpty()) {
192 return e.getResponse();
200 * Retrieves an object from A&AI and automatically unmarshalls it into a Map or List
205 public <T> Optional<T> get(GenericType<T> resultClass, AAIResourceUri uri) {
207 return this.createClient(uri).get(resultClass);
208 } catch (NotFoundException e) {
209 if (this.getRestProperties().mapNotFoundToEmpty()) {
210 return Optional.empty();
218 * Retrieves an object from A&AI wrapped in a helper class which offer additional features
223 public AAIResultWrapper get(AAIResourceUri uri) {
226 json = this.createClient(uri).get(String.class).orElse(null);
227 } catch (NotFoundException e) {
228 if (this.getRestProperties().mapNotFoundToEmpty()) {
234 return new AAIResultWrapper(json);
238 * Retrieves an object from A&AI wrapped in a helper class which offer additional features
239 * If the object cannot be found in A&AI the method will throw the runtime exception
240 * included as an argument
244 public AAIResultWrapper get(AAIResourceUri uri, Class<? extends RuntimeException> c) {
247 json = this.createClient(uri).get(String.class)
248 .orElseThrow(() -> createException(c, uri.build() + " not found in A&AI"));
249 } catch (NotFoundException e) {
250 throw createException(c, "could not construct uri for use with A&AI");
253 return new AAIResultWrapper(json);
256 private RuntimeException createException(Class<? extends RuntimeException> c, String message) {
259 e = c.getConstructor(String.class).newInstance(message);
260 } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
261 | NoSuchMethodException | SecurityException e1) {
262 throw new IllegalArgumentException("could not create instance for " + c.getName());
268 private Relationship buildRelationship(AAIResourceUri uri) {
269 return buildRelationship(uri, Optional.empty());
272 private Relationship buildRelationship(AAIResourceUri uri, AAIEdgeLabel label) {
273 return buildRelationship(uri, Optional.of(label));
275 private Relationship buildRelationship(AAIResourceUri uri, Optional<AAIEdgeLabel> label) {
276 final Relationship result = new Relationship();
277 result.setRelatedLink(uri.build().toString());
278 if (label.isPresent()) {
279 result.setRelationshipLabel(label.toString());
285 * Will automatically create the object if it does not exist
287 * @param obj - Optional object which serializes to a valid A&AI payload
291 public AAIResourcesClient createIfNotExists(AAIResourceUri uri, Optional<Object> obj) {
292 if(!this.exists(uri)){
293 if (obj.isPresent()) {
294 this.create(uri, obj.get());
296 this.createEmpty(uri);
304 * Starts a transaction which encloses multiple A&AI mutations
308 public AAITransactionalClient beginTransaction() {
309 return new AAITransactionalClient(this.getVersion());
313 * Starts a transaction groups multiple A&AI mutations
317 public AAISingleTransactionClient beginSingleTransaction() {
318 return new AAISingleTransactionClient(this.getVersion());
321 private AAIUri addParams(Optional<Depth> depth, boolean nodesOnly, AAIUri uri) {
322 AAIUri clone = uri.clone();
323 if (depth.isPresent()) {
324 clone.depth(depth.get());
327 clone.nodesOnly(nodesOnly);
333 public <T extends RestProperties> T getRestProperties() {
334 return super.getRestProperties();