Cleaned up content of MsoLogger
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / TrinityExceptionUtil.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.common.scripts
24
25 import org.camunda.bpm.engine.delegate.DelegateExecution
26 import org.apache.commons.lang3.*
27 import org.onap.so.logger.MessageEnum
28 import org.onap.so.logger.MsoLogger
29 import org.slf4j.Logger
30 import org.slf4j.LoggerFactory
31
32
33
34 class TrinityExceptionUtil {
35     private static final Logger logger = LoggerFactory.getLogger( TrinityExceptionUtil.class);
36
37
38
39
40         public static enum Error {
41                 SVC_GENERAL_SERVICE_ERROR("SVC0001","Internal Error"),
42                 SVC_BAD_PARAMETER("SVC0002", "Invalid input value for message part %1"),
43                 SVC_NO_SERVER_RESOURCES("SVC1000", "No server resources available to process the request"),
44                 SVC_DETAILED_SERVICE_ERROR("SVC2000", "The following service error occurred: %1. Error code is %2."),
45                 POL_GENERAL_POLICY_ERROR("POL0001", "A policy error occurred."),
46                 POL_USER_NOT_PROVISIONED("POL1009", "User has not been provisioned for service"),
47                 POL_USER_SUSPENDED("POL1010", "User has been suspended from service"),
48                 POL_DETAILED_POLICY_ERROR("POL2000", "The following policy error occurred: %1. Error code is %2."),
49                 POL_MSG_SIZE_EXCEEDS_LIMIT("POL9003", "Message content size exceeds the allowable limit")
50         
51
52                 private final String msgId
53                 private final String msgTxt
54
55                 private Error(String msgId, String msgTxt) {
56                         this.msgId = msgId
57                         this.msgTxt = msgTxt
58                 }
59
60                 public String getMsgId() {
61                      return msgId
62                   }
63
64                 public String getMsgTxt() {
65                         return msgTxt
66                 }
67
68         }
69
70
71
72
73         String mapAdapterExecptionToCommonException(String response, DelegateExecution execution)
74         {
75                 def utils=new MsoUtils()
76                 def method = getClass().getSimpleName() + '.mapAdapterExecptionToCommonException(' +
77                         'execution=' + execution.getId() +
78                         ')'
79
80                 logger.trace('Entered ' + method)
81
82
83                 def errorCode
84
85
86                 try {
87                           errorCode = MapCategoryToErrorCode(utils.getNodeText(response, "category"))
88                           execution.setVariable(prefix+"err",errorCode)
89                           String message = buildException(response, execution)
90                           logger.trace("End MapAdapterExecptionToWorkflowException ")
91                           return message
92                 }catch (Exception ex) {
93                         //Ignore the exception - cases include non xml payload
94                         logger.debug("error mapping error, ignoring: " + ex)
95                         logger.trace("End MapAdapterExecptionToWorkflowException ")
96                         return buildException(response, execution)
97                 }
98         }
99
100         /**
101          * @param response
102          * @param execution
103          * @return mapped exception
104          */
105         String mapAOTSExecptionToCommonException(String response, DelegateExecution execution)
106         {
107                 def utils=new MsoUtils()
108
109                 def prefix=execution.getVariable("prefix")
110                 def method = getClass().getSimpleName() + '.mapAOTSExecptionToCommonException(' +
111                         'execution=' + execution.getId() +
112                         ')'
113
114                 logger.trace('Entered ' + method)
115
116
117                 try {
118                           def errorCode = utils.getNodeText(response,"code")
119                           def descr = utils.getNodeText(response, "description")
120                           def mappedErr = mapErrorCodetoError(errorCode, descr)
121                           if(mappedErr == Error.SVC_DETAILED_SERVICE_ERROR || mappedError == Error.POL_DETAILED_POLICY_ERROR){
122                                   ArrayList myVars = new ArrayList()
123                                   myVars.add(descr)
124                                   myVars.add(errorCode)
125                                   execution.setVariable(prefix+"errVariables", myVars)
126                           }
127                           execution.setVariable(prefix+"err",mappedErr)
128                           def message = buildException("Received error from AOTS: " + descr, execution)
129                           logger.trace("End MapAOTSExecptionToCommonException ")
130                           return message
131                 }catch (Exception ex) {
132                         //Ignore the exception - cases include non xml payload
133                         logger.debug("error mapping error, ignoring: " + ex)
134                         logger.trace("End MapAOTSExecptionToCommonException ")
135                         return buildException(response, execution)
136                 }
137         }
138
139         String mapSDNCAdapterExceptionToErrorResponse(String sdncAdapterCallbackRequest, DelegateExecution execution) {
140                 def utils=new MsoUtils()
141                 def prefix=execution.getVariable("prefix")
142                 def method = getClass().getSimpleName() + '.mapSDNCAdapterExceptionToErrorResponse(' +
143                         'execution=' + execution.getId() +
144                         ')'
145
146                 logger.trace('Entered ' + method)
147
148                 def sdncResponseCode
149                 String responseCode = execution.getVariable(prefix+"ResponseCode")
150                 logger.debug('responseCode to map: ' + responseCode)
151                 def errorMessage
152
153                 try {
154
155                         if(utils.nodeExists(sdncAdapterCallbackRequest, "RequestData")) {
156                                 def reqDataXml = utils.getNodeXml(sdncAdapterCallbackRequest, "RequestData")
157                                 errorMessage = utils.getNodeText(reqDataXml, "response-message")
158                                 sdncResponseCode = utils.getNodeText(reqDataXml, "response-code")
159                         }else{
160                                 errorMessage = utils.getNodeText(sdncAdapterCallbackRequest, "ResponseMessage")
161                                 sdncResponseCode = responseCode
162                     }
163                         def mappedErr = mapErrorCodetoError(responseCode, errorMessage)
164                         errorMessage = errorMessage
165                         def modifiedErrorMessage = "Received error from SDN-C: " + errorMessage
166                         if(mappedErr == Error.SVC_DETAILED_SERVICE_ERROR || mappedErr == Error.POL_DETAILED_POLICY_ERROR){
167                                 ArrayList myVars = new ArrayList()
168                                 myVars.add(errorMessage)
169                                 myVars.add(sdncResponseCode)
170                                 execution.setVariable(prefix+"errVariables", myVars)
171                         }
172                         execution.setVariable(prefix+"err",mappedErr)
173                         def message = buildException(modifiedErrorMessage, execution)
174
175
176                         logger.trace("End MapSDNCAdapterException ")
177                     return message
178                 }catch (Exception ex) {
179                         //Ignore the exception - cases include non xml payload
180                         logger.debug("error mapping sdnc error, ignoring: " + ex)
181                         logger.trace("End MapSDNCAdapterException ")
182                         return null
183                 }
184
185         }
186
187         /**
188          * @param response message from called component (ex: AAI)
189          * @param execution
190          * @return an error response conforming to the common 
191          */
192         String mapAAIExceptionTCommonException(String response, DelegateExecution execution)
193         {
194                 def utils=new MsoUtils()
195                 def prefix=execution.getVariable("prefix")
196                 def method = getClass().getSimpleName() + '.mapAAIExceptionTCommonException(' +
197                         'execution=' + execution.getId() +
198                         ')'
199
200                 logger.trace('Entered ' + method)
201                 def variables
202                 def message
203                 String errorCode = 'SVC0001'
204                 logger.debug("response: " + response)
205                 //they use the same format we do, pass their error along
206                 //TODO add Received error from A&AI at beg of text
207                 try {
208                          message = utils.getNodeXml(response, "requestError")
209                          message = utils.removeXmlNamespaces(message)
210                 } catch (Exception ex) {
211                         //Ignore the exception - cases include non xml payload
212                                 message = buildException("Received error from A&AI, unable to parse",execution)
213                         logger.debug("error mapping error, ignoring: " + ex)
214                 }
215
216                 if(message != null) {
217                          execution.setVariable(prefix+"ErrorResponse",message)
218                          logger.error("{} {} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), "Fault", "BPMN",
219                                          MsoLogger.ErrorCode.UnknownError.getValue(),
220                                          execution.getVariable(prefix+"ErrorResponse"));
221                          return message
222                 } else {
223                                 return null
224                 }
225         }
226
227         /**
228          * @param execution
229          * @return an error response conforming to the common API with default text msg
230          */
231         String buildException(execution){
232                 return buildException(null, execution)
233         }
234         
235         /**
236          * @param response message from called component (ex: AAI)
237          * @param execution
238          * @return an error response conforming to the common
239          */
240         String buildException(response, execution){
241                 def utils=new MsoUtils()
242                 def method = getClass().getSimpleName() + '.buildException(' +
243                         'execution=' + execution.getId() +
244                         ')'
245
246                 logger.trace('Entered ' + method)
247                 def prefix=execution.getVariable("prefix")
248                 def responseCode = String.valueOf(execution.getVariable(prefix+"ResponseCode"))
249                 def variables
250                 logger.debug("response: " + response)
251
252                         try {
253                                 logger.debug("formatting error message" )
254                                 def msgVars = execution.getVariable(prefix+"errVariables")
255                                 def myErr = execution.getVariable(prefix+"err")
256                                 def messageTxt = execution.getVariable(prefix+"errTxt")
257                                 def messageId = null
258
259                                 if(myErr == null){
260                                         logger.debug("mapping response code: " + responseCode)
261                                         myErr = mapErrorCodetoError(responseCode, response)
262                                         if(myErr == null){
263                                                 //not a service or policy error, just return error code
264                                                 return ""
265                                         }
266                                 }
267                                 messageId = myErr.getMsgId()
268
269                                 if(messageTxt == null){
270                                         if(myErr!=null){
271                                                 messageTxt = myErr.getMsgTxt()
272                                         }else{
273                                                 messageTxt = response
274                                         }
275                                 }
276                                 
277                                 if(msgVars==null && (myErr == Error.SVC_DETAILED_SERVICE_ERROR || myErr == Error.POL_DETAILED_POLICY_ERROR)){
278                                         msgVars = new ArrayList()
279                                         msgVars.add(response)
280                                         msgVars.add(responseCode)
281                                 }
282                                 
283                                 def msgVarsXML=""
284                                 StringBuffer msgVarsBuff = new StringBuffer()
285                                 if(msgVars!=null){
286                                         for(String msgVar : msgVars){
287                                                 msgVarsBuff.append(
288                                                         """
289                         <tns:variables>${MsoUtils.xmlEscape(msgVar)}</tns:variables>""")
290                                         }
291                                         
292                                 }
293                                 def message = ""
294                                 if(messageId.startsWith("SVC")){
295                                         message = """<tns:requestError xmlns:tns="http://org.onap/so/request/types/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://org.onap/so/request/types/v1 MsoServiceInstanceTypesV1.xsd">
296         <tns:serviceException>
297                 <tns:messageId>${MsoUtils.xmlEscape(messageId)}</tns:messageId>
298                 <tns:text>${MsoUtils.xmlEscape(messageTxt)}</tns:text>${msgVarsBuff}
299         </tns:serviceException>
300 </tns:requestError>"""
301                                 }else{
302                                         message ="""<tns:requestError xmlns:tns="http://org.onap/so/request/types/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://org.onap/so/request/types/v1 MsoServiceInstanceTypesV1.xsd">
303         <tns:policyException>
304                 <tns:messageId>${MsoUtils.xmlEscape(messageId)}</tns:messageId>
305                 <tns:text>${MsoUtils.xmlEscape(messageTxt)}</tns:text>${msgVarsBuff}
306         </tns:policyException>
307 </tns:requestError>"""
308                                 }
309                                  logger.debug("message " + message)
310                                  execution.setVariable(prefix+"ErrorResponse",message)
311                                  execution.setVariable(prefix+"err", myErr)
312                                  execution.setVariable(prefix+"errTxt", messageTxt)
313                                  execution.setVariable(prefix+"errVariables", msgVars)
314                                  logger.error("{} {} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), "Fault", "BPMN",
315                                                  MsoLogger.ErrorCode.UnknownError.getValue(),
316                                                  execution.getVariable(prefix+"ErrorResponse"));
317                                  return message
318                         }catch(Exception ex) {
319                                 logger.debug("error mapping error, return null: " + ex)
320                                 return null
321                         }
322
323         }
324
325         String parseError(DelegateExecution execution){
326                 def utils=new MsoUtils()
327                 def prefix=execution.getVariable("prefix")
328                 def text = execution.getVariable(prefix+"errTxt")
329                 def msgVars = execution.getVariable(prefix+"errVariables")
330                 logger.debug('parsing message: ' + text)
331                 if(text == null){
332                         return 'failed'
333                 }
334                 if(msgVars!=null && !msgVars.isEmpty()){
335                         for(int i=0; i<msgVars.size(); i++){
336                                 text = text.replaceFirst("%"+(i+1), msgVars[i])
337                         }
338                 }
339                 logger.debug('parsed message is: ' + text)
340                 return text
341         }
342
343
344
345         Error mapErrorCodetoError(responseCode, descr)
346         {
347
348                 if(responseCode==null || responseCode=='0' || responseCode=='500' || responseCode =='408'){
349                         return Error.SVC_NO_SERVER_RESOURCES
350                 }else if(responseCode == '401' || responseCode == '405' || responseCode == '409' || responseCode == '503'){
351                         return null
352                 }else if(responseCode == '400'){
353                         if(descr==null){
354                                 return Error.SVC_GENERAL_SERVICE_ERROR
355                         }else{
356                                 return Error.SVC_DETAILED_SERVICE_ERROR
357                         }
358                 }else if(responseCode == '401'){
359                         if(descr==null){
360                                 return Error.POL_GENERAL_POLICY_ERROR
361                         }else{
362                                 return Error.POL_DETAILED_POLICY_ERROR
363                         }
364                 }else{
365                         return Error.SVC_NO_SERVER_RESOURCES
366                 }
367         }
368         
369         String mapCategoryToErrorCode(String errorCategory)
370         {
371                 if(errorCategory.equals('OPENSTACK'))
372                         return Error.SVC_NO_SERVER_RESOURCES
373                 else if (errorCategory.equals('IO'))
374                         return Error.SVC_NO_SERVER_RESOURCES
375                 else if (errorCategory.equals('INTERNAL'))
376                         return Error.SVC_NO_SERVER_RESOURCES
377                 else if (errorCategory.equals('USERDATA'))
378                         return Error.SVC_GENERAL_SERVICE_ERROR
379                 else
380                         return Error.SVC_GENERAL_SERVICE_ERROR
381         }
382 }