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.onap.ccsdk.sli.adaptors.aai.AAIService.TransactionIdTracker;
56 import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum;
57 import org.onap.ccsdk.sli.adaptors.aai.data.ErrorResponse;
58 import org.onap.ccsdk.sli.adaptors.aai.data.RequestError;
59 import org.onap.ccsdk.sli.adaptors.aai.data.ResourceVersion;
60 import org.onap.ccsdk.sli.adaptors.aai.data.ServiceException;
61 import org.onap.ccsdk.sli.adaptors.aai.update.BulkUpdateResponseData;
62 import org.onap.ccsdk.sli.core.sli.MetricLogger;
63 import org.onap.logging.ref.slf4j.ONAPLogConstants;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
67 import com.fasterxml.jackson.databind.DeserializationFeature;
68 import com.fasterxml.jackson.databind.ObjectMapper;
70 import org.apache.http.client.utils.URIBuilder;
71 import org.apache.http.impl.EnglishReasonPhraseCatalog;
74 * The AAIClientRESTExecutor class provides CRUD API for AAI Client service.
75 * @author Rich Tabedzki
77 public class AAIClientRESTExecutor implements AAIExecutorInterface {
79 private final String truststorePath;
80 private final String truststorePassword;
81 private final String keystorePath;
82 private final String keystorePassword;
83 private final Boolean ignoreCertificateHostError;
84 // authentication credentials
85 private String userName;
86 private String userPassword;
87 private final String applicationId;
88 private static final String HTTP_URL_CONNECTION_RESULT="HttpURLConnection result: {} : {}";
89 private static final String ENTRY_DOESNT_EXIST="Entry does not exist.";
93 * @param props - properties to initialize an instance.
95 public AAIClientRESTExecutor(Properties props) {
98 userName = props.getProperty(AAIService.CLIENT_NAME);
99 userPassword = props.getProperty(AAIService.CLIENT_PWWD);
101 if(userName == null || userName.isEmpty()){
102 LOG.debug("Basic user name is not set");
104 if(userPassword == null || userPassword.isEmpty()) {
105 LOG.debug("Basic password is not set");
108 truststorePath = props.getProperty(AAIService.TRUSTSTORE_PATH);
109 truststorePassword = props.getProperty(AAIService.TRUSTSTORE_PSSWD);
110 keystorePath = props.getProperty(AAIService.KEYSTORE_PATH);
111 keystorePassword = props.getProperty(AAIService.KEYSTORE_PSSWD);
113 String tmpApplicationId =props.getProperty(AAIService.APPLICATION_ID);
114 if(tmpApplicationId == null || tmpApplicationId.isEmpty()) {
115 tmpApplicationId = "SDNC";
117 applicationId = tmpApplicationId;
119 String iche = props.getProperty(AAIService.CERTIFICATE_HOST_ERROR);
120 boolean host_error = false;
121 if(iche != null && !iche.isEmpty()) {
122 host_error = Boolean.valueOf(iche);
125 ignoreCertificateHostError = host_error;
127 HttpsURLConnection.setDefaultHostnameVerifier( (String string,SSLSession ssls) -> {
128 return ignoreCertificateHostError;
132 if(truststorePath != null && truststorePassword != null && (new File(truststorePath)).exists()) {
133 System.setProperty("javax.net.ssl.trustStore", truststorePath);
134 System.setProperty("javax.net.ssl.trustStorePassword", truststorePassword);
137 if(keystorePath != null && keystorePassword != null && (new File(keystorePath)).exists())
139 //both jersey and HttpURLConnection can use this
140 SSLContext ctx = null;
142 ctx = SSLContext.getInstance("TLS");
144 KeyManagerFactory kmf = null;
145 try (FileInputStream fin = new FileInputStream(keystorePath)){
146 String storeType = "PKCS12";
147 String def = KeyStore.getDefaultType();
148 kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
150 String extension = keystorePath.substring(keystorePath.lastIndexOf(".") + 1);
152 if(extension != null && !extension.isEmpty() && "JKS".equalsIgnoreCase(extension)) {
155 KeyStore ks = KeyStore.getInstance(storeType);
157 char[] pwd = keystorePassword.toCharArray();
160 } catch (Exception ex) {
161 LOG.error("AAIResource", ex);
164 ctx.init(kmf.getKeyManagers(), null, null);
167 LOG.debug("SSLContext created");
169 } catch (KeyManagementException | NoSuchAlgorithmException exc) {
170 LOG.error("AAIResource", exc);
175 Field methodsField = HttpURLConnection.class.getDeclaredField("methods");
176 methodsField.setAccessible(true);
177 // get the methods field modifiers
178 Field modifiersField = Field.class.getDeclaredField("modifiers");
179 // bypass the "private" modifier
180 modifiersField.setAccessible(true);
182 // remove the "final" modifier
183 modifiersField.setInt(methodsField, methodsField.getModifiers() & ~Modifier.FINAL);
185 /* valid HTTP methods */
187 "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "PATCH"
189 // set the new methods - including patch
190 methodsField.set(null, methods);
192 } catch (SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchFieldException e) {
193 LOG.warn("Adding PATCH method", e);
195 LOG.info("AAIResource.ctor initialized.");
199 private static final Logger LOG = LoggerFactory.getLogger(AAIService.class);
200 private static final String NOT_PROVIDED = "NOT PROVIDED";
201 private final MetricLogger ml = new MetricLogger();
203 private SSLContext CTX;
206 private int connection_timeout = 300000;
208 private int read_timeout = 300000;
211 * Returns an String that contains JSON data returned from the AAI Server.
213 * This method always returns immediately, whether or not the
216 * @param request an instance of AAIRequiest representing
217 * the request made by DirectedGraph node.
218 * @return the JSON based representation of data instance requested.
222 public String get(AAIRequest request) throws AAIServiceException {
223 String response = null;
224 InputStream inputStream = null;
225 HttpURLConnection con = null;
226 URL requestUrl = null;
228 StringBuilder errorStringBuilder = new StringBuilder();
232 if(request.getRequestObject() != null) {
233 requestUrl = request.getRequestUrl(HttpMethod.POST, null);
234 requestUrl = appendDepth(requestUrl, request);
235 LOG.info(String.format("%s : %s", HttpMethod.GET, requestUrl.toString()));
236 con = getConfiguredConnection(requestUrl, HttpMethod.POST);
237 String json_text = request.toJSONString();
238 LOGwriteDateTrace("data", json_text);
239 logMetricRequest("POST "+requestUrl.toString(), json_text, requestUrl.toString());
240 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
241 osw.write(json_text);
244 requestUrl = request.getRequestUrl(HttpMethod.GET, null);
245 requestUrl = appendDepth(requestUrl, request);
246 LOG.info(String.format("%s : %s", HttpMethod.GET, requestUrl.toString()));
247 con = getConfiguredConnection(requestUrl, HttpMethod.GET);
248 logMetricRequest("GET "+requestUrl.toString(), "", requestUrl.toString());
252 int responseCode = con.getResponseCode();
253 if (responseCode == HttpURLConnection.HTTP_OK) {
254 inputStream = con.getInputStream();
256 inputStream = con.getErrorStream();
258 String responseMessage = null;
260 responseMessage = con.getResponseMessage();
261 } catch(Exception exc) {
262 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
264 if(responseMessage == null)
265 responseMessage = NOT_PROVIDED;
268 // Process the response
269 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
270 logMetricResponse(responseCode, responseMessage);
272 if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8));
273 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
275 ObjectMapper mapper = AAIService.getObjectMapper();
277 if (responseCode == HttpURLConnection.HTTP_OK) {
278 StringBuilder stringBuilder = new StringBuilder();
280 while( ( line = reader.readLine() ) != null ) {
281 stringBuilder.append( line );
283 response = stringBuilder.toString();
285 Object object = mapper.readValue(response, Object.class);
286 LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, responseMessage, mapper.writeValueAsString(object));
287 } catch(Exception exc) {
288 LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, responseMessage, mapper.writeValueAsString(response));
290 } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
291 LOGwriteEndingTrace(responseCode, responseMessage, ENTRY_DOESNT_EXIST);
292 ErrorResponse errorresponse = null;
294 errorresponse = mapper.readValue(reader, ErrorResponse.class);
295 } catch(Exception exc) {
296 errorresponse = new ErrorResponse();
297 RequestError requestError = new RequestError();
298 ServiceException serviceException = new ServiceException();
299 serviceException.setText(ENTRY_DOESNT_EXIST);
300 requestError.setServiceException(serviceException);
301 errorresponse.setRequestError(requestError );
303 throw new AAIServiceException(responseCode, errorresponse);
304 } else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
305 StringBuilder stringBuilder = new StringBuilder();
307 while( ( line = reader.readLine() ) != null ) {
308 stringBuilder.append( line );
310 LOGwriteEndingTrace(responseCode, responseMessage, stringBuilder.toString());
311 ServiceException serviceException = new ServiceException();
312 serviceException.setMessageId("HTTP_UNAUTHORIZED");
313 serviceException.setText(stringBuilder.toString());
314 RequestError requestError = new RequestError();
315 requestError.setServiceException(serviceException);
316 ErrorResponse errorresponse = new ErrorResponse();
317 errorresponse.setRequestError(requestError);
318 throw new AAIServiceException(responseCode, errorresponse);
321 while( ( line = reader.readLine() ) != null ) {
322 errorStringBuilder.append("\n").append( line );
325 ErrorResponse errorresponse = mapper.readValue(errorStringBuilder.toString(), ErrorResponse.class);
326 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
327 throw new AAIServiceException(responseCode, errorresponse);
330 } catch(AAIServiceException aaiexc) {
332 } catch (Exception exc) {
333 LOG.warn(errorStringBuilder.toString(), exc);
334 throw new AAIServiceException(exc);
336 if(inputStream != null){
339 } catch(Exception exc) {
348 * Returns an String that contains JSON data returned from the AAI Server.
350 * This method always returns immediately, whether or not the
353 * @param request an instance of AAIRequiest representing
354 * the request made by DirectedGraph node.
355 * @return the JSON based representation of data instance requested.
359 public String post(AAIRequest request) throws AAIServiceException {
360 InputStream inputStream = null;
363 String resourceVersion = null;
364 AAIDatum instance = request.getRequestObject();
367 Method getResourceVersionMethod = instance.getClass().getMethod("getResourceVersion");
368 if(getResourceVersionMethod != null){
370 Object object = getResourceVersionMethod.invoke(instance);
372 resourceVersion = object.toString();
373 } catch (InvocationTargetException exc) {
377 } catch(Exception exc) {
381 URL requestUrl = request.getRequestUrl(HttpMethod.PUT, resourceVersion);
382 HttpURLConnection con = getConfiguredConnection(requestUrl, HttpMethod.PUT);
383 String jsonText = request.toJSONString();
384 LOGwriteDateTrace("data", jsonText);
387 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
392 logMetricRequest("PUT "+requestUrl.toString(), jsonText, requestUrl.toString());
396 int responseCode = con.getResponseCode();
397 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
398 inputStream = con.getInputStream();
400 inputStream = con.getErrorStream();
402 String responseMessage = null;
404 responseMessage = con.getResponseMessage();
405 } catch(Exception exc) {
406 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
408 if(responseMessage == null)
409 responseMessage = NOT_PROVIDED;
412 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
413 logMetricResponse(responseCode, responseMessage);
415 // Process the response
416 ObjectMapper mapper = AAIService.getObjectMapper();
417 BufferedReader reader;
419 reader = new BufferedReader( new InputStreamReader( inputStream ) );
420 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
422 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
423 StringBuilder stringBuilder = new StringBuilder();
425 while( ( line = reader.readLine() ) != null ) {
426 stringBuilder.append( line );
428 LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder.length() > 0) ? stringBuilder.toString() : "{no-data}");
429 return stringBuilder.toString();
431 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
432 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
434 throw new AAIServiceException(responseCode, errorresponse);
436 } catch(AAIServiceException aaiexc) {
438 } catch (Exception exc) {
439 LOG.warn("AAIRequestExecutor.post", exc);
440 throw new AAIServiceException(exc);
443 if(inputStream != null)
445 } catch (Exception exc) {
446 LOG.warn("AAIRequestExecutor.post", exc);
452 * Returns Boolean that contains completion state of the command executed.
454 * This method always returns immediately, whether or not the
457 * @param request an instance of AAIRequiest representing
458 * @param resourceVersion a resource version of the data instacne to be deleted.
459 * the request made by DirectedGraph node.
460 * @return completion state of the command.
464 public Boolean delete(AAIRequest request, String resourceVersion) throws AAIServiceException {
465 Boolean response = null;
466 InputStream inputStream = null;
468 if(resourceVersion == null) {
469 throw new AAIServiceException("resource-version is required for DELETE request");
473 URL requestUrl = request.getRequestUrl(HttpMethod.DELETE, resourceVersion);
474 HttpURLConnection conn = getConfiguredConnection(requestUrl, HttpMethod.DELETE);
475 logMetricRequest("DELETE "+requestUrl.getPath(), "", requestUrl.getPath());
476 conn.setDoOutput(true);
479 int responseCode = conn.getResponseCode();
480 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
481 inputStream = conn.getInputStream();
483 inputStream = conn.getErrorStream();
485 String responseMessage = null;
487 responseMessage = conn.getResponseMessage();
488 } catch(Exception exc) {
489 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
491 if(responseMessage == null)
492 responseMessage = NOT_PROVIDED;
495 // Process the response
496 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
497 logMetricResponse(responseCode, responseMessage);
499 if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8));
500 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
503 ObjectMapper mapper = AAIService.getObjectMapper();
505 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
506 StringBuilder stringBuilder = new StringBuilder();
508 while( ( line = reader.readLine() ) != null ) {
509 stringBuilder.append( line );
511 LOGwriteEndingTrace(responseCode, responseMessage, stringBuilder.toString());
513 } else if(responseCode == HttpURLConnection.HTTP_NOT_FOUND ) {
514 LOGwriteEndingTrace(responseCode, responseMessage, ENTRY_DOESNT_EXIST);
517 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
518 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
519 throw new AAIServiceException(responseCode, errorresponse);
521 } catch(AAIServiceException aaiexc) {
523 } catch (Exception exc) {
524 LOG.warn("delete", exc);
525 throw new AAIServiceException(exc);
527 if(inputStream != null){
530 } catch(Exception exc) {
531 LOG.warn("delete", exc);
539 * Returns an String that contains JSON data returned from the AAI Server.
541 * This method always returns immediately, whether or not the
544 * @param request an instance of AAIRequiest representing
545 * the request made by DirectedGraph node.
546 * @param clas an definition of the class for which data will be returned
547 * @return the instance of the class with data.
551 public Object query(AAIRequest request, Class clas) throws AAIServiceException {
552 Object response = null;
553 InputStream inputStream = null;
556 URL requestUrl = request.getRequestQueryUrl(HttpMethod.GET);
557 HttpURLConnection con = getConfiguredConnection(requestUrl, HttpMethod.GET);
558 logMetricRequest("GET "+requestUrl.getPath(), "", requestUrl.getPath());
561 int responseCode = con.getResponseCode();
562 if (responseCode == HttpURLConnection.HTTP_OK) {
563 inputStream = con.getInputStream();
565 inputStream = con.getErrorStream();
567 String responseMessage = null;
569 responseMessage = con.getResponseMessage();
570 } catch(Exception exc) {
571 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
573 if(responseMessage == null)
574 responseMessage = NOT_PROVIDED;
577 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
578 logMetricResponse(responseCode, responseMessage);
579 ObjectMapper mapper = AAIService.getObjectMapper();
581 if (responseCode == HttpURLConnection.HTTP_OK) {
582 // Process the response
583 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
584 response = mapper.readValue(reader, clas);
585 LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, "SUCCESS", mapper.writeValueAsString(response));
586 } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
587 LOGwriteEndingTrace(responseCode, "HTTP_NOT_FOUND", ENTRY_DOESNT_EXIST);
590 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
591 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
592 LOGwriteEndingTrace(responseCode, "FAILURE", mapper.writeValueAsString(errorresponse));
593 throw new AAIServiceException(responseCode, errorresponse);
596 } catch(AAIServiceException aaiexc) {
598 } catch (Exception exc) {
599 LOG.warn("GET", exc);
600 throw new AAIServiceException(exc);
602 if(inputStream != null){
605 } catch(Exception exc) {
606 LOG.warn("GET", exc);
614 public Boolean patch(AAIRequest request, String resourceVersion) throws AAIServiceException {
615 InputStream inputStream = null;
618 AAIDatum instance = request.getRequestObject();
619 if(instance instanceof ResourceVersion) {
620 resourceVersion = ((ResourceVersion)instance).getResourceVersion();
623 URL requestUrl = null;
624 requestUrl = request.getRequestUrl("PATCH", resourceVersion);
625 HttpURLConnection con = getConfiguredConnection(requestUrl, "PATCH");
626 ObjectMapper mapper = AAIService.getObjectMapper();
627 String jsonText = request.toJSONString();
629 LOGwriteDateTrace("data", jsonText);
630 logMetricRequest("PATCH "+requestUrl.getPath(), jsonText, requestUrl.getPath());
632 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
637 int responseCode = con.getResponseCode();
638 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
639 inputStream = con.getInputStream();
641 inputStream = con.getErrorStream();
643 String responseMessage = null;
645 responseMessage = con.getResponseMessage();
646 } catch(Exception exc) {
647 LOG.info("Exception occured", exc.getMessage());
648 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
650 if(responseMessage == null)
651 responseMessage = NOT_PROVIDED;
654 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
655 logMetricResponse(responseCode, responseMessage);
657 // Process the response
658 BufferedReader reader;
660 reader = new BufferedReader( new InputStreamReader( inputStream ) );
661 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
663 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
664 StringBuilder stringBuilder = new StringBuilder();
666 while( ( line = reader.readLine() ) != null ) {
667 stringBuilder.append( line );
669 LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder.length() > 0) ? stringBuilder.toString() : "{no-data}");
672 StringBuilder stringBuilder = new StringBuilder();
674 while( ( line = reader.readLine() ) != null ) {
675 stringBuilder.append("\n").append( line );
677 LOG.info(stringBuilder.toString());
680 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
681 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
683 throw new AAIServiceException(responseCode, errorresponse);
685 } catch(AAIServiceException aaiexc) {
687 } catch (Exception exc) {
688 LOG.warn("AAIRequestExecutor.patch", exc);
689 throw new AAIServiceException(exc);
692 if(inputStream != null)
694 } catch (Exception exc) {
695 LOG.warn("AAIRequestExecutor.patch", exc);
701 * Returns an String that contains JSON data returned from the AAI Server.
703 * This method always returns immediately, whether or not the
706 * @param request an instance of AAIRequiest representing
707 * the request made by DirectedGraph node.
708 * @return the JSON based representation of data instance requested.
712 public String bulkUpdate(BulkUpdateRequest request) throws AAIServiceException {
713 InputStream inputStream = null;
716 URL requestUrl = request.getRequestUrl(HttpMethod.POST, null);
717 HttpURLConnection con = getConfiguredConnection(requestUrl, HttpMethod.POST);
718 String jsonText = request.toJSONString();
719 LOGwriteDateTrace("data", jsonText);
722 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
727 logMetricRequest("POST "+requestUrl.toString(), jsonText, requestUrl.toString());
731 int responseCode = con.getResponseCode();
732 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
733 inputStream = con.getInputStream();
735 inputStream = con.getErrorStream();
737 String responseMessage = null;
739 responseMessage = con.getResponseMessage();
740 } catch(Exception exc) {
741 responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null);
743 if(responseMessage == null)
744 responseMessage = NOT_PROVIDED;
747 LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage);
748 logMetricResponse(responseCode, responseMessage);
750 // Process the response
751 ObjectMapper mapper = AAIService.getObjectMapper();
752 BufferedReader reader;
754 reader = new BufferedReader( new InputStreamReader( inputStream ) );
755 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
757 if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
758 StringBuilder stringBuilder = new StringBuilder();
760 while( ( line = reader.readLine() ) != null ) {
761 stringBuilder.append( line );
763 LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder.length() > 0) ? stringBuilder.toString() : "{no-data}");
764 return stringBuilder.toString();
766 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
767 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
769 throw new AAIServiceException(responseCode, errorresponse);
771 } catch(AAIServiceException aaiexc) {
773 } catch (Exception exc) {
774 LOG.warn("AAIRequestExecutor.post", exc);
775 throw new AAIServiceException(exc);
778 if(inputStream != null)
780 } catch (Exception exc) {
781 LOG.warn("AAIRequestExecutor.post", exc);
793 protected HttpURLConnection getConfiguredConnection(URL httpReqUrl, String method) throws Exception {
794 HttpURLConnection con = (HttpURLConnection) httpReqUrl.openConnection();
796 // Set up the connection properties
797 con.setRequestProperty("Connection", "close");
798 con.setDoInput(true);
799 con.setDoOutput(true);
800 con.setUseCaches(false);
801 con.setConnectTimeout(connection_timeout);
802 con.setReadTimeout(read_timeout);
803 con.setRequestMethod(method);
804 con.setRequestProperty("Accept", "application/json");
805 con.setRequestProperty("Transfer-Encoding","chunked");
806 con.setRequestProperty("Content-Type",
807 "PATCH".equalsIgnoreCase(method) ? "application/merge-patch+json" : "application/json");
808 con.setRequestProperty("X-FromAppId", applicationId);
809 con.setRequestProperty("X-TransactionId", TransactionIdTracker.getNextTransactionId());
810 con.setRequestProperty("X-DslApiVersion", "V2");
811 String mlId = ml.getRequestID();
812 if (mlId != null && !mlId.isEmpty()) {
813 LOG.debug(String.format("MetricLogger requestId = %s", mlId));
814 con.setRequestProperty(ONAPLogConstants.MDCs.REQUEST_ID, mlId);
816 LOG.debug("MetricLogger requestId is null");
819 if (userName != null && !userName.isEmpty() && userPassword != null && !userPassword.isEmpty()) {
820 String basicAuth = "Basic " + new String(Base64.encodeBase64((userName + ":" + userPassword).getBytes()));
821 con.setRequestProperty("Authorization", basicAuth);
824 if (con instanceof HttpsURLConnection && CTX != null) {
825 SSLSocketFactory sockFact = CTX.getSocketFactory();
826 HttpsURLConnection.class.cast(con).setSSLSocketFactory(sockFact);
831 private URL appendDepth(URL requestUrl, AAIRequest request) throws MalformedURLException, URISyntaxException {
832 final String NODES_ONLY = "nodes-only";
833 URIBuilder builder = new URIBuilder(requestUrl.toURI());
834 // PROCESS nodes-only option
835 if (request.requestProperties.containsKey(NODES_ONLY)) {
836 if(request.requestProperties.containsKey(NODES_ONLY)) {
837 String nodesOnly = request.requestProperties.getProperty(NODES_ONLY);
838 if(nodesOnly != null && !nodesOnly.isEmpty()) {
839 builder.setParameter(NODES_ONLY, nodesOnly);
842 // do not add depth by default with nodes-only
843 if(!request.requestProperties.containsKey("depth")) {
844 return builder.build().toURL();
848 String depth = request.requestProperties.getProperty("depth", "1");
850 builder.setParameter("depth", depth);
852 return builder.build().toURL();
855 public void logMetricRequest(String targetServiceName, String msg, String path){
856 String svcInstanceId = "";
857 String svcName = null;
858 String partnerName = null;
859 String targetEntity = "A&AI";
860 String targetVirtualEntity = null;
862 ml.logRequest(svcInstanceId, svcName, partnerName, targetEntity, targetServiceName, targetVirtualEntity, msg);
865 public void logMetricResponse(int responseCode, String responseDescription){
866 ml.logResponse(responseCode < 400 ? "COMPLETE" : "ERROR", Integer.toString(responseCode), responseDescription);
869 protected void LOGwriteFirstTrace(String method, String url) {
870 String time = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(System.currentTimeMillis());
871 LOG.info("A&AI transaction :");
872 LOG.info("Request Time : " + time + ", Method : " + method);
873 LOG.info("Request URL : "+ url);
876 protected void LOGwriteDateTrace(String name, String data) {
877 LOG.info("Input - " + name + " : " + data);
880 protected void LOGwriteEndingTrace(int response_code, String comment, String data) {
881 LOG.info("Response code : " + response_code +", " + comment);
882 LOG.info(String.format("Response data : %s", data));