Replaced all tabs with spaces in java and pom.xml
[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 import javax.ws.rs.NotFoundException;
27 import javax.ws.rs.core.GenericType;
28 import javax.ws.rs.core.Response;
29 import javax.ws.rs.core.Response.Status;
30 import org.onap.aai.domain.yang.Relationship;
31 import org.onap.so.client.RestClient;
32 import org.onap.so.client.RestProperties;
33 import org.onap.so.client.graphinventory.entities.GraphInventoryEdgeLabel;
34 import org.onap.so.client.graphinventory.entities.GraphInventoryResultWrapper;
35 import org.onap.so.client.graphinventory.entities.uri.Depth;
36 import org.onap.so.client.graphinventory.entities.uri.GraphInventoryResourceUri;
37 import org.onap.so.client.graphinventory.entities.uri.GraphInventoryUri;
38
39 public abstract class GraphInventoryResourcesClient<Self, Uri extends GraphInventoryResourceUri, EdgeLabel extends GraphInventoryEdgeLabel, Wrapper extends GraphInventoryResultWrapper, TransactionalClient, SingleTransactionClient> {
40
41     protected GraphInventoryClient client;
42
43     protected GraphInventoryResourcesClient(GraphInventoryClient client) {
44         this.client = client;
45     }
46
47     /**
48      * creates a new object in GraphInventory
49      * 
50      * @param obj - can be any object which will marshal into a valid GraphInventory payload
51      * @param uri
52      * @return
53      */
54     public void create(Uri uri, Object obj) {
55         RestClient giRC = client.createClient(uri);
56         giRC.put(obj);
57     }
58
59     /**
60      * creates a new object in GraphInventory with no payload body
61      * 
62      * @param uri
63      * @return
64      */
65     public void createEmpty(Uri uri) {
66         RestClient giRC = client.createClient(uri);
67         giRC.put("");
68     }
69
70     /**
71      * returns false if the object does not exist in GraphInventory
72      * 
73      * @param uri
74      * @return
75      */
76     public boolean exists(Uri uri) {
77         GraphInventoryUri forceMinimal = this.addParams(Optional.of(Depth.ZERO), true, uri);
78         try {
79             RestClient giRC = client.createClient(forceMinimal);
80
81             return giRC.get().getStatus() == Status.OK.getStatusCode();
82         } catch (NotFoundException e) {
83             return false;
84         }
85     }
86
87     /**
88      * Adds a relationship between two objects in GraphInventory
89      * 
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 with a given edge label
102      * 
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>>() {}).orElseThrow(
137                 () -> 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      * 
156      * @param clazz
157      * @param uri
158      * @return
159      */
160     public <T> Optional<T> get(Class<T> clazz, Uri uri) {
161         try {
162             return client.createClient(uri).get(clazz);
163         } catch (NotFoundException e) {
164             if (this.getRestProperties().mapNotFoundToEmpty()) {
165                 return Optional.empty();
166             } else {
167                 throw e;
168             }
169         }
170     }
171
172     /**
173      * Retrieves an object from GraphInventory and returns complete response
174      * 
175      * @param uri
176      * @return
177      */
178     public Response getFullResponse(Uri uri) {
179         try {
180             return client.createClient(uri).get();
181         } catch (NotFoundException e) {
182             if (this.getRestProperties().mapNotFoundToEmpty()) {
183                 return e.getResponse();
184             } else {
185                 throw e;
186             }
187         }
188     }
189
190     /**
191      * Retrieves an object from GraphInventory and automatically unmarshalls it into a Map or List
192      * 
193      * @param resultClass
194      * @param uri
195      * @return
196      */
197     public <T> Optional<T> get(GenericType<T> resultClass, Uri uri) {
198         try {
199             return client.createClient(uri).get(resultClass);
200         } catch (NotFoundException e) {
201             if (this.getRestProperties().mapNotFoundToEmpty()) {
202                 return Optional.empty();
203             } else {
204                 throw e;
205             }
206         }
207     }
208
209     /**
210      * Retrieves an object from GraphInventory wrapped in a helper class which offer additional features
211      * 
212      * @param uri
213      * @return
214      */
215     public Wrapper get(Uri uri) {
216         String json;
217         try {
218             json = client.createClient(uri).get(String.class).orElse(null);
219         } catch (NotFoundException e) {
220             if (this.getRestProperties().mapNotFoundToEmpty()) {
221                 json = null;
222             } else {
223                 throw e;
224             }
225         }
226         return this.createWrapper(json);
227     }
228
229     /**
230      * Retrieves an object from GraphInventory wrapped in a helper class which offer additional features If the object
231      * cannot be found in GraphInventory the method will throw the runtime exception included as an argument
232      * 
233      * @param uri
234      * @return
235      */
236     public Wrapper get(Uri uri, Class<? extends RuntimeException> c) {
237         String json;
238         try {
239             json = client.createClient(uri).get(String.class).orElseThrow(() -> createException(c,
240                     uri.build() + " not found in " + client.getGraphDBName(), Optional.empty()));
241         } catch (NotFoundException e) {
242             throw createException(c, "could not construct uri for use with " + client.getGraphDBName(), Optional.of(e));
243         }
244
245         return this.createWrapper(json);
246     }
247
248     private RuntimeException createException(Class<? extends RuntimeException> c, String message,
249             Optional<Throwable> t) {
250         RuntimeException e;
251         try {
252             if (t.isPresent()) {
253                 e = c.getConstructor(String.class, Throwable.class).newInstance(message, t.get());
254             } else {
255                 e = c.getConstructor(String.class).newInstance(message);
256             }
257         } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
258                 | NoSuchMethodException | SecurityException e1) {
259             throw new IllegalArgumentException("could not create instance for " + c.getName());
260         }
261
262         return e;
263     }
264
265     /**
266      * Will automatically create the object if it does not exist
267      * 
268      * @param obj - Optional object which serializes to a valid GraphInventory payload
269      * @param uri
270      * @return
271      */
272     public Self createIfNotExists(Uri uri, Optional<Object> obj) {
273         if (!this.exists(uri)) {
274             if (obj.isPresent()) {
275                 this.create(uri, obj.get());
276             } else {
277                 this.createEmpty(uri);
278             }
279
280         }
281         return (Self) this;
282     }
283
284     protected Relationship buildRelationship(GraphInventoryResourceUri uri) {
285         return buildRelationship(uri, Optional.empty());
286     }
287
288     protected Relationship buildRelationship(GraphInventoryResourceUri uri, GraphInventoryEdgeLabel label) {
289         return buildRelationship(uri, Optional.of(label));
290     }
291
292     protected Relationship buildRelationship(GraphInventoryResourceUri uri, Optional<GraphInventoryEdgeLabel> label) {
293         final Relationship result = new Relationship();
294         result.setRelatedLink(uri.build().toString());
295         if (label.isPresent()) {
296             result.setRelationshipLabel(label.get().toString());
297         }
298         return result;
299     }
300
301     public abstract Wrapper createWrapper(String json);
302
303     /**
304      * Starts a transaction which encloses multiple GraphInventory mutations
305      * 
306      * @return
307      */
308     public abstract TransactionalClient beginTransaction();
309
310     /**
311      * Starts a transaction groups multiple GraphInventory mutations
312      * 
313      * @return
314      */
315     public abstract SingleTransactionClient beginSingleTransaction();
316
317     private GraphInventoryUri addParams(Optional<Depth> depth, boolean nodesOnly, GraphInventoryUri uri) {
318         GraphInventoryUri clone = uri.clone();
319         if (depth.isPresent()) {
320             clone.depth(depth.get());
321         }
322         if (nodesOnly) {
323             clone.nodesOnly(nodesOnly);
324         }
325
326         return clone;
327     }
328
329     public <T extends RestProperties> T getRestProperties() {
330         return client.getRestProperties();
331     }
332
333 }