Enhancements for the aai-common library
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / util / RestController.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 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.aai.util;
22
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 import com.fasterxml.jackson.databind.ObjectMapper;
26 import com.fasterxml.jackson.databind.type.TypeFactory;
27 import com.sun.jersey.api.client.Client;
28 import com.sun.jersey.api.client.ClientHandlerException;
29 import com.sun.jersey.api.client.ClientResponse;
30
31 import java.io.IOException;
32 import java.security.KeyManagementException;
33 import java.security.KeyStoreException;
34 import java.security.UnrecoverableKeyException;
35 import java.security.cert.CertificateException;
36 import java.security.NoSuchAlgorithmException;
37 import java.util.ArrayList;
38 import java.util.List;
39 import java.util.UUID;
40
41 import org.onap.aai.exceptions.AAIException;
42
43 public class RestController implements RestControllerInterface {
44
45     private static final String TARGET_NAME = "AAI";
46     private static Logger LOGGER = LoggerFactory.getLogger(RestController.class);
47
48     private static Client client = null;
49
50     private String restSrvrBaseURL;
51
52     private String overrideLocalHost = null;
53
54     // To do - Come up with helper function that will automatically
55     // generate the REST API path based on path parameter(s) and query parameter(s)!
56     public static final String REST_APIPATH_COMPLEXES = "cloud-infrastructure/complexes";
57     public static final String REST_APIPATH_COMPLEX = "cloud-infrastructure/complexes/complex/";
58     public static final String REST_APIPATH_PSERVERS = "cloud-infrastructure/pservers";
59     public static final String REST_APIPATH_PSERVER = "cloud-infrastructure/pservers/pserver/";
60     public static final String REST_APIPATH_PHYSICALLINKS = "network/physical-links/";
61     public static final String REST_APIPATH_PHYSICALLINK = "network/physical-links/physical-link/";
62     public static final String REST_APIPATH_PINTERFACES = "network/p-interfaces/";
63     public static final String REST_APIPATH_PINTERFACE = "network/p-interfaces/p-interface/";
64     public static final String REST_APIPATH_VPLSPES = "network/vpls-pes/";
65     public static final String REST_APIPATH_VPLSPE = "network/vpls-pes/vpls-pe/";
66     public static final String REST_APIPATH_UPDATE = "actions/update/";
67     public static final String REST_APIPATH_SEARCH = "search/nodes-query?search-node-type=";
68
69     public static final String REST_APIPATH_CLOUDREGION = "cloud-infrastructure/cloud-regions/cloud-region/";
70     public static final String REST_APIPATH_TENANT = "cloud-infrastructure/tenants/tenant/";
71     public static final String REST_APIPATH_VIRTUAL_DATA_CENTER =
72             "cloud-infrastructure/virtual-data-centers/virtual-data-center/";
73     public static final String REST_APIPATH_VIRTUAL_DATA_CENTERS = "cloud-infrastructure/virtual-data-centers/";
74     public static final String REST_APIPATH_GENERIC_VNF = "network/generic-vnfs/generic-vnf/";
75     public static final String REST_APIPATH_GENERIC_VNFS = "network/generic-vnfs";
76     public static final String REST_APIPATH_L3_NETWORK = "network/l3-networks/l3-network/";
77     public static final String REST_APIPATH_L3_NETWORKS = "network/l3-networks";
78     public static final String REST_APIPATH_INSTANCE_GROUP = "network/instance-groups/instance-group";
79     public static final String REST_APIPATH_INSTANCE_GROUPS = "network/instance-groups";
80     public static final String REST_APIPATH_VFMODULE = "nodes/vf-modules/vf-module/";
81
82     public static final String REST_APIPATH_VCE = "network/vces/vce/";
83
84     public static final String REST_APIPATH_SERVICE = "service-design-and-creation/services/service/";
85     public static final String REST_APIPATH_LOGICALLINKS = "network/logical-links/";
86     public static final String REST_APIPATH_LOGICALLINK = "network/logical-links/logical-link/";
87
88     public RestController() throws AAIException {
89         this.initRestClient();
90     }
91
92     public RestController(String truststorePath, String truststorePassword, String keystorePath, String keystorePassword) throws AAIException {
93         this.initRestClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
94     }
95     /**
96      * Inits the rest client.
97      *
98      * @throws AAIException the AAI exception
99      */
100     public void initRestClient() throws AAIException {
101         if (client == null) {
102             try {
103                 client = getHttpsAuthClient();
104             } catch (KeyManagementException e) {
105                 throw new AAIException("AAI_7117", "KeyManagementException in REST call to DB: " + e.toString());
106             } catch (Exception e) {
107                 throw new AAIException("AAI_7117", " Exception in REST call to DB: " + e.toString());
108             }
109         }
110     }
111     /**
112      * Inits the rest client.
113      *
114      * @throws AAIException the AAI exception
115      */
116     public void initRestClient(String truststorePath, String truststorePassword, String keystorePath, String keystorePassword) throws AAIException {
117         if (client == null) {
118             try {
119                 client = getHttpsAuthClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
120             } catch (KeyManagementException e) {
121                 throw new AAIException("AAI_7117", "KeyManagementException in REST call to DB: " + e.toString());
122             } catch (Exception e) {
123                 throw new AAIException("AAI_7117", " Exception in REST call to DB: " + e.toString());
124             }
125         }
126     }
127     public Client getHttpsAuthClient(String truststorePath, String truststorePassword, String keystorePath, String keystorePassword) throws KeyManagementException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException {
128         return HttpsAuthClient.getClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
129     }
130
131     public Client getHttpsAuthClient() throws KeyManagementException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, AAIException {
132         return HttpsAuthClient.getClient();
133     }
134     /**
135      * Sets the rest srvr base URL.
136      *
137      * @param baseURL the base URL
138      * @throws AAIException the AAI exception
139      */
140     public void SetRestSrvrBaseURL(String baseURL) throws AAIException {
141         if (baseURL == null)
142             throw new AAIException("AAI_7117", "REST Server base URL cannot be null.");
143         restSrvrBaseURL = baseURL;
144     }
145
146     /**
147      * Gets the rest srvr base URL.
148      *
149      * @return the rest srvr base URL
150      */
151     public String getRestSrvrBaseURL() {
152         return restSrvrBaseURL;
153     }
154
155     public <T> void Get(T t, String sourceID, String transId, String path, RestObject<T> restObject, boolean oldserver)
156             throws AAIException {
157         Get(t, sourceID, transId, path, restObject, oldserver, AAIConstants.AAI_RESOURCES_PORT);
158     }
159
160     /**
161      * To do - optimization and automation. Also make it as generic as possible.
162      *
163      * @param <T> the generic type
164      * @param t the t
165      * @param sourceID the source ID
166      * @param transId the trans id
167      * @param path the path
168      * @param restObject the rest object
169      * @param oldserver the oldserver
170      * @throws AAIException the AAI exception
171      */
172     @SuppressWarnings("unchecked")
173     public <T> void Get(T t, String sourceID, String transId, String path, RestObject<T> restObject, boolean oldserver,
174             int port) throws AAIException {
175         String methodName = "Get";
176         String url = "";
177         transId += ":" + UUID.randomUUID().toString();
178
179         LOGGER.debug(methodName + " start");
180
181         restObject.set(t);
182
183         if (oldserver) {
184             url = AAIConfig.get(AAIConstants.AAI_OLDSERVER_URL) + path;
185         } else {
186             if (overrideLocalHost == null) {
187                 overrideLocalHost =
188                         AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
189             }
190             if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) {
191                 url = String.format(AAIConstants.AAI_LOCAL_REST, port,
192                         AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
193             } else {
194                 url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost,
195                         AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
196             }
197         }
198         LOGGER.debug(url + " for the get REST API");
199         ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
200                 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json")
201                 .get(ClientResponse.class);
202
203         // System.out.println("cres.EntityInputSream()="+cres.getEntityInputStream().toString());
204         // System.out.println("cres.tostring()="+cres.toString());
205
206         if (cres.getStatus() == 200) {
207             // System.out.println(methodName + ": url=" + url);
208             t = (T) cres.getEntity(t.getClass());
209             restObject.set(t);
210             LOGGER.debug(methodName + "REST api GET was successfull!");
211         } else {
212             // System.out.println(methodName + ": url=" + url + " failed with status=" + cres.getStatus());
213             throw new AAIException("AAI_7116", methodName + " with status=" + cres.getStatus() + ", url=" + url);
214         }
215     }
216
217     /**
218      * To do - optimization and automation. Also make it as generic as possible.
219      *
220      * @param <T> the generic type
221      * @param t the t
222      * @param sourceID the source ID
223      * @param transId the trans id
224      * @param path the path
225      * @param restObject the rest object
226      * @param oldserver the oldserver
227      * @throws AAIException the AAI exception
228      */
229     @SuppressWarnings("unchecked")
230     public <T> void Get(T t, String sourceID, String transId, String path, RestObject<T> restObject, String apiVersion)
231             throws AAIException {
232         String methodName = "Get";
233         String url = "";
234         transId += ":" + UUID.randomUUID().toString();
235
236         LOGGER.debug(methodName + " start");
237
238         restObject.set(t);
239
240         url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path;
241
242         LOGGER.debug(url + " for the get REST API");
243         ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
244                 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json")
245                 .get(ClientResponse.class);
246
247         // System.out.println("cres.EntityInputSream()="+cres.getEntityInputStream().toString());
248         // System.out.println("cres.tostring()="+cres.toString());
249
250         if (cres.getStatus() == 200) {
251             // System.out.println(methodName + ": url=" + url);
252             t = (T) cres.getEntity(t.getClass());
253             restObject.set(t);
254             LOGGER.debug(methodName + "REST api GET was successfull!");
255         } else {
256             // System.out.println(methodName + ": url=" + url + " failed with status=" + cres.getStatus());
257             throw new AAIException("AAI_7116", methodName + " with status=" + cres.getStatus() + ", url=" + url);
258         }
259     }
260
261     /**
262      * Map json to object list.
263      *
264      * @param <T> the generic type
265      * @param typeDef the type def
266      * @param json the json
267      * @param clazz the clazz
268      * @return the list
269      * @throws Exception the exception
270      */
271     private <T> List<T> mapJsonToObjectList(T typeDef, String json, Class clazz) throws Exception {
272         List<T> list;
273         ObjectMapper mapper = new ObjectMapper();
274         System.out.println(json);
275         TypeFactory t = TypeFactory.defaultInstance();
276         list = mapper.readValue(json, t.constructCollectionType(ArrayList.class, clazz));
277
278         return list;
279     }
280
281     /**
282      * Put.
283      *
284      * @param <T> the generic type
285      * @param t the t
286      * @param sourceID the source ID
287      * @param transId the trans id
288      * @param path the path
289      * @throws AAIException the AAI exception
290      */
291     public <T> void Put(T t, String sourceID, String transId, String path) throws AAIException {
292         Put(t, sourceID, transId, path, false, AAIConstants.AAI_RESOURCES_PORT);
293     }
294
295     /**
296      * Put.
297      *
298      * @param <T> the generic type
299      * @param t the t
300      * @param sourceID the source ID
301      * @param transId the trans id
302      * @param path the path
303      * @throws AAIException the AAI exception
304      */
305     public <T> void Put(T t, String sourceID, String transId, String path, boolean oldserver) throws AAIException {
306         Put(t, sourceID, transId, path, oldserver, AAIConstants.AAI_RESOURCES_PORT);
307     }
308
309     /**
310      * Put.
311      *
312      * @param <T> the generic type
313      * @param t the t
314      * @param sourceID the source ID
315      * @param transId the trans id
316      * @param path the path
317      * @param oldserver the oldserver
318      * @throws AAIException the AAI exception
319      */
320     public <T> void Put(T t, String sourceID, String transId, String path, boolean oldserver, int port)
321             throws AAIException {
322         String methodName = "Put";
323         String url = "";
324         transId += ":" + UUID.randomUUID().toString();
325
326         LOGGER.debug(methodName + " start");
327
328         if (oldserver) {
329             url = AAIConfig.get(AAIConstants.AAI_OLDSERVER_URL) + path;
330         } else {
331             if (overrideLocalHost == null) {
332                 overrideLocalHost =
333                         AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
334             }
335             if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) {
336                 url = String.format(AAIConstants.AAI_LOCAL_REST, port,
337                         AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
338             } else {
339                 url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost,
340                         AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
341             }
342         }
343
344         ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
345                 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t)
346                 .put(ClientResponse.class);
347
348         // System.out.println("cres.tostring()="+cres.toString());
349
350         int statuscode = cres.getStatus();
351         if (statuscode >= 200 && statuscode <= 299) {
352             LOGGER.debug(methodName + ": url=" + url + ", request=" + path);
353         } else {
354             throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg="
355                     + cres.getEntity(String.class));
356         }
357     }
358
359     public void Delete(String sourceID, String transId, String path) throws AAIException {
360         Delete(sourceID, transId, path, AAIConstants.AAI_RESOURCES_PORT);
361     }
362
363     /**
364      * Delete.
365      *
366      * @param sourceID the source ID
367      * @param transId the trans id
368      * @param path the path
369      * @throws AAIException the AAI exception
370      */
371     public void Delete(String sourceID, String transId, String path, int port) throws AAIException {
372         String methodName = "Delete";
373         String url = "";
374         transId += ":" + UUID.randomUUID().toString();
375
376         LOGGER.debug(methodName + " start");
377
378         String request = "{}";
379         if (overrideLocalHost == null) {
380             overrideLocalHost = AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
381         }
382         if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) {
383             url = String.format(AAIConstants.AAI_LOCAL_REST, port,
384                     AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
385         } else {
386             url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost,
387                     AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
388         }
389         ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
390                 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(request)
391                 .delete(ClientResponse.class);
392
393         if (cres.getStatus() == 404) { // resource not found
394             LOGGER.info("Resource does not exist...: " + cres.getStatus() + ":" + cres.getEntity(String.class));
395         } else if (cres.getStatus() == 200 || cres.getStatus() == 204) {
396             LOGGER.info("Resource " + url + " deleted");
397         } else {
398             LOGGER.error("Deleting Resource failed: " + cres.getStatus() + ":" + cres.getEntity(String.class));
399             throw new AAIException("AAI_7116", "Error during DELETE");
400         }
401     }
402
403     public <T> String Post(T t, String sourceID, String transId, String path) throws Exception {
404         return Post(t, sourceID, transId, path, AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
405     }
406
407     /**
408      * Post.
409      *
410      * @param <T> the generic type
411      * @param t the t
412      * @param sourceID the source ID
413      * @param transId the trans id
414      * @param path the path
415      * @param apiVersion the apiVersion
416      * @return the string
417      * @throws Exception the exception
418      */
419     public <T> String Post(T t, String sourceID, String transId, String path, String apiVersion) throws Exception {
420         String methodName = "Post";
421         String url = "";
422         transId += ":" + UUID.randomUUID().toString();
423
424         LOGGER.debug(methodName + " start");
425
426         try {
427
428             url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path;
429
430             ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
431                     .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t)
432                     .post(ClientResponse.class);
433
434             int statuscode = cres.getStatus();
435             if (statuscode >= 200 && statuscode <= 299) {
436                 LOGGER.debug(methodName + "REST api POST was successful!");
437                 return cres.getEntity(String.class);
438             } else {
439                 throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg="
440                         + cres.getEntity(String.class));
441             }
442
443         } catch (AAIException e) {
444             throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());
445         } catch (Exception e) {
446             throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());
447
448         } finally {
449         }
450     }
451
452     /**
453      * Gets the single instance of RestController.
454      *
455      * @param <T> the generic type
456      * @param clazz the clazz
457      * @return single instance of RestController
458      * @throws IllegalAccessException the illegal access exception
459      * @throws InstantiationException the instantiation exception
460      */
461     public <T> T getInstance(Class<T> clazz) throws IllegalAccessException, InstantiationException {
462         return clazz.newInstance();
463     }
464
465     /**
466      * Does resource exist.
467      *
468      * @param <T> the generic type
469      * @param resourcePath the resource path
470      * @param resourceClassName the resource class name
471      * @param fromAppId the from app id
472      * @param transId the trans id
473      * @return the t
474      */
475     /*
476      * DoesResourceExist
477      * 
478      * To check whether a resource exist or get a copy of the existing version of the resource
479      * 
480      * Resourcepath: should contain the qualified resource path (including encoded unique key identifier value),
481      * resourceClassName: is the canonical name of the resource class name,
482      * fromAppId:
483      * transId:
484      * 
485      * Will return null (if the resource doesn’t exist) (or)
486      * Will return the specified resource from the Graph.
487      * 
488      * Example:
489      * LogicalLink llink = new LogicalLink();
490      * String resourceClassName = llink.getClass().getCanonicalName();
491      * llink = RestController.DoesResourceExist("network/logical-links/logical-link/" + <encoded-link-name>,
492      * resourceClassName, fromAppId, transId);
493      */
494     public <T> T DoesResourceExist(String resourcePath, String resourceClassName, String fromAppId, String transId) {
495
496         try {
497
498             RestObject<T> restObj = new RestObject<T>();
499             @SuppressWarnings("unchecked")
500             T resourceObj = (T) getInstance(Class.forName(resourceClassName));
501             restObj.set(resourceObj);
502             Get(resourceObj, fromAppId, transId, resourcePath, restObj, false, AAIConstants.AAI_RESOURCES_PORT);
503
504             resourceObj = restObj.get();
505             if (resourceObj != null)
506                 return resourceObj;
507
508         } catch (AAIException e) {
509
510         } catch (ClientHandlerException che) {
511
512         } catch (Exception e) {
513
514         }
515
516         return null;
517     }
518
519     /**
520      * Patch.
521      *
522      * @param <T> the generic type
523      * @param sourceID the source ID
524      * @param transId the trans id
525      * @param path the path
526      * @throws AAIException the AAI exception
527      */
528     public <T> void Patch(T t, String sourceID, String transId, String path) throws AAIException {
529         String methodName = "Patch";
530         String url = "";
531         transId += ":" + UUID.randomUUID().toString();
532
533         int numRetries = 5;
534         ClientResponse cres = null;
535         int statusCode = -1;
536
537         try {
538             if (overrideLocalHost == null) {
539                 overrideLocalHost =
540                         AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
541             }
542             if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) {
543                 url = String.format(AAIConstants.AAI_LOCAL_REST, AAIConstants.AAI_RESOURCES_PORT,
544                         AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
545             } else {
546                 url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost,
547                         AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
548             }
549
550             do {
551
552                 cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
553                         .header("X-FromAppId", sourceID).header("X-HTTP-Method-Override", "PATCH")
554                         .type("application/merge-patch+json").entity(t).post(ClientResponse.class);
555
556                 statusCode = cres.getStatus();
557
558                 if (statusCode >= 200 && statusCode <= 299) {
559                     LOGGER.debug(methodName + "REST api PATCH was successful!");
560                     return;
561                 } else {
562                     LOGGER.debug(methodName + "Unable to make the patch request to url " + url + " so retrying");
563                 }
564
565                 numRetries--;
566
567             } while (numRetries >= 0);
568
569             LOGGER.debug(methodName + "Unable to make the patch request to url " + url + " even after trying = "
570                     + numRetries + " times.");
571             throw new AAIException("AAI_7116", methodName + " with status=" + statusCode + ", url=" + url + ", msg="
572                     + cres.getEntity(String.class));
573
574         } catch (AAIException e) {
575             throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());
576         } catch (Exception e) {
577             throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());
578
579         } finally {
580         }
581
582     }
583 }