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