Add subscription for notifications
[so.git] / common / src / main / java / org / onap / so / client / graphinventory / GraphInventoryResourcesClient.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 - 2019 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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.onap.so.client.graphinventory;
22
23 import java.lang.reflect.InvocationTargetException;
24 import java.util.Map;
25 import java.util.Optional;
26
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;
31
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.graphinventory.entities.GraphInventoryEdgeLabel;
36 import org.onap.so.client.graphinventory.entities.GraphInventoryResultWrapper;
37 import org.onap.so.client.graphinventory.entities.uri.Depth;
38 import org.onap.so.client.graphinventory.entities.uri.GraphInventoryResourceUri;
39 import org.onap.so.client.graphinventory.entities.uri.GraphInventoryUri;
40
41 public abstract class GraphInventoryResourcesClient<Self, Uri extends GraphInventoryResourceUri, EdgeLabel extends GraphInventoryEdgeLabel, Wrapper extends GraphInventoryResultWrapper, TransactionalClient, SingleTransactionClient> {
42
43         protected GraphInventoryClient client;
44         
45         protected GraphInventoryResourcesClient(GraphInventoryClient client) {
46                 this.client = client;
47         }
48         /**
49          * creates a new object in GraphInventory
50          * 
51          * @param obj - can be any object which will marshal into a valid GraphInventory payload
52          * @param uri
53          * @return
54          */
55         public void create(Uri uri, Object obj) {
56                 RestClient giRC = client.createClient(uri);
57                 giRC.put(obj);
58         }
59
60         /**
61          * creates a new object in GraphInventory with no payload body
62          * 
63          * @param uri
64          * @return
65          */
66         public void createEmpty(Uri uri) {
67                 RestClient giRC = client.createClient(uri);
68                 giRC.put("");
69         }
70
71         /**
72          * returns false if the object does not exist in GraphInventory
73          * 
74          * @param uri
75          * @return
76          */
77         public boolean exists(Uri uri) {
78                 GraphInventoryUri forceMinimal = this.addParams(Optional.of(Depth.ZERO), true, uri);
79                 try {
80                         RestClient giRC = client.createClient(forceMinimal);
81                         
82                         return giRC.get().getStatus() == Status.OK.getStatusCode();
83                 } catch (NotFoundException e) {
84                         return false;
85                 }
86         }
87
88         /**
89          * Adds a relationship between two objects in GraphInventory 
90          * @param uriA
91          * @param uriB
92          * @return
93          */
94         public void connect(Uri uriA, Uri uriB) {
95                 GraphInventoryResourceUri uriAClone = uriA.clone();
96                 RestClient giRC = client.createClient(uriAClone.relationshipAPI());
97                 giRC.put(this.buildRelationship(uriB));
98         }
99
100         /**
101          * Adds a relationship between two objects in GraphInventory 
102          * with a given edge label
103          * @param uriA
104          * @param uriB
105          * @param edge label
106          * @return
107          */
108         public void connect(Uri uriA, Uri uriB, EdgeLabel label) {
109                 GraphInventoryResourceUri uriAClone = uriA.clone();
110                 RestClient giRC = client.createClient(uriAClone.relationshipAPI());
111                 giRC.put(this.buildRelationship(uriB, label));
112         }
113
114         /**
115          * Removes relationship from two objects in GraphInventory
116          * 
117          * @param uriA
118          * @param uriB
119          * @return
120          */
121         public void disconnect(Uri uriA, Uri uriB) {
122                 GraphInventoryResourceUri uriAClone = uriA.clone();
123                 RestClient giRC = client.createClient(uriAClone.relationshipAPI());
124                 giRC.delete(this.buildRelationship(uriB));
125         }
126
127         /**
128          * Deletes object from GraphInventory. Automatically handles resource-version.
129          * 
130          * @param uri
131          * @return
132          */
133         public void delete(Uri uri) {
134                 GraphInventoryResourceUri clone = uri.clone();
135                 RestClient giRC = client.createClient(clone);
136                 Map<String, Object> result = giRC.get(new GenericType<Map<String, Object>>(){})
137                                 .orElseThrow(() -> new NotFoundException(clone.build() + " does not exist in " + client.getGraphDBName()));
138                 String resourceVersion = (String) result.get("resource-version");
139                 giRC = client.createClient(clone.resourceVersion(resourceVersion));
140                 giRC.delete();
141         }
142
143         /**
144          * @param obj - can be any object which will marshal into a valid GraphInventory payload
145          * @param uri
146          * @return
147          */
148         public void update(Uri uri, Object obj) {
149                 RestClient giRC = client.createClient(uri);
150                 giRC.patch(obj);
151         }
152
153         /**
154          * Retrieves an object from GraphInventory and unmarshalls it into the Class specified
155          * @param clazz
156          * @param uri
157          * @return
158          */
159         public <T> Optional<T> get(Class<T> clazz, Uri uri) {
160                 try {
161                         return client.createClient(uri).get(clazz);
162                 } catch (NotFoundException e) {
163                         if (this.getRestProperties().mapNotFoundToEmpty()) {
164                                 return Optional.empty();
165                         } else {
166                                 throw e;
167                         }
168                 }
169         }
170
171         /**
172          * Retrieves an object from GraphInventory and returns complete response
173          * @param uri
174          * @return
175          */
176         public Response getFullResponse(Uri uri) {
177                 try {
178                         return client.createClient(uri).get();
179                 } catch (NotFoundException e) {
180                         if (this.getRestProperties().mapNotFoundToEmpty()) {
181                                 return e.getResponse();
182                         } else {
183                                 throw e;
184                         }
185                 }
186         }
187
188         /**
189          * Retrieves an object from GraphInventory and automatically unmarshalls it into a Map or List 
190          * @param resultClass
191          * @param uri
192          * @return
193          */
194         public <T> Optional<T> get(GenericType<T> resultClass, Uri uri) {
195                 try {
196                         return client.createClient(uri).get(resultClass);
197                 } catch (NotFoundException e) {
198                         if (this.getRestProperties().mapNotFoundToEmpty()) {
199                                 return Optional.empty();
200                         } else {
201                                 throw e;
202                         }
203                 }
204         }
205         /**
206          * Retrieves an object from GraphInventory wrapped in a helper class which offer additional features
207          * 
208          * @param uri
209          * @return
210          */
211         public Wrapper get(Uri uri) {
212                 String json;
213                 try {
214                         json = client.createClient(uri).get(String.class).orElse(null);
215                 } catch (NotFoundException e) {
216                         if (this.getRestProperties().mapNotFoundToEmpty()) {
217                                 json = null;
218                         } else {
219                                 throw e;
220                         }
221                 }
222                 return this.createWrapper(json);
223         }
224
225         /**
226          * Retrieves an object from GraphInventory wrapped in a helper class which offer additional features
227          * If the object cannot be found in GraphInventory the method will throw the runtime exception
228          * included as an argument
229          * @param uri
230          * @return
231          */
232         public Wrapper get(Uri uri, Class<? extends RuntimeException> c) {
233                 String json;
234                 try {
235                         json = client.createClient(uri).get(String.class)
236                                         .orElseThrow(() -> createException(c, uri.build() + " not found in " + client.getGraphDBName(), Optional.empty()));
237                 } catch (NotFoundException e) {
238                         throw createException(c, "could not construct uri for use with " + client.getGraphDBName(), Optional.of(e));
239                 }
240
241                 return this.createWrapper(json);
242         }
243         
244         private RuntimeException createException(Class<? extends RuntimeException> c, String message, Optional<Throwable> t) {
245                 RuntimeException e;
246                 try {
247                         if (t.isPresent()) {
248                                 e = c.getConstructor(String.class, Throwable.class).newInstance(message, t.get());
249                         } else {
250                                 e = c.getConstructor(String.class).newInstance(message);
251                         }
252                 } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
253                                 | NoSuchMethodException | SecurityException e1) {
254                         throw new IllegalArgumentException("could not create instance for " + c.getName());
255                 }
256                 
257                 return e;
258         }
259
260         /**
261          * Will automatically create the object if it does not exist
262          * 
263          * @param obj - Optional object which serializes to a valid GraphInventory payload
264          * @param uri
265          * @return
266          */
267         public Self createIfNotExists(Uri uri, Optional<Object> obj) {
268                 if(!this.exists(uri)){
269                         if (obj.isPresent()) {
270                                 this.create(uri, obj.get());
271                         } else {
272                                 this.createEmpty(uri);
273                         }
274                         
275                 }
276                 return (Self)this;
277         }
278         protected Relationship buildRelationship(GraphInventoryResourceUri uri) {
279                 return buildRelationship(uri, Optional.empty());
280         }
281         
282         protected Relationship buildRelationship(GraphInventoryResourceUri uri, GraphInventoryEdgeLabel label) {
283                 return buildRelationship(uri, Optional.of(label));
284         }
285         protected Relationship buildRelationship(GraphInventoryResourceUri uri, Optional<GraphInventoryEdgeLabel> label) {
286                 final Relationship result = new Relationship();
287                 result.setRelatedLink(uri.build().toString());
288                 if (label.isPresent()) {
289                         result.setRelationshipLabel(label.get().toString());
290                 }
291                 return result;
292         }
293         
294         public abstract Wrapper createWrapper(String json);
295         
296         /**
297          * Starts a transaction which encloses multiple GraphInventory mutations
298          * 
299          * @return
300          */
301         public abstract TransactionalClient beginTransaction();
302
303         /**
304          * Starts a transaction groups multiple GraphInventory mutations
305          * 
306          * @return
307          */
308         public abstract SingleTransactionClient beginSingleTransaction();
309
310         private GraphInventoryUri addParams(Optional<Depth> depth, boolean nodesOnly, GraphInventoryUri uri) {
311                 GraphInventoryUri clone = uri.clone();
312                 if (depth.isPresent()) {
313                         clone.depth(depth.get());
314                 }
315                 if (nodesOnly) {
316                         clone.nodesOnly(nodesOnly);
317                 }
318                 
319                 return clone;
320         }
321         
322         public <T extends RestProperties> T getRestProperties() {
323                 return client.getRestProperties();
324         }
325
326 }