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.security.KeyManagementException;
31 import java.security.KeyStoreException;
32 import java.security.NoSuchAlgorithmException;
33 import java.security.UnrecoverableKeyException;
34 import java.security.cert.CertificateException;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.UUID;
39 import org.onap.aai.exceptions.AAIException;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 public class RestController implements RestControllerInterface {
45 private static final String TARGET_NAME = "AAI";
46 private static final Logger LOGGER = LoggerFactory.getLogger(RestController.class);
48 private static Client client = null;
50 private String restSrvrBaseURL;
52 private String overrideLocalHost = null;
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=";
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/";
82 public static final String REST_APIPATH_VCE = "network/vces/vce/";
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/";
88 public RestController(String truststorePath, String truststorePassword, String keystorePath,
89 String keystorePassword) throws AAIException {
90 this.initRestClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
94 * Inits the rest client.
96 * @throws AAIException the AAI exception
98 public void initRestClient(String truststorePath, String truststorePassword, String keystorePath,
99 String keystorePassword) throws AAIException {
100 if (client == null) {
102 client = getHttpsAuthClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
103 } catch (KeyManagementException e) {
104 throw new AAIException("AAI_7117", "KeyManagementException in REST call to DB: " + e.toString());
105 } catch (Exception e) {
106 throw new AAIException("AAI_7117", " Exception in REST call to DB: " + e.toString());
111 public Client getHttpsAuthClient(String truststorePath, String truststorePassword, String keystorePath,
112 String keystorePassword) throws KeyManagementException, UnrecoverableKeyException, CertificateException,
113 NoSuchAlgorithmException, KeyStoreException, IOException {
114 return HttpsAuthClient.getClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
117 public Client getHttpsAuthClient() throws KeyManagementException, UnrecoverableKeyException, CertificateException,
118 NoSuchAlgorithmException, KeyStoreException, IOException, AAIException {
119 return HttpsAuthClient.getClient();
123 * Sets the rest srvr base URL.
125 * @param baseURL the base URL
126 * @throws AAIException the AAI exception
128 public void SetRestSrvrBaseURL(String baseURL) throws AAIException {
130 throw new AAIException("AAI_7117", "REST Server base URL cannot be null.");
131 restSrvrBaseURL = baseURL;
135 * Gets the rest srvr base URL.
137 * @return the rest srvr base URL
139 public String getRestSrvrBaseURL() {
140 return restSrvrBaseURL;
143 public <T> void Get(T t, String sourceID, String transId, String path, RestObject<T> restObject, boolean oldserver)
144 throws AAIException {
145 Get(t, sourceID, transId, path, restObject, oldserver, AAIConstants.AAI_RESOURCES_PORT);
149 * To do - optimization and automation. Also make it as generic as possible.
151 * @param <T> the generic type
153 * @param sourceID the source ID
154 * @param transId the trans id
155 * @param path the path
156 * @param restObject the rest object
157 * @param oldserver the oldserver
158 * @throws AAIException the AAI exception
160 @SuppressWarnings("unchecked")
161 public <T> void Get(T t, String sourceID, String transId, String path, RestObject<T> restObject, boolean oldserver,
162 int port) throws AAIException {
163 String methodName = "Get";
165 transId += ":" + UUID.randomUUID().toString();
167 LOGGER.debug(methodName + " start");
172 url = AAIConfig.get(AAIConstants.AAI_OLDSERVER_URL) + path;
174 if (overrideLocalHost == null) {
176 AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
178 if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) {
179 url = String.format(AAIConstants.AAI_LOCAL_REST, port,
180 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
182 url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost,
183 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
186 LOGGER.debug(url + " for the get REST API");
187 ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
188 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json")
189 .get(ClientResponse.class);
191 // System.out.println("cres.EntityInputSream()="+cres.getEntityInputStream().toString());
192 // System.out.println("cres.tostring()="+cres.toString());
194 if (cres.getStatus() == 200) {
195 // System.out.println(methodName + ": url=" + url);
196 t = (T) cres.getEntity(t.getClass());
198 LOGGER.debug(methodName + "REST api GET was successfull!");
200 // System.out.println(methodName + ": url=" + url + " failed with status=" + cres.getStatus());
201 throw new AAIException("AAI_7116", methodName + " with status=" + cres.getStatus() + ", url=" + url);
206 * To do - optimization and automation. Also make it as generic as possible.
208 * @param <T> the generic type
210 * @param sourceID the source ID
211 * @param transId the trans id
212 * @param path the path
213 * @param restObject the rest object
214 * @param oldserver the oldserver
215 * @throws AAIException the AAI exception
217 @SuppressWarnings("unchecked")
218 public <T> void Get(T t, String sourceID, String transId, String path, RestObject<T> restObject, String apiVersion)
219 throws AAIException {
220 String methodName = "Get";
222 transId += ":" + UUID.randomUUID().toString();
224 LOGGER.debug(methodName + " start");
228 url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path;
230 LOGGER.debug(url + " for the get REST API");
231 ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
232 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json")
233 .get(ClientResponse.class);
235 // System.out.println("cres.EntityInputSream()="+cres.getEntityInputStream().toString());
236 // System.out.println("cres.tostring()="+cres.toString());
238 if (cres.getStatus() == 200) {
239 // System.out.println(methodName + ": url=" + url);
240 t = (T) cres.getEntity(t.getClass());
242 LOGGER.debug(methodName + "REST api GET was successfull!");
244 // System.out.println(methodName + ": url=" + url + " failed with status=" + cres.getStatus());
245 throw new AAIException("AAI_7116", methodName + " with status=" + cres.getStatus() + ", url=" + url);
250 * Map json to object list.
252 * @param <T> the generic type
253 * @param typeDef the type def
254 * @param json the json
255 * @param clazz the clazz
257 * @throws Exception the exception
259 private <T> List<T> mapJsonToObjectList(T typeDef, String json, Class<?> clazz) throws Exception {
261 ObjectMapper mapper = new ObjectMapper();
262 System.out.println(json);
263 TypeFactory t = TypeFactory.defaultInstance();
264 list = mapper.readValue(json, t.constructCollectionType(ArrayList.class, clazz));
272 * @param <T> the generic type
274 * @param sourceID the source ID
275 * @param transId the trans id
276 * @param path the path
277 * @throws AAIException the AAI exception
279 public <T> void Put(T t, String sourceID, String transId, String path) throws AAIException {
280 Put(t, sourceID, transId, path, false, AAIConstants.AAI_RESOURCES_PORT);
286 * @param <T> the generic type
288 * @param sourceID the source ID
289 * @param transId the trans id
290 * @param path the path
291 * @throws AAIException the AAI exception
293 public <T> void Put(T t, String sourceID, String transId, String path, boolean oldserver) throws AAIException {
294 Put(t, sourceID, transId, path, oldserver, AAIConstants.AAI_RESOURCES_PORT);
300 * @param <T> the generic type
302 * @param sourceID the source ID
303 * @param transId the trans id
304 * @param path the path
305 * @param oldserver the oldserver
306 * @throws AAIException the AAI exception
308 public <T> void Put(T t, String sourceID, String transId, String path, boolean oldserver, int port)
309 throws AAIException {
310 String methodName = "Put";
312 transId += ":" + UUID.randomUUID().toString();
314 LOGGER.debug(methodName + " start");
317 url = AAIConfig.get(AAIConstants.AAI_OLDSERVER_URL) + path;
319 if (overrideLocalHost == null) {
321 AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
323 if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) {
324 url = String.format(AAIConstants.AAI_LOCAL_REST, port,
325 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
327 url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost,
328 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
332 ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
333 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t)
334 .put(ClientResponse.class);
336 // System.out.println("cres.tostring()="+cres.toString());
338 int statuscode = cres.getStatus();
339 if (statuscode >= 200 && statuscode <= 299) {
340 LOGGER.debug(methodName + ": url=" + url + ", request=" + path);
342 throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg="
343 + cres.getEntity(String.class));
350 * @param <T> the generic type
352 * @param sourceID the source ID
353 * @param transId the trans id
354 * @param path the path
355 * @param apiVersion version number
356 * @throws AAIException the AAI exception
358 public <T> void Put(T t, String sourceID, String transId, String path, String apiVersion) throws AAIException {
359 String methodName = "Put";
361 transId += ":" + UUID.randomUUID().toString();
363 LOGGER.debug(methodName + " start");
365 url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path;
367 ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
368 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t)
369 .put(ClientResponse.class);
371 // System.out.println("cres.tostring()="+cres.toString());
373 int statuscode = cres.getStatus();
374 if (statuscode >= 200 && statuscode <= 299) {
375 LOGGER.debug(methodName + ": url=" + url + ", request=" + path);
377 throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg="
378 + cres.getEntity(String.class));
382 public void Delete(String sourceID, String transId, String path) throws AAIException {
383 Delete(sourceID, transId, path, AAIConstants.AAI_RESOURCES_PORT);
389 * @param sourceID the source ID
390 * @param transId the trans id
391 * @param path the path
392 * @throws AAIException the AAI exception
394 public void Delete(String sourceID, String transId, String path, int port) throws AAIException {
395 String methodName = "Delete";
397 transId += ":" + UUID.randomUUID().toString();
399 LOGGER.debug(methodName + " start");
401 String request = "{}";
402 if (overrideLocalHost == null) {
403 overrideLocalHost = AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
405 if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) {
406 url = String.format(AAIConstants.AAI_LOCAL_REST, port,
407 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
409 url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost,
410 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
412 ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
413 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(request)
414 .delete(ClientResponse.class);
416 if (cres.getStatus() == 404) { // resource not found
417 LOGGER.info("Resource does not exist...: " + cres.getStatus() + ":" + cres.getEntity(String.class));
418 } else if (cres.getStatus() == 200 || cres.getStatus() == 204) {
419 LOGGER.info("Resource " + url + " deleted");
421 LOGGER.error("Deleting Resource failed: " + cres.getStatus() + ":" + cres.getEntity(String.class));
422 throw new AAIException("AAI_7116", "Error during DELETE");
426 public <T> String Post(T t, String sourceID, String transId, String path) throws Exception {
427 return Post(t, sourceID, transId, path, AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
433 * @param <T> the generic type
435 * @param sourceID the source ID
436 * @param transId the trans id
437 * @param path the path
438 * @param apiVersion the apiVersion
440 * @throws Exception the exception
442 public <T> String Post(T t, String sourceID, String transId, String path, String apiVersion) throws Exception {
443 String methodName = "Post";
445 transId += ":" + UUID.randomUUID().toString();
447 LOGGER.debug(methodName + " start");
451 url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path;
453 ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
454 .header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json").entity(t)
455 .post(ClientResponse.class);
457 int statuscode = cres.getStatus();
458 if (statuscode >= 200 && statuscode <= 299) {
459 LOGGER.debug(methodName + "REST api POST was successful!");
460 return cres.getEntity(String.class);
462 throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg="
463 + cres.getEntity(String.class));
466 } catch (AAIException e) {
467 throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());
468 } catch (Exception e) {
469 throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());
476 * Gets the single instance of RestController.
478 * @param <T> the generic type
479 * @param clazz the clazz
480 * @return single instance of RestController
481 * @throws IllegalAccessException the illegal access exception
482 * @throws InstantiationException the instantiation exception
484 public <T> T getInstance(Class<T> clazz) throws IllegalAccessException, InstantiationException {
485 return clazz.newInstance();
489 * Does resource exist.
491 * @param <T> the generic type
492 * @param resourcePath the resource path
493 * @param resourceClassName the resource class name
494 * @param fromAppId the from app id
495 * @param transId the trans id
501 * To check whether a resource exist or get a copy of the existing version of the resource
503 * Resourcepath: should contain the qualified resource path (including encoded unique key identifier value),
504 * resourceClassName: is the canonical name of the resource class name,
508 * Will return null (if the resource doesn’t exist) (or)
509 * Will return the specified resource from the Graph.
512 * LogicalLink llink = new LogicalLink();
513 * String resourceClassName = llink.getClass().getCanonicalName();
514 * llink = RestController.DoesResourceExist("network/logical-links/logical-link/" + <encoded-link-name>,
515 * resourceClassName, fromAppId, transId);
517 public <T> T DoesResourceExist(String resourcePath, String resourceClassName, String fromAppId, String transId) {
521 RestObject<T> restObj = new RestObject<T>();
522 @SuppressWarnings("unchecked")
523 T resourceObj = (T) getInstance(Class.forName(resourceClassName));
524 restObj.set(resourceObj);
525 Get(resourceObj, fromAppId, transId, resourcePath, restObj, false, AAIConstants.AAI_RESOURCES_PORT);
527 resourceObj = restObj.get();
528 if (resourceObj != null)
531 } catch (AAIException e) {
533 } catch (ClientHandlerException che) {
535 } catch (Exception e) {
545 * @param <T> the generic type
546 * @param sourceID the source ID
547 * @param transId the trans id
548 * @param path the path
549 * @throws AAIException the AAI exception
551 public <T> void Patch(T t, String sourceID, String transId, String path) throws AAIException {
552 String methodName = "Patch";
554 transId += ":" + UUID.randomUUID().toString();
557 ClientResponse cres = null;
561 if (overrideLocalHost == null) {
563 AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
565 if (AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT.equals(overrideLocalHost)) {
566 url = String.format(AAIConstants.AAI_LOCAL_REST, AAIConstants.AAI_RESOURCES_PORT,
567 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
569 url = String.format(AAIConstants.AAI_LOCAL_REST_OVERRIDE, overrideLocalHost,
570 AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
575 cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
576 .header("X-FromAppId", sourceID).header("X-HTTP-Method-Override", "PATCH")
577 .type("application/merge-patch+json").entity(t).post(ClientResponse.class);
579 statusCode = cres.getStatus();
581 if (statusCode >= 200 && statusCode <= 299) {
582 LOGGER.debug(methodName + "REST api PATCH was successful!");
585 LOGGER.debug(methodName + "Unable to make the patch request to url " + url + " so retrying");
590 } while (numRetries >= 0);
592 LOGGER.debug(methodName + "Unable to make the patch request to url " + url + " even after trying = "
593 + numRetries + " times.");
594 throw new AAIException("AAI_7116", methodName + " with status=" + statusCode + ", url=" + url + ", msg="
595 + cres.getEntity(String.class));
597 } catch (AAIException e) {
598 throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());
599 } catch (Exception e) {
600 throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());