2 * ============LICENSE_START=======================================================
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
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.aai.util;
23 import com.fasterxml.jackson.databind.ObjectMapper;
24 import com.fasterxml.jackson.databind.type.TypeFactory;
25 import com.sun.jersey.api.client.Client;
26 import com.sun.jersey.api.client.ClientHandlerException;
27 import com.sun.jersey.api.client.ClientResponse;
29 import java.io.IOException;
30 import java.lang.reflect.InvocationTargetException;
31 import java.security.KeyManagementException;
32 import java.security.KeyStoreException;
33 import java.security.NoSuchAlgorithmException;
34 import java.security.UnrecoverableKeyException;
35 import java.security.cert.CertificateException;
36 import java.util.ArrayList;
37 import java.util.List;
38 import java.util.UUID;
40 import org.onap.aai.exceptions.AAIException;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
44 public class RestController implements RestControllerInterface {
46 private static final String TARGET_NAME = "AAI";
47 private static final Logger LOGGER = LoggerFactory.getLogger(RestController.class);
49 private static Client client = null;
51 private String restSrvrBaseURL;
53 private String overrideLocalHost = null;
55 // To do - Come up with helper function that will automatically
56 // generate the REST API path based on path parameter(s) and query parameter(s)!
57 public static final String REST_APIPATH_COMPLEXES = "cloud-infrastructure/complexes";
58 public static final String REST_APIPATH_COMPLEX = "cloud-infrastructure/complexes/complex/";
59 public static final String REST_APIPATH_PSERVERS = "cloud-infrastructure/pservers";
60 public static final String REST_APIPATH_PSERVER = "cloud-infrastructure/pservers/pserver/";
61 public static final String REST_APIPATH_PHYSICALLINKS = "network/physical-links/";
62 public static final String REST_APIPATH_PHYSICALLINK = "network/physical-links/physical-link/";
63 public static final String REST_APIPATH_PINTERFACES = "network/p-interfaces/";
64 public static final String REST_APIPATH_PINTERFACE = "network/p-interfaces/p-interface/";
65 public static final String REST_APIPATH_VPLSPES = "network/vpls-pes/";
66 public static final String REST_APIPATH_VPLSPE = "network/vpls-pes/vpls-pe/";
67 public static final String REST_APIPATH_UPDATE = "actions/update/";
68 public static final String REST_APIPATH_SEARCH = "search/nodes-query?search-node-type=";
70 public static final String REST_APIPATH_CLOUDREGION = "cloud-infrastructure/cloud-regions/cloud-region/";
71 public static final String REST_APIPATH_TENANT = "cloud-infrastructure/tenants/tenant/";
72 public static final String REST_APIPATH_VIRTUAL_DATA_CENTER =
73 "cloud-infrastructure/virtual-data-centers/virtual-data-center/";
74 public static final String REST_APIPATH_VIRTUAL_DATA_CENTERS = "cloud-infrastructure/virtual-data-centers/";
75 public static final String REST_APIPATH_GENERIC_VNF = "network/generic-vnfs/generic-vnf/";
76 public static final String REST_APIPATH_GENERIC_VNFS = "network/generic-vnfs";
77 public static final String REST_APIPATH_L3_NETWORK = "network/l3-networks/l3-network/";
78 public static final String REST_APIPATH_L3_NETWORKS = "network/l3-networks";
79 public static final String REST_APIPATH_INSTANCE_GROUP = "network/instance-groups/instance-group";
80 public static final String REST_APIPATH_INSTANCE_GROUPS = "network/instance-groups";
81 public static final String REST_APIPATH_VFMODULE = "nodes/vf-modules/vf-module/";
83 public static final String REST_APIPATH_VCE = "network/vces/vce/";
85 public static final String REST_APIPATH_SERVICE = "service-design-and-creation/services/service/";
86 public static final String REST_APIPATH_LOGICALLINKS = "network/logical-links/";
87 public static final String REST_APIPATH_LOGICALLINK = "network/logical-links/logical-link/";
89 public RestController(String truststorePath, String truststorePassword, String keystorePath,
90 String keystorePassword) throws AAIException {
91 this.initRestClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
95 * Inits the rest client.
97 * @throws AAIException the AAI exception
99 public void initRestClient(String truststorePath, String truststorePassword, String keystorePath,
100 String keystorePassword) throws AAIException {
101 if (client == null) {
103 client = getHttpsAuthClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
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());
112 public Client getHttpsAuthClient(String truststorePath, String truststorePassword, String keystorePath,
113 String keystorePassword) throws KeyManagementException, UnrecoverableKeyException, CertificateException,
114 NoSuchAlgorithmException, KeyStoreException, IOException {
115 return HttpsAuthClient.getClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
118 public Client getHttpsAuthClient() throws KeyManagementException, UnrecoverableKeyException, CertificateException,
119 NoSuchAlgorithmException, KeyStoreException, IOException, AAIException {
120 return HttpsAuthClient.getClient();
124 * Sets the rest srvr base URL.
126 * @param baseURL the base URL
127 * @throws AAIException the AAI exception
129 public void SetRestSrvrBaseURL(String baseURL) throws AAIException {
131 throw new AAIException("AAI_7117", "REST Server base URL cannot be null.");
132 restSrvrBaseURL = baseURL;
136 * Gets the rest srvr base URL.
138 * @return the rest srvr base URL
140 public String getRestSrvrBaseURL() {
141 return restSrvrBaseURL;
144 public <T> void Get(T t, String sourceID, String transId, String path, RestObject<T> restObject, boolean oldserver)
145 throws AAIException {
146 Get(t, sourceID, transId, path, restObject, oldserver, AAIConstants.AAI_RESOURCES_PORT);
150 * To do - optimization and automation. Also make it as generic as possible.
152 * @param <T> the generic type
154 * @param sourceID the source ID
155 * @param transId the trans id
156 * @param path the path
157 * @param restObject the rest object
158 * @param oldserver the oldserver
159 * @throws AAIException the AAI exception
161 @SuppressWarnings("unchecked")
162 public <T> void Get(T t, String sourceID, String transId, String path, RestObject<T> restObject, boolean oldserver,
163 int port) throws AAIException {
164 String methodName = "Get";
166 transId += ":" + UUID.randomUUID().toString();
168 LOGGER.debug(methodName + " start");
173 url = AAIConfig.get(AAIConstants.AAI_OLDSERVER_URL) + path;
175 if (overrideLocalHost == null) {
177 AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
179 if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) {
180 url = String.format(AAIConstants.AAI_LOCAL_REST, port,
181 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
183 url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost,
184 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
187 LOGGER.debug(url + " for the get REST API");
188 ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
189 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json")
190 .get(ClientResponse.class);
192 // System.out.println("cres.EntityInputSream()="+cres.getEntityInputStream().toString());
193 // System.out.println("cres.tostring()="+cres.toString());
195 if (cres.getStatus() == 200) {
196 // System.out.println(methodName + ": url=" + url);
197 t = (T) cres.getEntity(t.getClass());
199 LOGGER.debug(methodName + "REST api GET was successfull!");
201 // System.out.println(methodName + ": url=" + url + " failed with status=" + cres.getStatus());
202 throw new AAIException("AAI_7116", methodName + " with status=" + cres.getStatus() + ", url=" + url);
207 * To do - optimization and automation. Also make it as generic as possible.
209 * @param <T> the generic type
211 * @param sourceID the source ID
212 * @param transId the trans id
213 * @param path the path
214 * @param restObject the rest object
215 * @param oldserver the oldserver
216 * @throws AAIException the AAI exception
218 @SuppressWarnings("unchecked")
219 public <T> void Get(T t, String sourceID, String transId, String path, RestObject<T> restObject, String apiVersion)
220 throws AAIException {
221 String methodName = "Get";
223 transId += ":" + UUID.randomUUID().toString();
225 LOGGER.debug(methodName + " start");
229 url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path;
231 LOGGER.debug(url + " for the get REST API");
232 ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
233 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json")
234 .get(ClientResponse.class);
236 // System.out.println("cres.EntityInputSream()="+cres.getEntityInputStream().toString());
237 // System.out.println("cres.tostring()="+cres.toString());
239 if (cres.getStatus() == 200) {
240 // System.out.println(methodName + ": url=" + url);
241 t = (T) cres.getEntity(t.getClass());
243 LOGGER.debug(methodName + "REST api GET was successfull!");
245 // System.out.println(methodName + ": url=" + url + " failed with status=" + cres.getStatus());
246 throw new AAIException("AAI_7116", methodName + " with status=" + cres.getStatus() + ", url=" + url);
251 * Map json to object list.
253 * @param <T> the generic type
254 * @param typeDef the type def
255 * @param json the json
256 * @param clazz the clazz
258 * @throws Exception the exception
260 private <T> List<T> mapJsonToObjectList(T typeDef, String json, Class<?> clazz) throws Exception {
262 ObjectMapper mapper = new ObjectMapper();
263 System.out.println(json);
264 TypeFactory t = TypeFactory.defaultInstance();
265 list = mapper.readValue(json, t.constructCollectionType(ArrayList.class, clazz));
273 * @param <T> the generic type
275 * @param sourceID the source ID
276 * @param transId the trans id
277 * @param path the path
278 * @throws AAIException the AAI exception
280 public <T> void Put(T t, String sourceID, String transId, String path) throws AAIException {
281 Put(t, sourceID, transId, path, false, AAIConstants.AAI_RESOURCES_PORT);
287 * @param <T> the generic type
289 * @param sourceID the source ID
290 * @param transId the trans id
291 * @param path the path
292 * @throws AAIException the AAI exception
294 public <T> void Put(T t, String sourceID, String transId, String path, boolean oldserver) throws AAIException {
295 Put(t, sourceID, transId, path, oldserver, AAIConstants.AAI_RESOURCES_PORT);
301 * @param <T> the generic type
303 * @param sourceID the source ID
304 * @param transId the trans id
305 * @param path the path
306 * @param oldserver the oldserver
307 * @throws AAIException the AAI exception
309 public <T> void Put(T t, String sourceID, String transId, String path, boolean oldserver, int port)
310 throws AAIException {
311 String methodName = "Put";
313 transId += ":" + UUID.randomUUID().toString();
315 LOGGER.debug(methodName + " start");
318 url = AAIConfig.get(AAIConstants.AAI_OLDSERVER_URL) + path;
320 if (overrideLocalHost == null) {
322 AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
324 if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) {
325 url = String.format(AAIConstants.AAI_LOCAL_REST, port,
326 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
328 url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost,
329 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
333 ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
334 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t)
335 .put(ClientResponse.class);
337 // System.out.println("cres.tostring()="+cres.toString());
339 int statuscode = cres.getStatus();
340 if (statuscode >= 200 && statuscode <= 299) {
341 LOGGER.debug(methodName + ": url=" + url + ", request=" + path);
343 throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg="
344 + cres.getEntity(String.class));
351 * @param <T> the generic type
353 * @param sourceID the source ID
354 * @param transId the trans id
355 * @param path the path
356 * @param apiVersion version number
357 * @throws AAIException the AAI exception
359 public <T> void Put(T t, String sourceID, String transId, String path, String apiVersion) throws AAIException {
360 String methodName = "Put";
362 transId += ":" + UUID.randomUUID().toString();
364 LOGGER.debug(methodName + " start");
366 url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path;
368 ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
369 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t)
370 .put(ClientResponse.class);
372 // System.out.println("cres.tostring()="+cres.toString());
374 int statuscode = cres.getStatus();
375 if (statuscode >= 200 && statuscode <= 299) {
376 LOGGER.debug(methodName + ": url=" + url + ", request=" + path);
378 throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg="
379 + cres.getEntity(String.class));
383 public void Delete(String sourceID, String transId, String path) throws AAIException {
384 Delete(sourceID, transId, path, AAIConstants.AAI_RESOURCES_PORT);
390 * @param sourceID the source ID
391 * @param transId the trans id
392 * @param path the path
393 * @throws AAIException the AAI exception
395 public void Delete(String sourceID, String transId, String path, int port) throws AAIException {
396 String methodName = "Delete";
398 transId += ":" + UUID.randomUUID().toString();
400 LOGGER.debug(methodName + " start");
402 String request = "{}";
403 if (overrideLocalHost == null) {
404 overrideLocalHost = AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
406 if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) {
407 url = String.format(AAIConstants.AAI_LOCAL_REST, port,
408 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
410 url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost,
411 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
413 ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
414 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(request)
415 .delete(ClientResponse.class);
417 if (cres.getStatus() == 404) { // resource not found
418 LOGGER.info("Resource does not exist...: " + cres.getStatus() + ":" + cres.getEntity(String.class));
419 } else if (cres.getStatus() == 200 || cres.getStatus() == 204) {
420 LOGGER.info("Resource " + url + " deleted");
422 LOGGER.error("Deleting Resource failed: " + cres.getStatus() + ":" + cres.getEntity(String.class));
423 throw new AAIException("AAI_7116", "Error during DELETE");
427 public <T> String Post(T t, String sourceID, String transId, String path) throws Exception {
428 return Post(t, sourceID, transId, path, AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
434 * @param <T> the generic type
436 * @param sourceID the source ID
437 * @param transId the trans id
438 * @param path the path
439 * @param apiVersion the apiVersion
441 * @throws Exception the exception
443 public <T> String Post(T t, String sourceID, String transId, String path, String apiVersion) throws Exception {
444 String methodName = "Post";
446 transId += ":" + UUID.randomUUID().toString();
448 LOGGER.debug(methodName + " start");
452 url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path;
454 ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
455 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t)
456 .post(ClientResponse.class);
458 int statuscode = cres.getStatus();
459 if (statuscode >= 200 && statuscode <= 299) {
460 LOGGER.debug(methodName + "REST api POST was successful!");
461 return cres.getEntity(String.class);
463 throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg="
464 + cres.getEntity(String.class));
467 } catch (AAIException e) {
468 throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());
469 } catch (Exception e) {
470 throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());
477 * Gets the single instance of RestController.
479 * @param <T> the generic type
480 * @param clazz the clazz
481 * @return single instance of RestController
482 * @throws IllegalAccessException the illegal access exception
483 * @throws InstantiationException the instantiation exception
484 * @throws SecurityException
485 * @throws NoSuchMethodException
486 * @throws InvocationTargetException
487 * @throws IllegalArgumentException
489 public <T> T getInstance(Class<T> clazz) throws IllegalAccessException, InstantiationException,
490 IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
491 return clazz.getDeclaredConstructor().newInstance();
495 * Does resource exist.
497 * @param <T> the generic type
498 * @param resourcePath the resource path
499 * @param resourceClassName the resource class name
500 * @param fromAppId the from app id
501 * @param transId the trans id
507 * To check whether a resource exist or get a copy of the existing version of the resource
509 * Resourcepath: should contain the qualified resource path (including encoded unique key identifier value),
510 * resourceClassName: is the canonical name of the resource class name,
514 * Will return null (if the resource doesn’t exist) (or)
515 * Will return the specified resource from the Graph.
518 * LogicalLink llink = new LogicalLink();
519 * String resourceClassName = llink.getClass().getCanonicalName();
520 * llink = RestController.DoesResourceExist("network/logical-links/logical-link/" + <encoded-link-name>,
521 * resourceClassName, fromAppId, transId);
523 public <T> T DoesResourceExist(String resourcePath, String resourceClassName, String fromAppId, String transId) {
527 RestObject<T> restObj = new RestObject<T>();
528 @SuppressWarnings("unchecked")
529 T resourceObj = (T) getInstance(Class.forName(resourceClassName));
530 restObj.set(resourceObj);
531 Get(resourceObj, fromAppId, transId, resourcePath, restObj, false, AAIConstants.AAI_RESOURCES_PORT);
533 resourceObj = restObj.get();
534 if (resourceObj != null)
537 } catch (AAIException e) {
539 } catch (ClientHandlerException che) {
541 } catch (Exception e) {
551 * @param <T> the generic type
552 * @param sourceID the source ID
553 * @param transId the trans id
554 * @param path the path
555 * @throws AAIException the AAI exception
557 public <T> void Patch(T t, String sourceID, String transId, String path) throws AAIException {
558 String methodName = "Patch";
560 transId += ":" + UUID.randomUUID().toString();
563 ClientResponse cres = null;
567 if (overrideLocalHost == null) {
569 AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
571 if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) {
572 url = String.format(AAIConstants.AAI_LOCAL_REST, AAIConstants.AAI_RESOURCES_PORT,
573 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
575 url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost,
576 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
581 cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
582 .header("X-FromAppId", sourceID).header("X-HTTP-Method-Override", "PATCH")
583 .type("application/merge-patch+json").entity(t).post(ClientResponse.class);
585 statusCode = cres.getStatus();
587 if (statusCode >= 200 && statusCode <= 299) {
588 LOGGER.debug(methodName + "REST api PATCH was successful!");
591 LOGGER.debug(methodName + "Unable to make the patch request to url " + url + " so retrying");
596 } while (numRetries >= 0);
598 LOGGER.debug(methodName + "Unable to make the patch request to url " + url + " even after trying = "
599 + numRetries + " times.");
600 throw new AAIException("AAI_7116", methodName + " with status=" + statusCode + ", url=" + url + ", msg="
601 + cres.getEntity(String.class));
603 } catch (AAIException e) {
604 throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());
605 } catch (Exception e) {
606 throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());