Isolate deprecated code in CCSDK aai-service
[ccsdk/sli/adaptors.git] / aai-service / provider / src / main / java / org / onap / ccsdk / sli / adaptors / aai / AAIClientRESTExecutor.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.ccsdk.sli.adaptors.aai;
23
24 import java.io.BufferedReader;
25 import java.io.ByteArrayInputStream;
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.InputStream;
29 import java.io.InputStreamReader;
30 import java.io.OutputStreamWriter;
31 import java.lang.reflect.Field;
32 import java.lang.reflect.InvocationTargetException;
33 import java.lang.reflect.Method;
34 import java.lang.reflect.Modifier;
35 import java.net.HttpURLConnection;
36 import java.net.MalformedURLException;
37 import java.net.URL;
38 import java.nio.charset.StandardCharsets;
39 import java.security.KeyManagementException;
40 import java.security.KeyStore;
41 import java.security.NoSuchAlgorithmException;
42 import java.text.SimpleDateFormat;
43 import java.util.Properties;
44
45 import javax.net.ssl.HostnameVerifier;
46 import javax.net.ssl.HttpsURLConnection;
47 import javax.net.ssl.KeyManagerFactory;
48 import javax.net.ssl.SSLContext;
49 import javax.net.ssl.SSLSession;
50 import javax.net.ssl.SSLSocketFactory;
51 import javax.net.ssl.TrustManager;
52 import javax.ws.rs.HttpMethod;
53
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.core.sli.MetricLogger;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
64
65 import com.fasterxml.jackson.databind.DeserializationFeature;
66 import com.fasterxml.jackson.databind.ObjectMapper;
67 import com.sun.jersey.api.client.config.DefaultClientConfig;
68 import com.sun.jersey.client.urlconnection.HTTPSProperties;
69
70 public  class AAIClientRESTExecutor implements AAIExecutorInterface {
71
72         private final String truststorePath;
73         private final String truststorePassword;
74         private final String keystorePath;
75         private final String keystorePassword;
76         private final Boolean ignoreCertificateHostError;
77         // authentication credentials
78         private String userName;
79         private String userPassword;
80         private final String applicationId;
81         
82         public AAIClientRESTExecutor(Properties props) {
83                 super();
84
85         userName                        = props.getProperty(AAIService.CLIENT_NAME);
86         userPassword            = props.getProperty(AAIService.CLIENT_PWWD);
87
88         if(userName == null || userName.isEmpty()){
89                 LOG.debug("Basic user name is not set");
90         }
91         if(userPassword == null || userPassword.isEmpty()) {
92                 LOG.debug("Basic password is not set");
93         }
94
95                 truststorePath  = props.getProperty(AAIService.TRUSTSTORE_PATH);
96                 truststorePassword = props.getProperty(AAIService.TRUSTSTORE_PSSWD);
97                 keystorePath            = props.getProperty(AAIService.KEYSTORE_PATH);
98                 keystorePassword        = props.getProperty(AAIService.KEYSTORE_PSSWD);
99 //              this.read_timeout = read_timeout;
100                 
101                 String tmpApplicationId =props.getProperty(AAIService.APPLICATION_ID);
102                 if(tmpApplicationId == null || tmpApplicationId.isEmpty()) {
103                         tmpApplicationId = "SDNC";
104                 }
105                 applicationId = tmpApplicationId;
106                 
107                 String iche = props.getProperty(AAIService.CERTIFICATE_HOST_ERROR);
108                 boolean host_error = false;
109                 if(iche != null && !iche.isEmpty()) {
110                         host_error = Boolean.valueOf(iche);
111                 }
112
113                 ignoreCertificateHostError = host_error;
114
115         HttpsURLConnection.setDefaultHostnameVerifier( new HostnameVerifier(){
116             public boolean verify(String string,SSLSession ssls) {
117                 return ignoreCertificateHostError;
118             }
119         });
120
121                 if(truststorePath != null && truststorePassword != null && (new File(truststorePath)).exists()) {
122                         System.setProperty("javax.net.ssl.trustStore", truststorePath);
123                         System.setProperty("javax.net.ssl.trustStorePassword", truststorePassword);
124                 }
125
126 //              MyX509ExtendedTrustManager trustManager = null;
127 //              try {
128 //                      trustManager = new MyX509ExtendedTrustManager();
129 //              } catch (Exception e1) {
130 //                      // TODO Auto-generated catch block
131 //                      e1.printStackTrace();
132 //              }
133 //              
134 //              TrustManager[] trustManagers = {trustManager};
135                 
136         if(keystorePath != null && keystorePassword != null && (new File(keystorePath)).exists())
137         {
138                 DefaultClientConfig config = new DefaultClientConfig();
139                 //both jersey and HttpURLConnection can use this
140                 SSLContext ctx = null;
141                 try {
142                     ctx = SSLContext.getInstance("TLS");
143         
144                     KeyManagerFactory kmf = null;
145                     try {
146                         String def = "SunX509";
147                         String storeType = "PKCS12";
148                         def = KeyStore.getDefaultType();
149                         kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
150                         FileInputStream fin = new FileInputStream(keystorePath);
151         //                KeyStore ks = KeyStore.getInstance("PKCS12");
152         
153                         String extension = keystorePath.substring(keystorePath.lastIndexOf(".") + 1);
154         
155                         if(extension != null && !extension.isEmpty() && extension.equalsIgnoreCase("JKS")) {
156                                 storeType = "JKS";
157                         }
158                         KeyStore ks = KeyStore.getInstance(storeType);
159         
160                         char[] pwd = keystorePassword.toCharArray();
161                         ks.load(fin, pwd);
162                         kmf.init(ks, pwd);
163                     } catch (Exception ex) {
164                         LOG.error("AAIResource", ex);
165                     }
166         
167                     ctx.init(kmf.getKeyManagers(), null, null);
168                     config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties( new HostnameVerifier() {
169                             @Override
170                             public boolean verify( String s, SSLSession sslSession ) {
171                                 return ignoreCertificateHostError;
172                             }
173                     }, ctx));
174         
175                     CTX = ctx;
176                         LOG.debug("SSLContext created");
177         
178                 } catch (KeyManagementException | NoSuchAlgorithmException exc) {
179                         LOG.error("AAIResource", exc);
180                         }
181         }
182
183         try {
184             Field methodsField = HttpURLConnection.class.getDeclaredField("methods");
185             methodsField.setAccessible(true);
186             // get the methods field modifiers
187             Field modifiersField = Field.class.getDeclaredField("modifiers");
188             // bypass the "private" modifier
189             modifiersField.setAccessible(true);
190
191             // remove the "final" modifier
192             modifiersField.setInt(methodsField, methodsField.getModifiers() & ~Modifier.FINAL);
193
194             /* valid HTTP methods */
195             String[] methods = {
196                        "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "PATCH"
197             };
198             // set the new methods - including patch
199             methodsField.set(null, methods);
200
201         } catch (SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchFieldException e) {
202          e.printStackTrace();
203         }
204         LOG.info("AAIResource.ctor initialized.");
205                 
206         }
207
208         private static final Logger LOG = LoggerFactory.getLogger(AAIService.class);
209         private final MetricLogger ml = new MetricLogger();
210         
211         private SSLContext CTX;
212
213
214         private int connection_timeout = 300000;
215
216         private int read_timeout = 300000;
217         
218         /**
219          * Returns an String that contains JSON data returned from the AAI Server.  
220          * <p>
221          * This method always returns immediately, whether or not the 
222          * data exists. 
223          *
224          * @param  request  an instance of AAIRequiest representing 
225          *                              the request made by DirectedGraph node. 
226          * @return      the JSON based representation of data instance requested. 
227          * @see         String
228          */
229         @Override
230         public String get(AAIRequest request) throws AAIServiceException {
231                 String response = null;
232                 InputStream inputStream = null;
233                 HttpURLConnection con = null;
234                 URL requestUrl = null;
235
236                 StringBuilder errorStringBuilder = new StringBuilder();
237
238                 try {
239
240             if(request.getRequestObject() != null) {
241                 requestUrl = request.getRequestUrl(HttpMethod.POST, null);
242                 requestUrl = appendDepth(requestUrl, request);
243                 con = getConfiguredConnection(requestUrl, HttpMethod.POST);
244                 String json_text = request.toJSONString();
245                 LOGwriteDateTrace("data", json_text);
246                 logMetricRequest("POST "+requestUrl.getPath(), json_text, requestUrl.getPath());
247                 OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
248                 osw.write(json_text);
249                 osw.flush();
250             } else {
251                 requestUrl = request.getRequestUrl(HttpMethod.GET, null);
252                 requestUrl = appendDepth(requestUrl, request);
253                 con = getConfiguredConnection(requestUrl, HttpMethod.GET);
254                 logMetricRequest("GET "+requestUrl.getPath(), "", requestUrl.getPath());
255             }
256
257             // Check for errors
258             String responseMessage = con.getResponseMessage();
259             int responseCode = con.getResponseCode();
260             if (responseCode == HttpURLConnection.HTTP_OK) {
261                 inputStream = con.getInputStream();
262             } else {
263                 inputStream = con.getErrorStream();
264             }
265
266             // Process the response
267             LOG.debug("HttpURLConnection result:" + responseCode + " : " + responseMessage);
268             logMetricResponse(responseCode, responseMessage);
269
270             if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8));
271             BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
272
273             ObjectMapper mapper = AAIService.getObjectMapper();
274
275                         if (responseCode == HttpURLConnection.HTTP_OK) {
276                                 StringBuilder stringBuilder = new StringBuilder();
277                                 String line = null;
278                                 while( ( line = reader.readLine() ) != null ) {
279                                         stringBuilder.append( line );
280                                 }
281                                 response = stringBuilder.toString();
282                                 try {
283                                         Object object = mapper.readValue(response, Object.class);
284                                         LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, responseMessage, mapper.writeValueAsString(object));
285                                 } catch(Exception exc) {
286                                         LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, responseMessage, mapper.writeValueAsString(response));
287                                 }
288             } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
289                 LOGwriteEndingTrace(responseCode, responseMessage, "Entry does not exist.");
290                 ErrorResponse errorresponse = null;
291                 try {
292                         errorresponse = mapper.readValue(reader, ErrorResponse.class);
293                 } catch(Exception exc) {
294                         errorresponse = new ErrorResponse();
295                         RequestError requestError = new RequestError();
296                         ServiceException serviceException = new ServiceException();
297                         serviceException.setText("Entry does not exist.");
298                                         requestError.setServiceException(serviceException);
299                                         errorresponse.setRequestError(requestError );
300                 }
301                 throw new AAIServiceException(responseCode, errorresponse);
302             } else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
303                                 StringBuilder stringBuilder = new StringBuilder();
304                                 String line = null;
305                                 while( ( line = reader.readLine() ) != null ) {
306                                         stringBuilder.append( line );
307                                 }
308                 LOGwriteEndingTrace(responseCode, responseMessage, stringBuilder.toString());
309                 ServiceException serviceException = new ServiceException();
310                 serviceException.setMessageId("HTTP_UNAUTHORIZED");
311                 serviceException.setText(stringBuilder.toString());
312                 RequestError requestError = new RequestError();
313                 requestError.setServiceException(serviceException);
314                 ErrorResponse errorresponse = new ErrorResponse();
315                 errorresponse.setRequestError(requestError);
316                 throw new AAIServiceException(responseCode, errorresponse);
317             } else {
318 //                              StringBuilder errorStringBuilder = new StringBuilder();
319                                 String line = null;
320                                 while( ( line = reader.readLine() ) != null ) {
321                                         errorStringBuilder.append("\n").append( line );
322                                 }
323
324                 ErrorResponse errorresponse = mapper.readValue(errorStringBuilder.toString(), ErrorResponse.class);
325 //              ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
326                 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
327                 throw new AAIServiceException(responseCode, errorresponse);
328             }
329
330                 } catch(AAIServiceException aaiexc) {
331                         throw aaiexc;
332                 } catch (Exception exc) {
333                         LOG.warn(errorStringBuilder.toString(), exc);
334                         throw new AAIServiceException(exc);
335                 } finally {
336                         if(inputStream != null){
337                                 try {
338                                         inputStream.close();
339                                 } catch(Exception exc) {
340
341                                 }
342                         }
343                 }
344                 return response;
345         }
346
347         @Override
348         public String post(AAIRequest request) throws AAIServiceException {
349                 InputStream inputStream = null;
350
351                 try {
352                         String resourceVersion = null;
353                         AAIDatum instance = request.getRequestObject();
354
355                         try {
356                                 Method getResourceVersionMethod = instance.getClass().getMethod("getResourceVersion");
357                                 if(getResourceVersionMethod != null){
358                                         try {
359                                                 Object object = getResourceVersionMethod.invoke(instance);
360                                                 if(object != null)
361                                                         resourceVersion = object.toString();
362                                         } catch (InvocationTargetException x) {
363                                                 Throwable cause = x.getCause();
364                                         }
365                                 }
366                         } catch(Exception exc) {
367                                 LOG.error("", exc);
368                         }
369
370                         URL requestUrl = null;
371                         HttpURLConnection con = getConfiguredConnection(requestUrl = request.getRequestUrl(HttpMethod.PUT, resourceVersion), HttpMethod.PUT);
372                         ObjectMapper mapper = AAIService.getObjectMapper();
373                         String json_text = request.toJSONString();
374
375                         LOGwriteDateTrace("data", json_text);
376                         logMetricRequest("PUT "+requestUrl.getPath(), json_text, requestUrl.getPath());
377
378                         OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
379             osw.write(json_text);
380             osw.flush();
381
382             // Check for errors
383             String responseMessage = con.getResponseMessage();
384             int responseCode = con.getResponseCode();
385             if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
386                 inputStream = con.getInputStream();
387             } else {
388                 inputStream = con.getErrorStream();
389             }
390
391             LOG.debug("HttpURLConnection result:" + responseCode + " : " + responseMessage);
392             logMetricResponse(responseCode, responseMessage);
393
394             // Process the response
395             BufferedReader reader;
396             String line = null;
397             reader = new BufferedReader( new InputStreamReader( inputStream ) );
398             mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
399
400                         if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
401                                 StringBuilder stringBuilder = new StringBuilder();
402
403                                 while( ( line = reader.readLine() ) != null ) {
404                                         stringBuilder.append( line );
405                                 }
406                                 LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder != null) ? stringBuilder.toString() : "{no-data}");
407                                 return stringBuilder.toString();
408             } else {
409                 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
410                 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
411
412                 throw new AAIServiceException(responseCode, errorresponse);
413             }
414                 } catch(AAIServiceException aaiexc) {
415                         throw aaiexc;
416                 } catch (Exception exc) {
417                         LOG.warn("AAIRequestExecutor.post", exc);
418                         throw new AAIServiceException(exc);
419                 } finally {
420                         try {
421                                 if(inputStream != null)
422                                 inputStream.close();
423                         } catch (Exception exc) {
424
425                         }
426                 }
427         }
428
429         @Override
430         public Boolean delete(AAIRequest request, String resourceVersion) throws AAIServiceException {
431                 Boolean response = null;
432                 InputStream inputStream = null;
433
434                 if(resourceVersion == null) {
435                         throw new AAIServiceException("resource-version is required for DELETE request");
436                 }
437
438                 try {
439                         URL requestUrl = null;
440             HttpURLConnection conn = getConfiguredConnection(requestUrl = request.getRequestUrl(HttpMethod.DELETE, resourceVersion), HttpMethod.DELETE);
441             logMetricRequest("DELETE "+requestUrl.getPath(), "", requestUrl.getPath());
442             conn.setDoOutput(true);
443 //            if(request.isDeleteDataRequired()) {
444 //                              String json_text = request.toJSONString();
445 //
446 //                              LOGwriteDateTrace("data", json_text);
447 //                              OutputStream os = con.getOutputStream();
448 //                  OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
449 //                  osw.write(json_text);
450 //                  osw.flush();
451 //            }
452
453             // Check for errors
454             String responseMessage = conn.getResponseMessage();
455             int responseCode = conn.getResponseCode();
456             if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
457                 inputStream = conn.getInputStream();
458             } else {
459                 inputStream = conn.getErrorStream();
460             }
461
462             // Process the response
463             LOG.debug("HttpURLConnection result:" + responseCode + " : " + responseMessage);
464             logMetricResponse(responseCode, responseMessage);
465
466             if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8));
467             BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
468             String line = null;
469
470             ObjectMapper mapper = AAIService.getObjectMapper();
471
472                         if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
473                                 StringBuilder stringBuilder = new StringBuilder();
474
475                                 while( ( line = reader.readLine() ) != null ) {
476                                         stringBuilder.append( line );
477                                 }
478                                 LOGwriteEndingTrace(responseCode, responseMessage, stringBuilder.toString());
479                                 response = true;
480                         } else if(responseCode == HttpURLConnection.HTTP_NOT_FOUND ) {
481                                 LOGwriteEndingTrace(responseCode, responseMessage, "Entry does not exist.");
482                                 response = false;
483             } else {
484                 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
485                 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
486                 throw new AAIServiceException(responseCode, errorresponse);
487             }
488                 } catch(AAIServiceException aaiexc) {
489                         throw aaiexc;
490                 } catch (Exception exc) {
491                         LOG.warn("delete", exc);
492                         throw new AAIServiceException(exc);
493                 } finally {
494                         if(inputStream != null){
495                                 try {
496                                         inputStream.close();
497                                 } catch(Exception exc) {
498
499                                 }
500                         }
501                 }
502                 return response;
503         }
504
505         @Override
506         public Object query(AAIRequest request, Class clas) throws AAIServiceException {
507                 Object response = null;
508                 InputStream inputStream = null;
509                 HttpURLConnection con = null;
510                 URL requestUrl = null;
511
512                 try {
513             con = getConfiguredConnection(requestUrl = request.getRequestQueryUrl(HttpMethod.GET), HttpMethod.GET);
514             logMetricRequest("GET "+requestUrl.getPath(), "", requestUrl.getPath());
515
516             // Check for errors
517             String responseMessage = con.getResponseMessage();
518             int responseCode = con.getResponseCode();
519             if (responseCode == HttpURLConnection.HTTP_OK) {
520                 inputStream = con.getInputStream();
521             } else {
522                 inputStream = con.getErrorStream();
523             }
524
525             logMetricResponse(responseCode, responseMessage);
526             ObjectMapper mapper = AAIService.getObjectMapper();
527
528                         if (responseCode == HttpURLConnection.HTTP_OK) {
529                                 // Process the response
530                                 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
531                                 response = mapper.readValue(reader, clas);
532                 LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, "SUCCESS", mapper.writeValueAsString(response));
533             } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
534                 LOGwriteEndingTrace(responseCode, "HTTP_NOT_FOUND", "Entry does not exist.");
535                 return response;
536                         } else {
537                                 BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) );
538                 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
539                 LOGwriteEndingTrace(responseCode, "FAILURE", mapper.writeValueAsString(errorresponse));
540                 throw new AAIServiceException(responseCode, errorresponse);
541             }
542
543                 } catch(AAIServiceException aaiexc) {
544                         throw aaiexc;
545                 } catch (Exception exc) {
546                         LOG.warn("GET", exc);
547                         throw new AAIServiceException(exc);
548                 } finally {
549                         if(inputStream != null){
550                                 try {
551                                         inputStream.close();
552                                 } catch(Exception exc) {
553
554                                 }
555                         }
556                         con = null;
557                 }
558                 return response;
559         }
560
561         @Override
562         public Boolean patch(AAIRequest request, String resourceVersion) throws AAIServiceException {
563                 InputStream inputStream = null;
564
565                 try {
566                         AAIDatum instance = request.getRequestObject();
567                         if(instance instanceof ResourceVersion) {
568                                 resourceVersion = ((ResourceVersion)instance).getResourceVersion();
569                         }
570
571                         URL requestUrl = null;
572                         HttpURLConnection con = getConfiguredConnection(requestUrl = request.getRequestUrl("PATCH", resourceVersion), "PATCH");
573                         ObjectMapper mapper = AAIService.getObjectMapper();
574                         String json_text = request.toJSONString();
575
576                         LOGwriteDateTrace("data", json_text);
577                         logMetricRequest("PATCH "+requestUrl.getPath(), json_text, requestUrl.getPath());
578
579                         OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
580             osw.write(json_text);
581             osw.flush();
582
583             // Check for errors
584             String responseMessage = con.getResponseMessage();
585             int responseCode = con.getResponseCode();
586             if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
587                 inputStream = con.getInputStream();
588             } else {
589                 inputStream = con.getErrorStream();
590             }
591
592             LOG.info("HttpURLConnection result: " + responseCode + " : " + responseMessage);
593             logMetricResponse(responseCode, responseMessage);
594
595             // Process the response
596             BufferedReader reader;
597             String line = null;
598             reader = new BufferedReader( new InputStreamReader( inputStream ) );
599             mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
600
601                         if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
602                                 StringBuilder stringBuilder = new StringBuilder();
603
604                                 while( ( line = reader.readLine() ) != null ) {
605                                         stringBuilder.append( line );
606                                 }
607                                 LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder != null) ? stringBuilder.toString() : "{no-data}");
608                                 return true;
609             } else {
610                                 StringBuilder stringBuilder = new StringBuilder();
611
612                                 while( ( line = reader.readLine() ) != null ) {
613                                         stringBuilder.append("\n").append( line );
614                                 }
615                                 LOG.info(stringBuilder.toString());
616
617
618                 ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class);
619                 LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse));
620
621                 throw new AAIServiceException(responseCode, errorresponse);
622             }
623                 } catch(AAIServiceException aaiexc) {
624                         throw aaiexc;
625                 } catch (Exception exc) {
626                         LOG.warn("AAIRequestExecutor.patch", exc);
627                         throw new AAIServiceException(exc);
628                 } finally {
629                         try {
630                                 if(inputStream != null)
631                                 inputStream.close();
632                         } catch (Exception exc) {
633
634                         }
635                 }
636         }
637         
638         /**
639          *
640          * @param httpReqUrl
641          * @param method
642          * @return
643          * @throws Exception
644          */
645         protected HttpURLConnection getConfiguredConnection(URL httpReqUrl, String method) throws Exception {
646                 HttpURLConnection con = (HttpURLConnection) httpReqUrl.openConnection();
647
648                 // Set up the connection properties
649                 con.setRequestProperty("Connection", "close");
650                 con.setDoInput(true);
651                 con.setDoOutput(true);
652                 con.setUseCaches(false);
653                 con.setConnectTimeout(connection_timeout);
654                 con.setReadTimeout(read_timeout);
655                 con.setRequestMethod(method);
656                 con.setRequestProperty("Accept", "application/json");
657                 // con.setRequestProperty( "Accept-Encoding", "gzip,compress" );
658                 con.setRequestProperty("Transfer-Encoding","chunked");
659                 con.setRequestProperty("Content-Type",
660                                 "PATCH".equalsIgnoreCase(method) ? "application/merge-patch+json" : "application/json");
661                 con.setRequestProperty("X-FromAppId", applicationId);
662                 con.setRequestProperty("X-TransactionId", TransactionIdTracker.getNextTransactionId());
663                 String mlId = ml.getRequestID();
664                 if (mlId != null && !mlId.isEmpty()) {
665                         LOG.debug(String.format("MetricLogger requestId = %s", mlId));
666                         con.setRequestProperty(MetricLogger.REQUEST_ID, mlId);
667                 } else {
668                         LOG.debug("MetricLogger requestId is null");
669                 }
670
671                 if (userName != null && !userName.isEmpty() && userPassword != null && !userPassword.isEmpty()) {
672                         String basicAuth = "Basic " + new String(Base64.encodeBase64((userName + ":" + userPassword).getBytes()));
673                         con.setRequestProperty("Authorization", basicAuth);
674                 }
675
676                 if (con instanceof HttpsURLConnection && CTX != null) {
677                         SSLSocketFactory sockFact = CTX.getSocketFactory();
678                         HttpsURLConnection.class.cast(con).setSSLSocketFactory(sockFact);
679                 }
680                 return con;
681         }
682         
683         private URL appendDepth(URL requestUrl, AAIRequest request) throws MalformedURLException {
684         
685                 String depth = request.requestProperties.getProperty("depth", "1");
686                 String path = requestUrl.toString();
687                 if(path.contains("?depth=") || path.contains("&depth=")) {
688                         return requestUrl;
689                 } else {
690                         if(path.contains("?")) {
691                                 path = String.format("%s&depth=%s", path, depth);
692                         } else {
693                                 path = String.format("%s?depth=%s", path, depth);
694                         }
695                         return new URL(path);
696                 }
697         }
698
699         public void logMetricRequest(String targetServiceName, String msg, String path){
700                 String svcInstanceId = "";
701                 String svcName = null;
702                 String partnerName = null;
703                 String targetEntity = "A&AI";
704                 String targetVirtualEntity = null;
705
706                 targetServiceName = "";
707
708                 ml.logRequest(svcInstanceId, svcName, partnerName, targetEntity, targetServiceName, targetVirtualEntity, msg);
709         }
710
711         public void logMetricResponse(int responseCode, String responseDescription){
712                 ml.logResponse(responseCode < 400 ? "SUCCESS" : "FAILURE", Integer.toString(responseCode), responseDescription);
713         }
714         
715         protected void LOGwriteFirstTrace(String method, String url) {
716                 String time = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(System.currentTimeMillis());
717                 LOG.info("A&AI transaction :");
718                 LOG.info("Request Time : " + time + ", Method : " + method);
719                 LOG.info("Request URL : "+ url);
720         }
721
722         protected void LOGwriteDateTrace(String name, String data) {
723                 LOG.info("Input - " + name  + " : " + data);
724         }
725
726         protected void LOGwriteEndingTrace(int response_code, String comment, String data) {
727                 LOG.info("Response code : " + response_code +", " + comment);
728                 LOG.info(String.format("Response data : %s", data));
729         }
730
731 }