2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Modifications Copyright (C) 2018 IBM.
9 * ================================================================================
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 * ============LICENSE_END=========================================================
24 package org.onap.ccsdk.sli.adaptors.aai;
26 import java.io.BufferedReader;
27 import java.io.ByteArrayInputStream;
29 import java.io.FileInputStream;
30 import java.io.InputStream;
31 import java.io.InputStreamReader;
32 import java.io.OutputStreamWriter;
33 import java.lang.reflect.Field;
34 import java.lang.reflect.InvocationTargetException;
35 import java.lang.reflect.Method;
36 import java.lang.reflect.Modifier;
37 import java.net.HttpURLConnection;
38 import java.net.MalformedURLException;
39 import java.net.URISyntaxException;
41 import java.nio.charset.StandardCharsets;
42 import java.security.KeyManagementException;
43 import java.security.KeyStore;
44 import java.security.NoSuchAlgorithmException;
45 import java.text.SimpleDateFormat;
46 import java.util.Properties;
48 import javax.net.ssl.HttpsURLConnection;
49 import javax.net.ssl.KeyManagerFactory;
50 import javax.net.ssl.SSLContext;
51 import javax.net.ssl.SSLSession;
52 import javax.net.ssl.SSLSocketFactory;
54 import org.apache.commons.codec.binary.Base64;
55 import org.apache.commons.lang3.ObjectUtils;
56 import org.onap.ccsdk.sli.adaptors.aai.AAIService.TransactionIdTracker;
57 import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum;
58 import org.onap.ccsdk.sli.adaptors.aai.data.ErrorResponse;
59 import org.onap.ccsdk.sli.adaptors.aai.data.RequestError;
60 import org.onap.ccsdk.sli.adaptors.aai.data.ResourceVersion;
61 import org.onap.ccsdk.sli.adaptors.aai.data.ServiceException;
62 import org.onap.ccsdk.sli.adaptors.aai.update.BulkUpdateResponseData;
63 import org.onap.ccsdk.sli.core.sli.MetricLogger;
64 import org.onap.logging.ref.slf4j.ONAPLogConstants;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
68 import com.fasterxml.jackson.databind.DeserializationFeature;
69 import com.fasterxml.jackson.databind.ObjectMapper;
71 import org.apache.http.client.utils.URIBuilder;
72 import org.apache.http.impl.EnglishReasonPhraseCatalog;
75 * The AAIClientRESTExecutor class provides CRUD API for AAI Client service.
76 * @author Rich Tabedzki
78 public class AAIClientRESTExecutor implements AAIExecutorInterface {
80 private final String truststorePath;
81 private final String truststorePassword;
82 private final String keystorePath;
83 private final String keystorePassword;
84 private final Boolean ignoreCertificateHostError;
85 // authentication credentials
86 private String userName;
87 private String userPassword;
88 private final String applicationId;
89 private static final String HTTP_URL_CONNECTION_RESULT="HttpURLConnection result: {} : {}";
90 private static final String ENTRY_DOESNT_EXIST="Entry does not exist.";
94 * @param props - properties to initialize an instance.
96 public AAIClientRESTExecutor(Properties props) {
99 userName = props.getProperty(AAIService.CLIENT_NAME);
100 userPassword = props.getProperty(AAIService.CLIENT_PWWD);
102 if(userName == null || userName.isEmpty()){
103 LOG.debug("Basic user name is not set");
105 if(userPassword == null || userPassword.isEmpty()) {
106 LOG.debug("Basic password is not set");
109 truststorePath = props.getProperty(AAIService.TRUSTSTORE_PATH);
110 truststorePassword = props.getProperty(AAIService.TRUSTSTORE_PSSWD);
111 keystorePath = props.getProperty(AAIService.KEYSTORE_PATH);
112 keystorePassword = props.getProperty(AAIService.KEYSTORE_PSSWD);
114 String tmpApplicationId =props.getProperty(AAIService.APPLICATION_ID);
115 if(tmpApplicationId == null || tmpApplicationId.isEmpty()) {
116 tmpApplicationId = "SDNC";
118 applicationId = tmpApplicationId;
120 String iche = props.getProperty(AAIService.CERTIFICATE_HOST_ERROR);
121 boolean host_error = false;
122 if(iche != null && !iche.isEmpty()) {
123 host_error = Boolean.valueOf(iche);
126 ignoreCertificateHostError = host_error;
128 HttpsURLConnection.setDefaultHostnameVerifier( (String string,SSLSession ssls) -> {
129 return ignoreCertificateHostError;
133 if(truststorePath != null && truststorePassword != null && (new File(truststorePath)).exists()) {
134 System.setProperty("javax.net.ssl.trustStore", truststorePath);
135 System.setProperty("javax.net.ssl.trustStorePassword", truststorePassword);
138 if(keystorePath != null && keystorePassword != null && (new File(keystorePath)).exists())
140 //both jersey and HttpURLConnection can use this
141 SSLContext ctx = null;
143 ctx = SSLContext.getInstance("TLS");
145 KeyManagerFactory kmf = null;
146 try (FileInputStream fin = new FileInputStream(keystorePath)){
147 String storeType = "PKCS12";
148 String def = KeyStore.getDefaultType();
149 kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
151 String extension = keystorePath.substring(keystorePath.lastIndexOf(".") + 1);
153 if(extension != null && !extension.isEmpty() && "JKS".equalsIgnoreCase(extension)) {
156 KeyStore ks = KeyStore.getInstance(storeType);
158 char[] pwd = keystorePassword.toCharArray();
161 } catch (Exception ex) {
162 LOG.error("AAIResource", ex);
164 if (ObjectUtils.anyNotNull(kmf)) {
165 ctx.init(kmf.getKeyManagers(), null, null);
169 LOG.debug("SSLContext created");
171 } catch (KeyManagementException | NoSuchAlgorithmException exc) {
172 LOG.error("AAIResource", exc);
177 Field methodsField = HttpURLConnection.class.getDeclaredField("methods");
178 methodsField.setAccessible(true);
179 // get the methods field modifiers
180 Field modifiersField = Field.class.getDeclaredField("modifiers");
181 // bypass the "private" modifier
182 modifiersField.setAccessible(true);
184 // remove the "final" modifier
185 modifiersField.setInt(methodsField, methodsField.getModifiers() & ~Modifier.FINAL);
187 /* valid HTTP methods */
189 "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "PATCH"
191 // set the new methods - including patch
192 methodsField.set(null, methods);
194 } catch (SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchFieldException e) {
195 LOG.warn("Adding PATCH method", e);
197 LOG.info("AAIResource.ctor initialized.");
201 private static final Logger LOG = LoggerFactory.getLogger(AAIService.class);
202 private static final String NOT_PROVIDED = "NOT PROVIDED";
203 private final MetricLogger ml = new MetricLogger();
205 private SSLContext CTX;
208 private int connection_timeout = 300000;
210 private int read_timeout = 300000;
213 * Returns an String that contains JSON data returned from the AAI Server.
215 * This method always returns immediately, whether or not the
218 * @param request an instance of AAIRequiest representing
219 * the request made by DirectedGraph node.
220 * @return the JSON based representation of data instance requested.
224 public String get(AAIRequest request) throws AAIServiceException {
225 String response = null;
226 InputStream inputStream = null;
227 HttpURLConnection con = null;
228 URL requestUrl = null;
230 StringBuilder errorStringBuilder = new StringBuilder();
234 if(request.getRequestObject() != null) {
235 requestUrl = request.getRequestUrl(HttpMethod.POST, null);
236 requestUrl = appendDepth(requestUrl, request);
237 LOG.info(String.format("%s : %s", HttpMethod.GET, requestUrl.toString()));
238 con = getConfiguredConnection(requestUrl, HttpMethod.POST);
239 String json_text = request.toJSONString();
240 LOGwriteDateTrace("data", json_text);
241 logMetricRequest("POST "+requestUrl.toString(), json_text, requestUrl.toString());
242 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
243 osw.write(json_text);
246 requestUrl = request.getRequestUrl(HttpMethod.GET, null);
247 requestUrl = appendDepth(requestUrl, request);
248 LOG.info(String.format("%s : %s", HttpMethod.GET, requestUrl.toString()));
249 con = getConfiguredConnection(requestUrl, HttpMethod.GET);
250 logMetricRequest("GET "+requestUrl.toString(), "", requestUrl.toString());
254 int responseCode = con.getResponseCode();
255 if (responseCode == HttpURLConnection.HTTP_OK) {
256 inputStream = con.getInputStream();
258 inputStream = con.getErrorStream();
260 String responseMessage = null;
262 responseMessage = con.getResponseMessage();
263 } catch(Exception exc) {
264 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
266 if(responseMessage == null)
267 responseMessage = NOT_PROVIDED;
270 // Process the response
271 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
272 logMetricResponse(responseCode, responseMessage);
274 if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8));
275 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
277 ObjectMapper mapper = AAIService.getObjectMapper();
279 if (responseCode == HttpURLConnection.HTTP_OK) {
280 StringBuilder stringBuilder = new StringBuilder();
282 while( ( line = reader.readLine() ) != null ) {
283 stringBuilder.append( line );
285 response = stringBuilder.toString();
287 Object object = mapper.readValue(response, Object.class);
288 LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, responseMessage, mapper.writeValueAsString(object));
289 } catch(Exception exc) {
290 LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, responseMessage, mapper.writeValueAsString(response));
292 } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
293 LOGwriteEndingTrace(responseCode, responseMessage, ENTRY_DOESNT_EXIST);
294 ErrorResponse errorresponse = null;
296 errorresponse = mapper.readValue(reader, ErrorResponse.class);
297 } catch(Exception exc) {
298 errorresponse = new ErrorResponse();
299 RequestError requestError = new RequestError();
300 ServiceException serviceException = new ServiceException();
301 serviceException.setText(ENTRY_DOESNT_EXIST);
302 requestError.setServiceException(serviceException);
303 errorresponse.setRequestError(requestError );
305 throw new AAIServiceException(responseCode, errorresponse);
306 } else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
307 StringBuilder stringBuilder = new StringBuilder();
309 while( ( line = reader.readLine() ) != null ) {
310 stringBuilder.append( line );
312 LOGwriteEndingTrace(responseCode, responseMessage, stringBuilder.toString());
313 ServiceException serviceException = new ServiceException();
314 serviceException.setMessageId("HTTP_UNAUTHORIZED");
315 serviceException.setText(stringBuilder.toString());
316 RequestError requestError = new RequestError();
317 requestError.setServiceException(serviceException);
318 ErrorResponse errorresponse = new ErrorResponse();
319 errorresponse.setRequestError(requestError);
320 throw new AAIServiceException(responseCode, errorresponse);
323 while( ( line = reader.readLine() ) != null ) {
324 errorStringBuilder.append("\n").append( line );
327 ErrorResponse errorresponse = mapper.readValue(errorStringBuilder.toString(), ErrorResponse.class);
328 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
329 throw new AAIServiceException(responseCode, errorresponse);
332 } catch(AAIServiceException aaiexc) {
334 } catch (Exception exc) {
335 LOG.warn(errorStringBuilder.toString(), exc);
336 throw new AAIServiceException(exc);
338 if(inputStream != null){
341 } catch(Exception exc) {
350 * Returns an String that contains JSON data returned from the AAI Server.
352 * This method always returns immediately, whether or not the
355 * @param request an instance of AAIRequiest representing
356 * the request made by DirectedGraph node.
357 * @return the JSON based representation of data instance requested.
361 public String post(AAIRequest request) throws AAIServiceException {
362 InputStream inputStream = null;
365 String resourceVersion = null;
366 AAIDatum instance = request.getRequestObject();
369 Method getResourceVersionMethod = instance.getClass().getMethod("getResourceVersion");
370 if(getResourceVersionMethod != null){
372 Object object = getResourceVersionMethod.invoke(instance);
374 resourceVersion = object.toString();
375 } catch (InvocationTargetException exc) {
379 } catch(Exception exc) {
383 URL requestUrl = request.getRequestUrl(HttpMethod.PUT, resourceVersion);
384 HttpURLConnection con = getConfiguredConnection(requestUrl, HttpMethod.PUT);
385 String jsonText = request.toJSONString();
386 LOGwriteDateTrace("data", jsonText);
389 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
394 logMetricRequest("PUT "+requestUrl.toString(), jsonText, requestUrl.toString());
398 int responseCode = con.getResponseCode();
399 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
400 inputStream = con.getInputStream();
402 inputStream = con.getErrorStream();
404 String responseMessage = null;
406 responseMessage = con.getResponseMessage();
407 } catch(Exception exc) {
408 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
410 if(responseMessage == null)
411 responseMessage = NOT_PROVIDED;
414 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
415 logMetricResponse(responseCode, responseMessage);
417 // Process the response
418 ObjectMapper mapper = AAIService.getObjectMapper();
419 BufferedReader reader;
421 reader = new BufferedReader( new InputStreamReader( inputStream ) );
422 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
424 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
425 StringBuilder stringBuilder = new StringBuilder();
427 while( ( line = reader.readLine() ) != null ) {
428 stringBuilder.append( line );
430 LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder.length() > 0) ? stringBuilder.toString() : "{no-data}");
431 return stringBuilder.toString();
433 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
434 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
436 throw new AAIServiceException(responseCode, errorresponse);
438 } catch(AAIServiceException aaiexc) {
440 } catch (Exception exc) {
441 LOG.warn("AAIRequestExecutor.post", exc);
442 throw new AAIServiceException(exc);
445 if(inputStream != null)
447 } catch (Exception exc) {
448 LOG.warn("AAIRequestExecutor.post", exc);
454 * Returns Boolean that contains completion state of the command executed.
456 * This method always returns immediately, whether or not the
459 * @param request an instance of AAIRequiest representing
460 * @param resourceVersion a resource version of the data instacne to be deleted.
461 * the request made by DirectedGraph node.
462 * @return completion state of the command.
466 public Boolean delete(AAIRequest request, String resourceVersion) throws AAIServiceException {
467 Boolean response = null;
468 InputStream inputStream = null;
470 if(resourceVersion == null) {
471 throw new AAIServiceException("resource-version is required for DELETE request");
475 URL requestUrl = request.getRequestUrl(HttpMethod.DELETE, resourceVersion);
476 HttpURLConnection conn = getConfiguredConnection(requestUrl, HttpMethod.DELETE);
477 logMetricRequest("DELETE "+requestUrl.getPath(), "", requestUrl.getPath());
478 conn.setDoOutput(true);
481 int responseCode = conn.getResponseCode();
482 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
483 inputStream = conn.getInputStream();
485 inputStream = conn.getErrorStream();
487 String responseMessage = null;
489 responseMessage = conn.getResponseMessage();
490 } catch(Exception exc) {
491 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
493 if(responseMessage == null)
494 responseMessage = NOT_PROVIDED;
497 // Process the response
498 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
499 logMetricResponse(responseCode, responseMessage);
501 if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8));
502 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
505 ObjectMapper mapper = AAIService.getObjectMapper();
507 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
508 StringBuilder stringBuilder = new StringBuilder();
510 while( ( line = reader.readLine() ) != null ) {
511 stringBuilder.append( line );
513 LOGwriteEndingTrace(responseCode, responseMessage, stringBuilder.toString());
515 } else if(responseCode == HttpURLConnection.HTTP_NOT_FOUND ) {
516 LOGwriteEndingTrace(responseCode, responseMessage, ENTRY_DOESNT_EXIST);
519 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
520 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
521 throw new AAIServiceException(responseCode, errorresponse);
523 } catch(AAIServiceException aaiexc) {
525 } catch (Exception exc) {
526 LOG.warn("delete", exc);
527 throw new AAIServiceException(exc);
529 if(inputStream != null){
532 } catch(Exception exc) {
533 LOG.warn("delete", exc);
541 * Returns an String that contains JSON data returned from the AAI Server.
543 * This method always returns immediately, whether or not the
546 * @param request an instance of AAIRequiest representing
547 * the request made by DirectedGraph node.
548 * @param clas an definition of the class for which data will be returned
549 * @return the instance of the class with data.
553 public Object query(AAIRequest request, Class clas) throws AAIServiceException {
554 Object response = null;
555 InputStream inputStream = null;
558 URL requestUrl = request.getRequestQueryUrl(HttpMethod.GET);
559 HttpURLConnection con = getConfiguredConnection(requestUrl, HttpMethod.GET);
560 logMetricRequest("GET "+requestUrl.getPath(), "", requestUrl.getPath());
563 int responseCode = con.getResponseCode();
564 if (responseCode == HttpURLConnection.HTTP_OK) {
565 inputStream = con.getInputStream();
567 inputStream = con.getErrorStream();
569 String responseMessage = null;
571 responseMessage = con.getResponseMessage();
572 } catch(Exception exc) {
573 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
575 if(responseMessage == null)
576 responseMessage = NOT_PROVIDED;
579 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
580 logMetricResponse(responseCode, responseMessage);
581 ObjectMapper mapper = AAIService.getObjectMapper();
583 if (responseCode == HttpURLConnection.HTTP_OK) {
584 // Process the response
585 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
586 response = mapper.readValue(reader, clas);
587 LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, "SUCCESS", mapper.writeValueAsString(response));
588 } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
589 LOGwriteEndingTrace(responseCode, "HTTP_NOT_FOUND", ENTRY_DOESNT_EXIST);
592 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
593 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
594 LOGwriteEndingTrace(responseCode, "FAILURE", mapper.writeValueAsString(errorresponse));
595 throw new AAIServiceException(responseCode, errorresponse);
598 } catch(AAIServiceException aaiexc) {
600 } catch (Exception exc) {
601 LOG.warn("GET", exc);
602 throw new AAIServiceException(exc);
604 if(inputStream != null){
607 } catch(Exception exc) {
608 LOG.warn("GET", exc);
616 public Boolean patch(AAIRequest request, String resourceVersion) throws AAIServiceException {
617 InputStream inputStream = null;
620 AAIDatum instance = request.getRequestObject();
621 if(instance instanceof ResourceVersion) {
622 resourceVersion = ((ResourceVersion)instance).getResourceVersion();
625 URL requestUrl = null;
626 requestUrl = request.getRequestUrl("PATCH", resourceVersion);
627 HttpURLConnection con = getConfiguredConnection(requestUrl, "PATCH");
628 ObjectMapper mapper = AAIService.getObjectMapper();
629 String jsonText = request.toJSONString();
631 LOGwriteDateTrace("data", jsonText);
632 logMetricRequest("PATCH "+requestUrl.getPath(), jsonText, requestUrl.getPath());
634 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
639 int responseCode = con.getResponseCode();
640 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
641 inputStream = con.getInputStream();
643 inputStream = con.getErrorStream();
645 String responseMessage = null;
647 responseMessage = con.getResponseMessage();
648 } catch(Exception exc) {
649 LOG.info("Exception occured", exc.getMessage());
650 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
652 if(responseMessage == null)
653 responseMessage = NOT_PROVIDED;
656 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
657 logMetricResponse(responseCode, responseMessage);
659 // Process the response
660 BufferedReader reader;
662 reader = new BufferedReader( new InputStreamReader( inputStream ) );
663 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
665 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
666 StringBuilder stringBuilder = new StringBuilder();
668 while( ( line = reader.readLine() ) != null ) {
669 stringBuilder.append( line );
671 LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder.length() > 0) ? stringBuilder.toString() : "{no-data}");
674 StringBuilder stringBuilder = new StringBuilder();
676 while( ( line = reader.readLine() ) != null ) {
677 stringBuilder.append("\n").append( line );
679 LOG.info(stringBuilder.toString());
682 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
683 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
685 throw new AAIServiceException(responseCode, errorresponse);
687 } catch(AAIServiceException aaiexc) {
689 } catch (Exception exc) {
690 LOG.warn("AAIRequestExecutor.patch", exc);
691 throw new AAIServiceException(exc);
694 if(inputStream != null)
696 } catch (Exception exc) {
697 LOG.warn("AAIRequestExecutor.patch", exc);
703 * Returns an String that contains JSON data returned from the AAI Server.
705 * This method always returns immediately, whether or not the
708 * @param request an instance of AAIRequiest representing
709 * the request made by DirectedGraph node.
710 * @return the JSON based representation of data instance requested.
714 public String bulkUpdate(BulkUpdateRequest request) throws AAIServiceException {
715 InputStream inputStream = null;
718 URL requestUrl = request.getRequestUrl(HttpMethod.POST, null);
719 HttpURLConnection con = getConfiguredConnection(requestUrl, HttpMethod.POST);
720 String jsonText = request.toJSONString();
721 LOGwriteDateTrace("data", jsonText);
724 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
729 logMetricRequest("POST "+requestUrl.toString(), jsonText, requestUrl.toString());
733 int responseCode = con.getResponseCode();
734 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
735 inputStream = con.getInputStream();
737 inputStream = con.getErrorStream();
739 String responseMessage = null;
741 responseMessage = con.getResponseMessage();
742 } catch(Exception exc) {
743 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
745 if(responseMessage == null)
746 responseMessage = NOT_PROVIDED;
749 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
750 logMetricResponse(responseCode, responseMessage);
752 // Process the response
753 ObjectMapper mapper = AAIService.getObjectMapper();
754 BufferedReader reader;
756 reader = new BufferedReader( new InputStreamReader( inputStream ) );
757 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
759 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
760 StringBuilder stringBuilder = new StringBuilder();
762 while( ( line = reader.readLine() ) != null ) {
763 stringBuilder.append( line );
765 LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder.length() > 0) ? stringBuilder.toString() : "{no-data}");
766 return stringBuilder.toString();
768 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
769 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
771 throw new AAIServiceException(responseCode, errorresponse);
773 } catch(AAIServiceException aaiexc) {
775 } catch (Exception exc) {
776 LOG.warn("AAIRequestExecutor.post", exc);
777 throw new AAIServiceException(exc);
780 if(inputStream != null)
782 } catch (Exception exc) {
783 LOG.warn("AAIRequestExecutor.post", exc);
795 protected HttpURLConnection getConfiguredConnection(URL httpReqUrl, String method) throws Exception {
796 HttpURLConnection con = (HttpURLConnection) httpReqUrl.openConnection();
798 // Set up the connection properties
799 con.setRequestProperty("Connection", "close");
800 con.setDoInput(true);
801 con.setDoOutput(true);
802 con.setUseCaches(false);
803 con.setConnectTimeout(connection_timeout);
804 con.setReadTimeout(read_timeout);
805 con.setRequestMethod(method);
806 con.setRequestProperty("Accept", "application/json");
807 con.setRequestProperty("Transfer-Encoding","chunked");
808 con.setRequestProperty("Content-Type",
809 "PATCH".equalsIgnoreCase(method) ? "application/merge-patch+json" : "application/json");
810 con.setRequestProperty("X-FromAppId", applicationId);
811 con.setRequestProperty("X-TransactionId", TransactionIdTracker.getNextTransactionId());
812 con.setRequestProperty("X-DslApiVersion", "V2");
813 String mlId = ml.getRequestID();
814 if (mlId != null && !mlId.isEmpty()) {
815 LOG.debug(String.format("MetricLogger requestId = %s", mlId));
816 con.setRequestProperty(ONAPLogConstants.MDCs.REQUEST_ID, mlId);
818 LOG.debug("MetricLogger requestId is null");
821 if (userName != null && !userName.isEmpty() && userPassword != null && !userPassword.isEmpty()) {
822 String basicAuth = "Basic " + new String(Base64.encodeBase64((userName + ":" + userPassword).getBytes()));
823 con.setRequestProperty("Authorization", basicAuth);
826 if (con instanceof HttpsURLConnection && CTX != null) {
827 SSLSocketFactory sockFact = CTX.getSocketFactory();
828 HttpsURLConnection.class.cast(con).setSSLSocketFactory(sockFact);
833 private URL appendDepth(URL requestUrl, AAIRequest request) throws MalformedURLException, URISyntaxException {
834 final String NODES_ONLY = "nodes-only";
835 URIBuilder builder = new URIBuilder(requestUrl.toURI());
836 // PROCESS nodes-only option
837 if (request.requestProperties.containsKey(NODES_ONLY)) {
838 if(request.requestProperties.containsKey(NODES_ONLY)) {
839 String nodesOnly = request.requestProperties.getProperty(NODES_ONLY);
840 if(nodesOnly != null && !nodesOnly.isEmpty()) {
841 builder.setParameter(NODES_ONLY, nodesOnly);
844 // do not add depth by default with nodes-only
845 if(!request.requestProperties.containsKey("depth")) {
846 return builder.build().toURL();
850 String depth = request.requestProperties.getProperty("depth", "1");
852 builder.setParameter("depth", depth);
854 return builder.build().toURL();
857 public void logMetricRequest(String targetServiceName, String msg, String path){
858 String svcInstanceId = "";
859 String svcName = null;
860 String partnerName = null;
861 String targetEntity = "A&AI";
862 String targetVirtualEntity = null;
864 ml.logRequest(svcInstanceId, svcName, partnerName, targetEntity, targetServiceName, targetVirtualEntity, msg);
867 public void logMetricResponse(int responseCode, String responseDescription){
868 ml.logResponse(responseCode < 400 ? "COMPLETE" : "ERROR", Integer.toString(responseCode), responseDescription);
871 protected void LOGwriteFirstTrace(String method, String url) {
872 String time = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(System.currentTimeMillis());
873 LOG.info("A&AI transaction :");
874 LOG.info("Request Time : " + time + ", Method : " + method);
875 LOG.info("Request URL : "+ url);
878 protected void LOGwriteDateTrace(String name, String data) {
879 LOG.info("Input - " + name + " : " + data);
882 protected void LOGwriteEndingTrace(int response_code, String comment, String data) {
883 LOG.info("Response code : " + response_code +", " + comment);
884 LOG.info(String.format("Response data : %s", data));