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.InaccessibleObjectException;
35 import java.lang.reflect.InvocationTargetException;
36 import java.lang.reflect.Method;
37 import java.lang.reflect.Modifier;
38 import java.net.HttpURLConnection;
39 import java.net.MalformedURLException;
40 import java.net.URISyntaxException;
42 import java.nio.charset.StandardCharsets;
43 import java.security.KeyManagementException;
44 import java.security.KeyStore;
45 import java.security.NoSuchAlgorithmException;
46 import java.text.SimpleDateFormat;
47 import java.util.Properties;
49 import javax.net.ssl.HttpsURLConnection;
50 import javax.net.ssl.KeyManagerFactory;
51 import javax.net.ssl.SSLContext;
52 import javax.net.ssl.SSLSession;
53 import javax.net.ssl.SSLSocketFactory;
55 import org.apache.commons.codec.binary.Base64;
56 import org.apache.commons.lang3.ObjectUtils;
57 import org.onap.ccsdk.sli.adaptors.aai.AAIService.TransactionIdTracker;
58 import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum;
59 import org.onap.ccsdk.sli.adaptors.aai.data.ErrorResponse;
60 import org.onap.ccsdk.sli.adaptors.aai.data.RequestError;
61 import org.onap.ccsdk.sli.adaptors.aai.data.ResourceVersion;
62 import org.onap.ccsdk.sli.adaptors.aai.data.ServiceException;
63 import org.onap.ccsdk.sli.adaptors.aai.update.BulkUpdateResponseData;
64 import org.onap.ccsdk.sli.core.sli.MetricLogger;
65 import org.onap.logging.ref.slf4j.ONAPLogConstants;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
69 import com.fasterxml.jackson.databind.DeserializationFeature;
70 import com.fasterxml.jackson.databind.ObjectMapper;
72 import org.apache.http.client.utils.URIBuilder;
73 import org.apache.http.impl.EnglishReasonPhraseCatalog;
76 * The AAIClientRESTExecutor class provides CRUD API for AAI Client service.
77 * @author Rich Tabedzki
79 public class AAIClientRESTExecutor implements AAIExecutorInterface {
81 private final String truststorePath;
82 private final String truststorePassword;
83 private final String keystorePath;
84 private final String keystorePassword;
85 private final Boolean ignoreCertificateHostError;
86 // authentication credentials
87 private String userName;
88 private String userPassword;
89 private final String applicationId;
90 private static final String HTTP_URL_CONNECTION_RESULT="HttpURLConnection result: {} : {}";
91 private static final String ENTRY_DOESNT_EXIST="Entry does not exist.";
95 * @param props - properties to initialize an instance.
97 public AAIClientRESTExecutor(Properties props) {
100 userName = props.getProperty(AAIService.CLIENT_NAME);
101 userPassword = props.getProperty(AAIService.CLIENT_PWWD);
103 if(userName == null || userName.isEmpty()){
104 LOG.debug("Basic user name is not set");
106 if(userPassword == null || userPassword.isEmpty()) {
107 LOG.debug("Basic password is not set");
110 truststorePath = props.getProperty(AAIService.TRUSTSTORE_PATH);
111 truststorePassword = props.getProperty(AAIService.TRUSTSTORE_PSSWD);
112 keystorePath = props.getProperty(AAIService.KEYSTORE_PATH);
113 keystorePassword = props.getProperty(AAIService.KEYSTORE_PSSWD);
115 String tmpApplicationId =props.getProperty(AAIService.APPLICATION_ID);
116 if(tmpApplicationId == null || tmpApplicationId.isEmpty()) {
117 tmpApplicationId = "SDNC";
119 applicationId = tmpApplicationId;
121 String iche = props.getProperty(AAIService.CERTIFICATE_HOST_ERROR);
122 boolean host_error = false;
123 if(iche != null && !iche.isEmpty()) {
124 host_error = Boolean.valueOf(iche);
127 ignoreCertificateHostError = host_error;
129 HttpsURLConnection.setDefaultHostnameVerifier( (String string,SSLSession ssls) -> {
130 return ignoreCertificateHostError;
134 if(truststorePath != null && truststorePassword != null && (new File(truststorePath)).exists()) {
135 System.setProperty("javax.net.ssl.trustStore", truststorePath);
136 System.setProperty("javax.net.ssl.trustStorePassword", truststorePassword);
139 if(keystorePath != null && keystorePassword != null && (new File(keystorePath)).exists())
141 //both jersey and HttpURLConnection can use this
142 SSLContext ctx = null;
144 ctx = SSLContext.getInstance("TLS");
146 KeyManagerFactory kmf = null;
147 try (FileInputStream fin = new FileInputStream(keystorePath)){
148 String storeType = "PKCS12";
149 String def = KeyStore.getDefaultType();
150 kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
152 String extension = keystorePath.substring(keystorePath.lastIndexOf(".") + 1);
154 if(extension != null && !extension.isEmpty() && "JKS".equalsIgnoreCase(extension)) {
157 KeyStore ks = KeyStore.getInstance(storeType);
159 char[] pwd = keystorePassword.toCharArray();
162 } catch (Exception ex) {
163 LOG.error("AAIResource", ex);
165 if (ObjectUtils.anyNotNull(kmf)) {
166 ctx.init(kmf.getKeyManagers(), null, null);
170 LOG.debug("SSLContext created");
172 } catch (KeyManagementException | NoSuchAlgorithmException exc) {
173 LOG.error("AAIResource", exc);
177 /** This does not work in Java 17
179 Field methodsField = HttpURLConnection.class.getDeclaredField("methods");
180 methodsField.setAccessible(true);
181 // get the methods field modifiers
182 Field modifiersField = Field.class.getDeclaredField("modifiers");
183 // bypass the "private" modifier
184 modifiersField.setAccessible(true);
186 // remove the "final" modifier
187 modifiersField.setInt(methodsField, methodsField.getModifiers() & ~Modifier.FINAL);
189 // valid HTTP methods
191 "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "PATCH"
193 // set the new methods - including patch
194 methodsField.set(null, methods);
196 } catch (SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchFieldException e) {
197 LOG.warn("Adding PATCH method", e);
200 LOG.info("AAIResource.ctor initialized.");
204 private static final Logger LOG = LoggerFactory.getLogger(AAIService.class);
205 private static final String NOT_PROVIDED = "NOT PROVIDED";
206 private final MetricLogger ml = new MetricLogger();
208 private SSLContext CTX;
211 private int connection_timeout = 300000;
213 private int read_timeout = 300000;
216 * Returns an String that contains JSON data returned from the AAI Server.
218 * This method always returns immediately, whether or not the
221 * @param request an instance of AAIRequiest representing
222 * the request made by DirectedGraph node.
223 * @return the JSON based representation of data instance requested.
227 public String get(AAIRequest request) throws AAIServiceException {
228 String response = null;
229 InputStream inputStream = null;
230 HttpURLConnection con = null;
231 URL requestUrl = null;
233 StringBuilder errorStringBuilder = new StringBuilder();
237 if(request.getRequestObject() != null) {
238 requestUrl = request.getRequestUrl(HttpMethod.POST, null);
239 requestUrl = appendDepth(requestUrl, request);
240 LOG.info(String.format("%s : %s", HttpMethod.GET, requestUrl.toString()));
241 con = getConfiguredConnection(requestUrl, HttpMethod.POST);
242 String json_text = request.toJSONString();
243 LOGwriteDateTrace("data", json_text);
244 logMetricRequest("POST "+requestUrl.toString(), json_text, requestUrl.toString());
245 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
246 osw.write(json_text);
249 requestUrl = request.getRequestUrl(HttpMethod.GET, null);
250 requestUrl = appendDepth(requestUrl, request);
251 LOG.info(String.format("%s : %s", HttpMethod.GET, requestUrl.toString()));
252 con = getConfiguredConnection(requestUrl, HttpMethod.GET);
253 logMetricRequest("GET "+requestUrl.toString(), "", requestUrl.toString());
257 int responseCode = con.getResponseCode();
258 if (responseCode == HttpURLConnection.HTTP_OK) {
259 inputStream = con.getInputStream();
261 inputStream = con.getErrorStream();
263 String responseMessage = null;
265 responseMessage = con.getResponseMessage();
266 } catch(Exception exc) {
267 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
269 if(responseMessage == null)
270 responseMessage = NOT_PROVIDED;
273 // Process the response
274 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
275 logMetricResponse(responseCode, responseMessage);
277 if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8));
278 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
280 ObjectMapper mapper = AAIService.getObjectMapper();
282 if (responseCode == HttpURLConnection.HTTP_OK) {
283 StringBuilder stringBuilder = new StringBuilder();
285 while( ( line = reader.readLine() ) != null ) {
286 stringBuilder.append( line );
288 response = stringBuilder.toString();
290 Object object = mapper.readValue(response, Object.class);
291 LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, responseMessage, mapper.writeValueAsString(object));
292 } catch(Exception exc) {
293 LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, responseMessage, mapper.writeValueAsString(response));
295 } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
296 LOGwriteEndingTrace(responseCode, responseMessage, ENTRY_DOESNT_EXIST);
297 ErrorResponse errorresponse = null;
299 errorresponse = mapper.readValue(reader, ErrorResponse.class);
300 } catch(Exception exc) {
301 errorresponse = new ErrorResponse();
302 RequestError requestError = new RequestError();
303 ServiceException serviceException = new ServiceException();
304 serviceException.setText(ENTRY_DOESNT_EXIST);
305 requestError.setServiceException(serviceException);
306 errorresponse.setRequestError(requestError );
308 throw new AAIServiceException(responseCode, errorresponse);
309 } else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
310 StringBuilder stringBuilder = new StringBuilder();
312 while( ( line = reader.readLine() ) != null ) {
313 stringBuilder.append( line );
315 LOGwriteEndingTrace(responseCode, responseMessage, stringBuilder.toString());
316 ServiceException serviceException = new ServiceException();
317 serviceException.setMessageId("HTTP_UNAUTHORIZED");
318 serviceException.setText(stringBuilder.toString());
319 RequestError requestError = new RequestError();
320 requestError.setServiceException(serviceException);
321 ErrorResponse errorresponse = new ErrorResponse();
322 errorresponse.setRequestError(requestError);
323 throw new AAIServiceException(responseCode, errorresponse);
326 while( ( line = reader.readLine() ) != null ) {
327 errorStringBuilder.append("\n").append( line );
330 ErrorResponse errorresponse = mapper.readValue(errorStringBuilder.toString(), ErrorResponse.class);
331 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
332 throw new AAIServiceException(responseCode, errorresponse);
335 } catch(AAIServiceException aaiexc) {
337 } catch (Exception exc) {
338 LOG.warn(errorStringBuilder.toString(), exc);
339 throw new AAIServiceException(exc);
341 if(inputStream != null){
344 } catch(Exception exc) {
353 * Returns an String that contains JSON data returned from the AAI Server.
355 * This method always returns immediately, whether or not the
358 * @param request an instance of AAIRequiest representing
359 * the request made by DirectedGraph node.
360 * @return the JSON based representation of data instance requested.
364 public String post(AAIRequest request) throws AAIServiceException {
365 InputStream inputStream = null;
368 String resourceVersion = null;
369 AAIDatum instance = request.getRequestObject();
372 Method getResourceVersionMethod = instance.getClass().getMethod("getResourceVersion");
373 if(getResourceVersionMethod != null){
375 Object object = getResourceVersionMethod.invoke(instance);
377 resourceVersion = object.toString();
378 } catch (InvocationTargetException exc) {
382 } catch(Exception exc) {
386 URL requestUrl = request.getRequestUrl(HttpMethod.PUT, resourceVersion);
387 HttpURLConnection con = getConfiguredConnection(requestUrl, HttpMethod.PUT);
388 String jsonText = request.toJSONString();
389 LOGwriteDateTrace("data", jsonText);
392 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
397 logMetricRequest("PUT "+requestUrl.toString(), jsonText, requestUrl.toString());
401 int responseCode = con.getResponseCode();
402 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
403 inputStream = con.getInputStream();
405 inputStream = con.getErrorStream();
407 String responseMessage = null;
409 responseMessage = con.getResponseMessage();
410 } catch(Exception exc) {
411 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
413 if(responseMessage == null)
414 responseMessage = NOT_PROVIDED;
417 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
418 logMetricResponse(responseCode, responseMessage);
420 // Process the response
421 ObjectMapper mapper = AAIService.getObjectMapper();
422 BufferedReader reader;
424 reader = new BufferedReader( new InputStreamReader( inputStream ) );
425 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
427 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
428 StringBuilder stringBuilder = new StringBuilder();
430 while( ( line = reader.readLine() ) != null ) {
431 stringBuilder.append( line );
433 LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder.length() > 0) ? stringBuilder.toString() : "{no-data}");
434 return stringBuilder.toString();
436 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
437 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
439 throw new AAIServiceException(responseCode, errorresponse);
441 } catch(AAIServiceException aaiexc) {
443 } catch (Exception exc) {
444 LOG.warn("AAIRequestExecutor.post", exc);
445 throw new AAIServiceException(exc);
448 if(inputStream != null)
450 } catch (Exception exc) {
451 LOG.warn("AAIRequestExecutor.post", exc);
457 * Returns Boolean that contains completion state of the command executed.
459 * This method always returns immediately, whether or not the
462 * @param request an instance of AAIRequiest representing
463 * @param resourceVersion a resource version of the data instacne to be deleted.
464 * the request made by DirectedGraph node.
465 * @return completion state of the command.
469 public Boolean delete(AAIRequest request, String resourceVersion) throws AAIServiceException {
470 Boolean response = null;
471 InputStream inputStream = null;
473 if(resourceVersion == null) {
474 throw new AAIServiceException("resource-version is required for DELETE request");
478 URL requestUrl = request.getRequestUrl(HttpMethod.DELETE, resourceVersion);
479 HttpURLConnection conn = getConfiguredConnection(requestUrl, HttpMethod.DELETE);
480 logMetricRequest("DELETE "+requestUrl.getPath(), "", requestUrl.getPath());
481 conn.setDoOutput(true);
484 int responseCode = conn.getResponseCode();
485 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
486 inputStream = conn.getInputStream();
488 inputStream = conn.getErrorStream();
490 String responseMessage = null;
492 responseMessage = conn.getResponseMessage();
493 } catch(Exception exc) {
494 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
496 if(responseMessage == null)
497 responseMessage = NOT_PROVIDED;
500 // Process the response
501 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
502 logMetricResponse(responseCode, responseMessage);
504 if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8));
505 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
508 ObjectMapper mapper = AAIService.getObjectMapper();
510 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
511 StringBuilder stringBuilder = new StringBuilder();
513 while( ( line = reader.readLine() ) != null ) {
514 stringBuilder.append( line );
516 LOGwriteEndingTrace(responseCode, responseMessage, stringBuilder.toString());
518 } else if(responseCode == HttpURLConnection.HTTP_NOT_FOUND ) {
519 LOGwriteEndingTrace(responseCode, responseMessage, ENTRY_DOESNT_EXIST);
522 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
523 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
524 throw new AAIServiceException(responseCode, errorresponse);
526 } catch(AAIServiceException aaiexc) {
528 } catch (Exception exc) {
529 LOG.warn("delete", exc);
530 throw new AAIServiceException(exc);
532 if(inputStream != null){
535 } catch(Exception exc) {
536 LOG.warn("delete", exc);
544 * Returns an String that contains JSON data returned from the AAI Server.
546 * This method always returns immediately, whether or not the
549 * @param request an instance of AAIRequiest representing
550 * the request made by DirectedGraph node.
551 * @param clas an definition of the class for which data will be returned
552 * @return the instance of the class with data.
556 public Object query(AAIRequest request, Class clas) throws AAIServiceException {
557 Object response = null;
558 InputStream inputStream = null;
561 URL requestUrl = request.getRequestQueryUrl(HttpMethod.GET);
562 HttpURLConnection con = getConfiguredConnection(requestUrl, HttpMethod.GET);
563 logMetricRequest("GET "+requestUrl.getPath(), "", requestUrl.getPath());
566 int responseCode = con.getResponseCode();
567 if (responseCode == HttpURLConnection.HTTP_OK) {
568 inputStream = con.getInputStream();
570 inputStream = con.getErrorStream();
572 String responseMessage = null;
574 responseMessage = con.getResponseMessage();
575 } catch(Exception exc) {
576 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
578 if(responseMessage == null)
579 responseMessage = NOT_PROVIDED;
582 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
583 logMetricResponse(responseCode, responseMessage);
584 ObjectMapper mapper = AAIService.getObjectMapper();
586 if (responseCode == HttpURLConnection.HTTP_OK) {
587 // Process the response
588 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
589 response = mapper.readValue(reader, clas);
590 LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, "SUCCESS", mapper.writeValueAsString(response));
591 } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
592 LOGwriteEndingTrace(responseCode, "HTTP_NOT_FOUND", ENTRY_DOESNT_EXIST);
595 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
596 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
597 LOGwriteEndingTrace(responseCode, "FAILURE", mapper.writeValueAsString(errorresponse));
598 throw new AAIServiceException(responseCode, errorresponse);
601 } catch(AAIServiceException aaiexc) {
603 } catch (Exception exc) {
604 LOG.warn("GET", exc);
605 throw new AAIServiceException(exc);
607 if(inputStream != null){
610 } catch(Exception exc) {
611 LOG.warn("GET", exc);
619 public Boolean patch(AAIRequest request, String resourceVersion) throws AAIServiceException {
620 InputStream inputStream = null;
623 AAIDatum instance = request.getRequestObject();
624 if(instance instanceof ResourceVersion) {
625 resourceVersion = ((ResourceVersion)instance).getResourceVersion();
628 URL requestUrl = null;
629 requestUrl = request.getRequestUrl("PATCH", resourceVersion);
630 HttpURLConnection con = getConfiguredConnection(requestUrl, "PATCH");
631 ObjectMapper mapper = AAIService.getObjectMapper();
632 String jsonText = request.toJSONString();
634 LOGwriteDateTrace("data", jsonText);
635 logMetricRequest("PATCH "+requestUrl.getPath(), jsonText, requestUrl.getPath());
637 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
642 int responseCode = con.getResponseCode();
643 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
644 inputStream = con.getInputStream();
646 inputStream = con.getErrorStream();
648 String responseMessage = null;
650 responseMessage = con.getResponseMessage();
651 } catch(Exception exc) {
652 LOG.info("Exception occured", exc.getMessage());
653 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
655 if(responseMessage == null)
656 responseMessage = NOT_PROVIDED;
659 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
660 logMetricResponse(responseCode, responseMessage);
662 // Process the response
663 BufferedReader reader;
665 reader = new BufferedReader( new InputStreamReader( inputStream ) );
666 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
668 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
669 StringBuilder stringBuilder = new StringBuilder();
671 while( ( line = reader.readLine() ) != null ) {
672 stringBuilder.append( line );
674 LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder.length() > 0) ? stringBuilder.toString() : "{no-data}");
677 StringBuilder stringBuilder = new StringBuilder();
679 while( ( line = reader.readLine() ) != null ) {
680 stringBuilder.append("\n").append( line );
682 LOG.info(stringBuilder.toString());
685 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
686 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
688 throw new AAIServiceException(responseCode, errorresponse);
690 } catch(AAIServiceException aaiexc) {
692 } catch (Exception exc) {
693 LOG.warn("AAIRequestExecutor.patch", exc);
694 throw new AAIServiceException(exc);
697 if(inputStream != null)
699 } catch (Exception exc) {
700 LOG.warn("AAIRequestExecutor.patch", exc);
706 * Returns an String that contains JSON data returned from the AAI Server.
708 * This method always returns immediately, whether or not the
711 * @param request an instance of AAIRequiest representing
712 * the request made by DirectedGraph node.
713 * @return the JSON based representation of data instance requested.
717 public String bulkUpdate(BulkUpdateRequest request) throws AAIServiceException {
718 InputStream inputStream = null;
721 URL requestUrl = request.getRequestUrl(HttpMethod.POST, null);
722 HttpURLConnection con = getConfiguredConnection(requestUrl, HttpMethod.POST);
723 String jsonText = request.toJSONString();
724 LOGwriteDateTrace("data", jsonText);
727 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
732 logMetricRequest("POST "+requestUrl.toString(), jsonText, requestUrl.toString());
736 int responseCode = con.getResponseCode();
737 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
738 inputStream = con.getInputStream();
740 inputStream = con.getErrorStream();
742 String responseMessage = null;
744 responseMessage = con.getResponseMessage();
745 } catch(Exception exc) {
746 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
748 if(responseMessage == null)
749 responseMessage = NOT_PROVIDED;
752 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
753 logMetricResponse(responseCode, responseMessage);
755 // Process the response
756 ObjectMapper mapper = AAIService.getObjectMapper();
757 BufferedReader reader;
759 reader = new BufferedReader( new InputStreamReader( inputStream ) );
760 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
762 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
763 StringBuilder stringBuilder = new StringBuilder();
765 while( ( line = reader.readLine() ) != null ) {
766 stringBuilder.append( line );
768 LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder.length() > 0) ? stringBuilder.toString() : "{no-data}");
769 return stringBuilder.toString();
771 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
772 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
774 throw new AAIServiceException(responseCode, errorresponse);
776 } catch(AAIServiceException aaiexc) {
778 } catch (Exception exc) {
779 LOG.warn("AAIRequestExecutor.post", exc);
780 throw new AAIServiceException(exc);
783 if(inputStream != null)
785 } catch (Exception exc) {
786 LOG.warn("AAIRequestExecutor.post", exc);
798 protected HttpURLConnection getConfiguredConnection(URL httpReqUrl, String method) throws Exception {
799 HttpURLConnection con = (HttpURLConnection) httpReqUrl.openConnection();
801 // Set up the connection properties
802 con.setRequestProperty("Connection", "close");
803 con.setDoInput(true);
804 con.setDoOutput(true);
805 con.setUseCaches(false);
806 con.setConnectTimeout(connection_timeout);
807 con.setReadTimeout(read_timeout);
808 con.setRequestMethod(method);
809 con.setRequestProperty("Accept", "application/json");
810 con.setRequestProperty("Transfer-Encoding","chunked");
811 con.setRequestProperty("Content-Type",
812 "PATCH".equalsIgnoreCase(method) ? "application/merge-patch+json" : "application/json");
813 con.setRequestProperty("X-FromAppId", applicationId);
814 con.setRequestProperty("X-TransactionId", TransactionIdTracker.getNextTransactionId());
815 con.setRequestProperty("X-DslApiVersion", "V2");
816 String mlId = ml.getRequestID();
817 if (mlId != null && !mlId.isEmpty()) {
818 LOG.debug(String.format("MetricLogger requestId = %s", mlId));
819 con.setRequestProperty(ONAPLogConstants.MDCs.REQUEST_ID, mlId);
821 LOG.debug("MetricLogger requestId is null");
824 if (userName != null && !userName.isEmpty() && userPassword != null && !userPassword.isEmpty()) {
825 String basicAuth = "Basic " + new String(Base64.encodeBase64((userName + ":" + userPassword).getBytes()));
826 con.setRequestProperty("Authorization", basicAuth);
829 if (con instanceof HttpsURLConnection && CTX != null) {
830 SSLSocketFactory sockFact = CTX.getSocketFactory();
831 HttpsURLConnection.class.cast(con).setSSLSocketFactory(sockFact);
836 private URL appendDepth(URL requestUrl, AAIRequest request) throws MalformedURLException, URISyntaxException {
837 final String NODES_ONLY = "nodes-only";
838 URIBuilder builder = new URIBuilder(requestUrl.toURI());
839 // PROCESS nodes-only option
840 if (request.requestProperties.containsKey(NODES_ONLY)) {
841 if(request.requestProperties.containsKey(NODES_ONLY)) {
842 String nodesOnly = request.requestProperties.getProperty(NODES_ONLY);
843 if(nodesOnly != null && !nodesOnly.isEmpty()) {
844 builder.setParameter(NODES_ONLY, nodesOnly);
847 // do not add depth by default with nodes-only
848 if(!request.requestProperties.containsKey("depth")) {
849 return builder.build().toURL();
853 String depth = request.requestProperties.getProperty("depth", "1");
855 builder.setParameter("depth", depth);
857 return builder.build().toURL();
860 public void logMetricRequest(String targetServiceName, String msg, String path){
861 String svcInstanceId = "";
862 String svcName = null;
863 String partnerName = null;
864 String targetEntity = "A&AI";
865 String targetVirtualEntity = null;
867 ml.logRequest(svcInstanceId, svcName, partnerName, targetEntity, targetServiceName, targetVirtualEntity, msg);
870 public void logMetricResponse(int responseCode, String responseDescription){
871 ml.logResponse(responseCode < 400 ? "COMPLETE" : "ERROR", Integer.toString(responseCode), responseDescription);
874 protected void LOGwriteFirstTrace(String method, String url) {
875 String time = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(System.currentTimeMillis());
876 LOG.info("A&AI transaction :");
877 LOG.info("Request Time : " + time + ", Method : " + method);
878 LOG.info("Request URL : "+ url);
881 protected void LOGwriteDateTrace(String name, String data) {
882 LOG.info("Input - " + name + " : " + data);
885 protected void LOGwriteEndingTrace(int response_code, String comment, String data) {
886 LOG.info("Response code : " + response_code +", " + comment);
887 LOG.info(String.format("Response data : %s", data));