Merge "[AAI] Fix doc config files"
[aai/aai-common.git] / aai-els-onap-logging / src / main / java / org / onap / aai / logging / ErrorLogHelper.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *    http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.aai.logging;
22
23 import java.io.FileInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.StringWriter;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map.Entry;
32 import java.util.Properties;
33
34 import javax.ws.rs.core.MediaType;
35 import javax.xml.bind.JAXBContext;
36 import javax.xml.bind.Marshaller;
37
38 import org.apache.commons.lang3.StringUtils;
39 import org.onap.aai.exceptions.AAIException;
40 import org.onap.aai.util.AAIConstants;
41 import org.onap.aai.util.MapperUtil;
42 import org.onap.logging.filter.base.Constants;
43 import org.onap.logging.filter.base.MDCSetup;
44 import org.onap.logging.ref.slf4j.ONAPLogConstants;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47 import org.slf4j.MDC;
48
49 /**
50  *
51  * This classes loads the application error properties file
52  * and provides a method that returns an ErrorObject
53  *
54  */
55
56 public class ErrorLogHelper {
57     private static final Logger LOGGER = LoggerFactory.getLogger(ErrorLogHelper.class);
58     private static final HashMap<String, ErrorObject> ERROR_OBJECTS = new HashMap<String, ErrorObject>();
59
60     static {
61         try {
62             loadProperties();
63         } catch (IOException e) {
64             throw new RuntimeException("Failed to load error.properties file", e);
65         } catch (ErrorObjectFormatException e) {
66             throw new RuntimeException("Failed to parse error.properties file", e);
67         }
68     }
69
70     /**
71      * Load properties.
72      * 
73      * @throws IOException the exception
74      * @throws ErrorObjectFormatException
75      */
76     public static void loadProperties() throws IOException, ErrorObjectFormatException {
77         final String filePath = AAIConstants.AAI_HOME_ETC_APP_PROPERTIES + "error.properties";
78         final InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("error.properties");
79         final Properties properties = new Properties();
80
81         try (final FileInputStream fis = new FileInputStream(filePath)) {
82             LOGGER.info("Found the error.properties in the following location: {}",
83                     AAIConstants.AAI_HOME_ETC_APP_PROPERTIES);
84             properties.load(fis);
85         } catch (Exception ex) {
86             LOGGER.info("Unable to find the error.properties from filesystem so using file in jar");
87             if (is != null) {
88                 properties.load(is);
89             } else {
90                 LOGGER.error("Expected to find the error.properties in the jar but unable to find it");
91             }
92         }
93
94         for (Entry<Object, Object> entry : properties.entrySet()) {
95             final String key = (String) entry.getKey();
96             final String value = (String) entry.getValue();
97             final String[] errorProperties = value.split(":");
98
99             if (errorProperties.length < 7)
100                 throw new ErrorObjectFormatException();
101
102             final ErrorObject errorObject = new ErrorObject();
103
104             errorObject.setDisposition(errorProperties[0].trim());
105             errorObject.setCategory(errorProperties[1].trim());
106             errorObject.setSeverity(errorProperties[2].trim());
107             errorObject.setErrorCode(errorProperties[3].trim());
108             errorObject.setHTTPResponseCode(errorProperties[4].trim());
109             errorObject.setRESTErrorCode(errorProperties[5].trim());
110             errorObject.setErrorText(errorProperties[6].trim());
111             if (errorProperties.length > 7) {
112                 errorObject.setAaiElsErrorCode(errorProperties[7].trim());
113             }
114
115             ERROR_OBJECTS.put(key, errorObject);
116         }
117     }
118
119     /**
120      * Logs a known A&AI exception (i.e. one that can be found in error.properties)
121      *
122      * @param code for the error in the error.properties file
123      * @throws IOException
124      * @throws ErrorObjectNotFoundException
125      */
126     public static ErrorObject getErrorObject(String code) throws ErrorObjectNotFoundException {
127
128         if (code == null)
129             throw new IllegalArgumentException("Key cannot be null");
130
131         final ErrorObject errorObject = ERROR_OBJECTS.get(code);
132
133         if (errorObject == null) {
134             LOGGER.warn("Unknown AAIException with code=" + code + ".  Using default AAIException");
135             return ERROR_OBJECTS.get(AAIException.DEFAULT_EXCEPTION_CODE);
136         }
137
138         return errorObject;
139     }
140
141     /**
142      * Determines whether category is policy or not. If policy (1), this is a POL error, else it's a SVC error.
143      * The AAIRESTException may contain a different ErrorObject than that created with the REST error key.
144      * This allows lower level exception detail to be returned to the client to help troubleshoot the problem.
145      * If no error object is embedded in the AAIException, one will be created using the error object from the
146      * AAIException.
147      *
148      * @param are must have a restError value whose numeric value must match what should be returned in the REST API
149      * @param variables optional list of variables to flesh out text in error string
150      * @return appropriately formatted JSON response per the REST API spec.
151      * @throws IOException
152      * @deprecated
153      */
154     public static String getRESTAPIErrorResponse(AAIException are, ArrayList<String> variables) {
155         List<MediaType> acceptHeaders = new ArrayList<MediaType>();
156         acceptHeaders.add(MediaType.APPLICATION_JSON_TYPE);
157
158         return getRESTAPIErrorResponse(acceptHeaders, are, variables);
159     }
160
161     /**
162      * Determines whether category is policy or not. If policy (1), this is a POL error, else it's a SVC error.
163      * The AAIRESTException may contain a different ErrorObject than that created with the REST error key.
164      * This allows lower level exception detail to be returned to the client to help troubleshoot the problem.
165      * If no error object is embedded in the AAIException, one will be created using the error object from the
166      * AAIException.
167      *
168      * @param acceptHeadersOrig the accept headers orig
169      * @param are must have a restError value whose numeric value must match what should be returned in the REST API
170      * @param variables optional list of variables to flesh out text in error string
171      * @return appropriately formatted JSON response per the REST API spec.
172      */
173     public static String getRESTAPIErrorResponse(List<MediaType> acceptHeadersOrig, AAIException are,
174             ArrayList<String> variables) {
175
176         StringBuilder text = new StringBuilder();
177         String response = null;
178
179         List<MediaType> acceptHeaders = new ArrayList<MediaType>();
180         // we might have an exception but no accept header, so we'll set default to JSON
181         boolean foundValidAcceptHeader = false;
182         for (MediaType mt : acceptHeadersOrig) {
183             if (MediaType.APPLICATION_XML_TYPE.isCompatible(mt) || MediaType.APPLICATION_JSON_TYPE.isCompatible(mt)) {
184                 acceptHeaders.add(mt);
185                 foundValidAcceptHeader = true;
186             }
187         }
188         if (foundValidAcceptHeader == false) {
189             // override the exception, client needs to set an appropriate Accept header
190             are = new AAIException("AAI_4014");
191             acceptHeaders.add(MediaType.APPLICATION_JSON_TYPE);
192         }
193
194         final ErrorObject eo = are.getErrorObject();
195
196         int restErrorCode = Integer.parseInt(eo.getRESTErrorCode());
197
198         ErrorObject restErrorObject;
199
200         try {
201             restErrorObject = ErrorLogHelper.getErrorObject("AAI_" + restErrorCode);
202         } catch (ErrorObjectNotFoundException e) {
203             LOGGER.warn("Failed to find related error object AAI_" + restErrorCode + " for error object "
204                     + eo.getErrorCode() + "; using AAI_" + restErrorCode);
205             restErrorObject = eo;
206         }
207
208         text.append(restErrorObject.getErrorText());
209
210         // We want to always append the (msg=%n) (ec=%n+1) to the text, but have to find value of n
211         // This assumes that the variables in the ArrayList, which might be more than are needed to flesh out the
212         // error, are ordered based on the error string.
213         int localDataIndex = StringUtils.countMatches(restErrorObject.getErrorText(), "%");
214         text.append(" (msg=%").append(localDataIndex + 1).append(") (ec=%").append(localDataIndex + 2).append(")");
215
216         if (variables == null) {
217             variables = new ArrayList<String>();
218         }
219
220         if (variables.size() < localDataIndex) {
221             ErrorLogHelper.logError("AAI_4011", "data missing for rest error");
222             while (variables.size() < localDataIndex) {
223                 variables.add("null");
224             }
225         }
226
227         // This will put the error code and error text into the right positions
228         if (are.getMessage() == null || are.getMessage().length() == 0) {
229             variables.add(localDataIndex++, eo.getErrorText());
230         } else {
231             variables.add(localDataIndex++, eo.getErrorText() + ":" + are.getMessage());
232         }
233         variables.add(localDataIndex, eo.getErrorCodeString());
234
235         for (MediaType mediaType : acceptHeaders) {
236             if (MediaType.APPLICATION_XML_TYPE.isCompatible(mediaType)) {
237                 JAXBContext context = null;
238                 try {
239                     if (eo.getCategory().equals("1")) {
240
241                         context = JAXBContext.newInstance(org.onap.aai.domain.restPolicyException.Fault.class);
242                         Marshaller m = context.createMarshaller();
243                         m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
244                         m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
245
246                         org.onap.aai.domain.restPolicyException.ObjectFactory factory =
247                                 new org.onap.aai.domain.restPolicyException.ObjectFactory();
248                         org.onap.aai.domain.restPolicyException.Fault fault = factory.createFault();
249                         org.onap.aai.domain.restPolicyException.Fault.RequestError requestError =
250                                 factory.createFaultRequestError();
251                         org.onap.aai.domain.restPolicyException.Fault.RequestError.PolicyException policyException =
252                                 factory.createFaultRequestErrorPolicyException();
253                         org.onap.aai.domain.restPolicyException.Fault.RequestError.PolicyException.Variables polvariables =
254                                 factory.createFaultRequestErrorPolicyExceptionVariables();
255
256                         policyException.setMessageId("POL" + eo.getRESTErrorCode());
257                         policyException.setText(text.toString());
258                         for (int i = 0; i < variables.size(); i++) {
259                             polvariables.getVariable().add(variables.get(i));
260                         }
261                         policyException.setVariables(polvariables);
262                         requestError.setPolicyException(policyException);
263                         fault.setRequestError(requestError);
264
265                         StringWriter sw = new StringWriter();
266                         m.marshal(fault, sw);
267
268                         response = sw.toString();
269
270                     } else {
271
272                         context = JAXBContext.newInstance(org.onap.aai.domain.restServiceException.Fault.class);
273                         Marshaller m = context.createMarshaller();
274                         m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
275                         m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
276
277                         org.onap.aai.domain.restServiceException.ObjectFactory factory =
278                                 new org.onap.aai.domain.restServiceException.ObjectFactory();
279                         org.onap.aai.domain.restServiceException.Fault fault = factory.createFault();
280                         org.onap.aai.domain.restServiceException.Fault.RequestError requestError =
281                                 factory.createFaultRequestError();
282                         org.onap.aai.domain.restServiceException.Fault.RequestError.ServiceException serviceException =
283                                 factory.createFaultRequestErrorServiceException();
284                         org.onap.aai.domain.restServiceException.Fault.RequestError.ServiceException.Variables svcvariables =
285                                 factory.createFaultRequestErrorServiceExceptionVariables();
286                         serviceException.setMessageId("SVC" + eo.getRESTErrorCode());
287                         serviceException.setText(text.toString());
288                         for (int i = 0; i < variables.size(); i++) {
289                             svcvariables.getVariable().add(variables.get(i));
290                         }
291                         serviceException.setVariables(svcvariables);
292                         requestError.setServiceException(serviceException);
293                         fault.setRequestError(requestError);
294
295                         StringWriter sw = new StringWriter();
296                         m.marshal(fault, sw);
297
298                         response = sw.toString();
299
300                     }
301                 } catch (Exception ex) {
302                     LOGGER.error(
303                             "We were unable to create a rest exception to return on an API because of a parsing error "
304                                     + ex.getMessage());
305                 }
306             } else {
307                 try {
308                     if (eo.getCategory().equals("1")) {
309                         org.onap.aai.domain.restPolicyException.RESTResponse restresp =
310                                 new org.onap.aai.domain.restPolicyException.RESTResponse();
311                         org.onap.aai.domain.restPolicyException.RequestError reqerr =
312                                 new org.onap.aai.domain.restPolicyException.RequestError();
313                         org.onap.aai.domain.restPolicyException.PolicyException polexc =
314                                 new org.onap.aai.domain.restPolicyException.PolicyException();
315                         polexc.setMessageId("POL" + eo.getRESTErrorCode());
316                         polexc.setText(text.toString());
317                         polexc.setVariables(variables);
318                         reqerr.setPolicyException(polexc);
319                         restresp.setRequestError(reqerr);
320                         response = (MapperUtil.writeAsJSONString((Object) restresp));
321
322                     } else {
323                         org.onap.aai.domain.restServiceException.RESTResponse restresp =
324                                 new org.onap.aai.domain.restServiceException.RESTResponse();
325                         org.onap.aai.domain.restServiceException.RequestError reqerr =
326                                 new org.onap.aai.domain.restServiceException.RequestError();
327                         org.onap.aai.domain.restServiceException.ServiceException svcexc =
328                                 new org.onap.aai.domain.restServiceException.ServiceException();
329                         svcexc.setMessageId("SVC" + eo.getRESTErrorCode());
330                         svcexc.setText(text.toString());
331                         svcexc.setVariables(variables);
332                         reqerr.setServiceException(svcexc);
333                         restresp.setRequestError(reqerr);
334                         response = (MapperUtil.writeAsJSONString((Object) restresp));
335                     }
336                 } catch (Exception ex) {
337                     LOGGER.error(
338                             "We were unable to create a rest exception to return on an API because of a parsing error "
339                                     + ex.getMessage());
340                 }
341             }
342         }
343
344         return response;
345     }
346
347     /**
348      * Gets the RESTAPI error response with logging.
349      *
350      * @param acceptHeadersOrig the accept headers orig
351      * @param are the are
352      * @param variables the variables
353      */
354     public static String getRESTAPIErrorResponseWithLogging(List<MediaType> acceptHeadersOrig, AAIException are,
355             ArrayList<String> variables) {
356         String response = ErrorLogHelper.getRESTAPIErrorResponse(acceptHeadersOrig, are, variables);
357         logException(are);
358         return response;
359     }
360
361     /**
362      * Gets the RESTAPI info response.
363      *
364      * @param acceptHeaders the accept headers
365      * @param areList the are list
366      * @return the RESTAPI info response
367      */
368     public static Object getRESTAPIInfoResponse(List<MediaType> acceptHeaders,
369             HashMap<AAIException, ArrayList<String>> areList) {
370
371         Object respObj = null;
372
373         org.onap.aai.domain.restResponseInfo.ObjectFactory factory =
374                 new org.onap.aai.domain.restResponseInfo.ObjectFactory();
375         org.onap.aai.domain.restResponseInfo.Info info = factory.createInfo();
376         org.onap.aai.domain.restResponseInfo.Info.ResponseMessages responseMessages =
377                 factory.createInfoResponseMessages();
378         Iterator<Entry<AAIException, ArrayList<String>>> it = areList.entrySet().iterator();
379
380         while (it.hasNext()) {
381             Entry<AAIException, ArrayList<String>> pair = (Entry<AAIException, ArrayList<String>>) it.next();
382             AAIException are = pair.getKey();
383             ArrayList<String> variables = pair.getValue();
384
385             StringBuilder text = new StringBuilder();
386
387             ErrorObject eo = are.getErrorObject();
388
389             int restErrorCode = Integer.parseInt(eo.getRESTErrorCode());
390             ErrorObject restErrorObject;
391             try {
392                 restErrorObject = ErrorLogHelper.getErrorObject("AAI_" + String.format("%04d", restErrorCode));
393             } catch (ErrorObjectNotFoundException e) {
394                 restErrorObject = eo;
395             }
396             text.append(restErrorObject.getErrorText());
397
398             // We want to always append the (msg=%n) (ec=%n+1) to the text, but have to find value of n
399             // This assumes that the variables in the ArrayList, which might be more than are needed to flesh out the
400             // error, are ordered based on the error string.
401             int localDataIndex = StringUtils.countMatches(restErrorObject.getErrorText(), "%");
402             text.append(" (msg=%").append(localDataIndex + 1).append(") (rc=%").append(localDataIndex + 2).append(")");
403
404             if (variables == null) {
405                 variables = new ArrayList<String>();
406             }
407
408             if (variables.size() < localDataIndex) {
409                 ErrorLogHelper.logError("AAI_4011", "data missing for rest error");
410                 while (variables.size() < localDataIndex) {
411                     variables.add("null");
412                 }
413             }
414
415             // This will put the error code and error text into the right positions
416             if (are.getMessage() == null) {
417                 variables.add(localDataIndex++, eo.getErrorText());
418             } else {
419                 variables.add(localDataIndex++, eo.getErrorText() + ":" + are.getMessage());
420             }
421             variables.add(localDataIndex, eo.getErrorCodeString());
422
423             try {
424                 org.onap.aai.domain.restResponseInfo.Info.ResponseMessages.ResponseMessage responseMessage =
425                         factory.createInfoResponseMessagesResponseMessage();
426                 org.onap.aai.domain.restResponseInfo.Info.ResponseMessages.ResponseMessage.Variables infovariables =
427                         factory.createInfoResponseMessagesResponseMessageVariables();
428
429                 responseMessage.setMessageId("INF" + eo.getRESTErrorCode());
430                 responseMessage.setText(text.toString());
431                 for (int i = 0; i < variables.size(); i++) {
432                     infovariables.getVariable().add(variables.get(i));
433                 }
434
435                 responseMessage.setVariables(infovariables);
436                 responseMessages.getResponseMessage().add(responseMessage);
437
438             } catch (Exception ex) {
439                 LOGGER.error("We were unable to create a rest exception to return on an API because of a parsing error "
440                         + ex.getMessage());
441             }
442         }
443
444         info.setResponseMessages(responseMessages);
445         respObj = (Object) info;
446
447         return respObj;
448     }
449
450     /**
451      * Determines whether category is policy or not. If policy (1), this is a POL error, else it's a SVC error.
452      * The AAIRESTException may contain a different ErrorObject than that created with the REST error key.
453      * This allows lower level exception detail to be returned to the client to help troubleshoot the problem.
454      * If no error object is embedded in the AAIException, one will be created using the error object from the
455      * AAIException.
456      *
457      * @param are must have a restError value whose numeric value must match what should be returned in the REST API
458      * @param variables optional list of variables to flesh out text in error string
459      * @return appropriately formatted JSON response per the REST API spec.
460      */
461     public static String getRESTAPIPolicyErrorResponseXML(AAIException are, ArrayList<String> variables) {
462
463         StringBuilder text = new StringBuilder();
464         String response = null;
465         JAXBContext context = null;
466
467         ErrorObject eo = are.getErrorObject();
468
469         int restErrorCode = Integer.parseInt(eo.getRESTErrorCode());
470         ErrorObject restErrorObject;
471         try {
472             restErrorObject = ErrorLogHelper.getErrorObject("AAI_" + restErrorCode);
473         } catch (ErrorObjectNotFoundException e) {
474             restErrorObject = eo;
475         }
476
477         text.append(restErrorObject.getErrorText());
478
479         // We want to always append the (msg=%n) (ec=%n+1) to the text, but have to find value of n
480         // This assumes that the variables in the ArrayList, which might be more than are needed to flesh out the
481         // error, are ordered based on the error string.
482         int localDataIndex = StringUtils.countMatches(restErrorObject.getErrorText(), "%");
483         text.append(" (msg=%").append(localDataIndex + 1).append(") (ec=%").append(localDataIndex + 2).append(")");
484
485         if (variables == null) {
486             variables = new ArrayList<String>();
487         }
488
489         if (variables.size() < localDataIndex) {
490             ErrorLogHelper.logError("AAI_4011", "data missing for rest error");
491             while (variables.size() < localDataIndex) {
492                 variables.add("null");
493             }
494         }
495
496         // This will put the error code and error text into the right positions
497         if (are.getMessage() == null) {
498             variables.add(localDataIndex++, eo.getErrorText());
499         } else {
500             variables.add(localDataIndex++, eo.getErrorText() + ":" + are.getMessage());
501         }
502         variables.add(localDataIndex, eo.getErrorCodeString());
503
504         try {
505             if (eo.getCategory().equals("1")) {
506
507                 context = JAXBContext.newInstance(org.onap.aai.domain.restPolicyException.Fault.class);
508                 Marshaller m = context.createMarshaller();
509                 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
510                 m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
511
512                 org.onap.aai.domain.restPolicyException.ObjectFactory factory =
513                         new org.onap.aai.domain.restPolicyException.ObjectFactory();
514                 org.onap.aai.domain.restPolicyException.Fault fault = factory.createFault();
515                 org.onap.aai.domain.restPolicyException.Fault.RequestError requestError =
516                         factory.createFaultRequestError();
517                 org.onap.aai.domain.restPolicyException.Fault.RequestError.PolicyException policyException =
518                         factory.createFaultRequestErrorPolicyException();
519                 org.onap.aai.domain.restPolicyException.Fault.RequestError.PolicyException.Variables polvariables =
520                         factory.createFaultRequestErrorPolicyExceptionVariables();
521
522                 policyException.setMessageId("POL" + eo.getRESTErrorCode());
523                 policyException.setText(text.toString());
524                 for (int i = 0; i < variables.size(); i++) {
525                     polvariables.getVariable().add(variables.get(i));
526                 }
527                 policyException.setVariables(polvariables);
528                 requestError.setPolicyException(policyException);
529                 fault.setRequestError(requestError);
530
531                 StringWriter sw = new StringWriter();
532                 m.marshal(fault, sw);
533
534                 response = sw.toString();
535
536             } else {
537
538                 context = JAXBContext.newInstance(org.onap.aai.domain.restServiceException.Fault.class);
539                 Marshaller m = context.createMarshaller();
540                 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
541                 m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
542
543                 org.onap.aai.domain.restServiceException.ObjectFactory factory =
544                         new org.onap.aai.domain.restServiceException.ObjectFactory();
545                 org.onap.aai.domain.restServiceException.Fault fault = factory.createFault();
546                 org.onap.aai.domain.restServiceException.Fault.RequestError requestError =
547                         factory.createFaultRequestError();
548                 org.onap.aai.domain.restServiceException.Fault.RequestError.ServiceException serviceException =
549                         factory.createFaultRequestErrorServiceException();
550                 org.onap.aai.domain.restServiceException.Fault.RequestError.ServiceException.Variables svcvariables =
551                         factory.createFaultRequestErrorServiceExceptionVariables();
552                 serviceException.setMessageId("POL" + eo.getRESTErrorCode());
553                 serviceException.setText(text.toString());
554                 for (int i = 0; i < variables.size(); i++) {
555                     svcvariables.getVariable().add(variables.get(i));
556                 }
557                 serviceException.setVariables(svcvariables);
558                 requestError.setServiceException(serviceException);
559                 fault.setRequestError(requestError);
560
561                 StringWriter sw = new StringWriter();
562                 m.marshal(fault, sw);
563
564                 response = sw.toString();
565
566             }
567         } catch (Exception ex) {
568             LOGGER.error("We were unable to create a rest exception to return on an API because of a parsing error "
569                     + ex.getMessage());
570         }
571         return response;
572     }
573
574     public static void logException(AAIException e) {
575         final ErrorObject errorObject = e.getErrorObject();
576         /*
577          * String severityCode = errorObject.getSeverityCode(errorObject.getSeverity());
578          * 
579          * Severify should be left empty per Logging Specification 2019.11
580          * if (!StringUtils.isEmpty(severityCode)) {
581          * int sevCode = Integer.parseInt(severityCode);
582          * if (sevCode > 0 && sevCode <= 3) {
583          * LoggingContext.severity(sevCode);
584          * }
585          * }
586          */
587         String stackTrace = "";
588         try {
589             stackTrace = LogFormatTools.getStackTop(e);
590         } catch (Exception a) {
591             // ignore
592         }
593         final String errorMessage = new StringBuilder().append(errorObject.getErrorText()).append(":")
594                 .append(errorObject.getRESTErrorCode()).append(":").append(errorObject.getHTTPResponseCode())
595                 .append(":").append(e.getMessage()).toString().replaceAll("\\n", "^");
596
597         MDCSetup mdcSetup = new MDCSetup();
598         mdcSetup.setResponseStatusCode(errorObject.getHTTPResponseCode().getStatusCode());
599         mdcSetup.setErrorCode(Integer.parseInt(errorObject.getAaiElsErrorCode()));
600         String serviceName = MDC.get(ONAPLogConstants.MDCs.SERVICE_NAME);
601         if (serviceName == null || serviceName.isEmpty()) {
602             MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, Constants.DefaultValues.UNKNOWN);
603         }
604         MDC.put(ONAPLogConstants.MDCs.ERROR_DESC, errorMessage);
605         final String details =
606                 new StringBuilder().append(errorObject.getErrorCodeString()).append(" ").append(stackTrace).toString();
607
608         if (errorObject.getSeverity().equalsIgnoreCase("WARN"))
609             LOGGER.warn(details);
610         else if (errorObject.getSeverity().equalsIgnoreCase("ERROR"))
611             LOGGER.error(details);
612         else if (errorObject.getSeverity().equalsIgnoreCase("FATAL"))
613             LOGGER.error(details);
614         else if (errorObject.getSeverity().equals("INFO"))
615             LOGGER.info(details);
616     }
617
618     public static void logError(String code) {
619         logError(code, "");
620     }
621
622     public static void logError(String code, String message) {
623         logException(new AAIException(code, message));
624     }
625 }