2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.mso.bpmn.common.scripts
23 import static org.apache.commons.lang3.StringUtils.*
25 import com.google.common.xml.XmlEscapers
27 import org.apache.commons.lang3.*
28 import org.camunda.bpm.engine.delegate.BpmnError
29 import org.camunda.bpm.engine.delegate.DelegateExecution
30 import org.openecomp.mso.bpmn.core.WorkflowException
35 class ExceptionUtil extends AbstractServiceTaskProcessor {
39 * This error handling method maps an AAI Exception response to a
40 * WorkflowException Object. It then sets the WorkflowException Object
41 * on the execution as "WorkflowException".
43 * This method formats the exception from AAI into the WorkflowException's
44 * errorMessage that CCD expects.
46 * @param execution the execution
47 * @param response the aai exception
49 WorkflowException MapAAIExceptionToWorkflowException(String response, DelegateExecution execution)
51 def utils=new MsoUtils()
52 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
53 def prefix=execution.getVariable("prefix")
54 def errorMsg = execution.getVariable(prefix+"ErrorResponse")
55 utils.log("DEBUG","=========== Begin MapAAIExceptionToWorkflowException ===========",isDebugEnabled)
58 String errorCode = '5000'
59 WorkflowException wfex
60 utils.log("DEBUG","response: " + response, isDebugEnabled)
63 //String msg = utils.getNodeXml(response, "Fault")
64 variables = utils.getMultNodes(response, "variable")
65 text = utils.getNodeText1(response, "text")
66 } catch (Exception ex) {
67 //Ignore the exception - cases include non xml payload
68 utils.log("DEBUG","error mapping error, ignoring: " + ex,isDebugEnabled)
72 if(variables.size()>=4){
73 text = text.replaceFirst("%1", variables[0])
74 text = text.replaceFirst("%2", variables[1])
75 text = text.replaceFirst("%3", variables[2])
76 text = text.replaceFirst("%4", variables[3])
78 String modifiedErrorMessage = 'Received error from A&AI (' + text +')'
79 utils.log("DEBUG", "ModifiedErrorMessage " + modifiedErrorMessage, isDebugEnabled)
80 // let $ModifiedErrorMessage := concat( 'Received error from A',$exceptionaai:ampersand,'AI (' ,functx:replace-multi($ErrorMessage,$from,$Variables ),')')
81 buildWorkflowException(execution, 5000, modifiedErrorMessage)
83 wfex = execution.getVariable("WorkflowException")
84 utils.log("ERROR","Fault:"+ wfex)
88 errorCode = MapErrorCode(errorMsg)
89 String mappedErrorMessage = MapErrorMessage(errorMsg, errorCode)
91 int errorCodeInt = Integer.parseInt(errorCode)
92 buildWorkflowException(execution, errorCodeInt, mappedErrorMessage)
94 utils.log("DEBUG", "mappedErrorMessage " + mappedErrorMessage, isDebugEnabled)
95 wfex = execution.getVariable("WorkflowException")
96 utils.log("ERROR","Fault:"+ wfex, isDebugEnabled)
98 } catch(Exception ex) {
99 utils.log("DEBUG","error mapping error, return null: " + ex, isDebugEnabled)
105 utils.log("DEBUG", "Exception occured during MapAAIExceptionToWorkflowException: " + e, isDebugEnabled)
106 buildWorkflowException(execution, 5000, "Error mapping AAI Response to WorkflowException")
111 * This error handling method maps an AAI Exception response to a
112 * WorkflowException Object. It then sets the WorkflowException Object
113 * on the execution as "WorkflowException".
115 * This method takes the exact exception inside the <Fault> tags from AAI Response
116 * and puts it into the WorkflowException's errorMessage.
118 * @param execution the execution
119 * @param response the aai exception
121 WorkflowException MapAAIExceptionToWorkflowExceptionGeneric(DelegateExecution execution, String response, int resCode){
122 def utils=new MsoUtils()
123 def isDebugLogEnabled = execution.getVariable("isDebugLogEnabled")
124 utils.log("DEBUG", "Start MapAAIExceptionToWorkflowExceptionGeneric Process", isDebugLogEnabled)
126 WorkflowException wfex
128 if(utils.nodeExists(response, "Fault")){
129 String fault = utils.getNodeXml(response, "Fault")
130 fault = utils.removeXmlPreamble(fault)
131 fault = fault.replace("<Fault>", "").replace("</Fault>", "")
132 fault = fault.replaceAll("\\s+\\s+", "") // Removes extra white spaces
133 buildWorkflowException(execution, resCode, fault)
134 }else if(utils.nodeExists(response, "RESTFault")){
135 String rFault = utils.getNodeXml(response, "RESTFault")
136 buildWorkflowException(execution, resCode, rFault)
138 buildWorkflowException(execution, resCode, "Received a bad response from AAI")
140 } catch (Exception ex) {
141 utils.log("DEBUG", "Exception Occured during MapAAIExceptionToWorkflowExceptionGeneric: " + ex, isDebugLogEnabled)
142 buildWorkflowException(execution, resCode, "Internal Error - Occured in MapAAIExceptionToWorkflowExceptionGeneric")
145 utils.log("DEBUG", "Outgoing WorkflowException is: " + execution.getVariable("WorkflowException"), isDebugLogEnabled)
146 utils.log("DEBUG", "Completed MapAAIExceptionToWorkflowExceptionGeneric Process", isDebugLogEnabled)
150 * This method takes a WorkflowException Object and builds
151 * WorkflowException Xml. This method should only be used
152 * for the purpose of sending a sync error response or for
153 * creating a FalloutHandler request.
155 *@param - WorkflowException Object
157 *@return - String WorkflowException Xml
161 String buildErrorResponseXml(WorkflowException wfex) {
164 String mes = XmlEscapers.xmlContentEscaper().escape(wfex.getErrorMessage())
165 int code = wfex.getErrorCode()
167 """<aetgt:WorkflowException xmlns:aetgt="http://org.openecomp/mso/workflow/schema/v1">
168 <aetgt:ErrorMessage>${mes}</aetgt:ErrorMessage>
169 <aetgt:ErrorCode>${code}</aetgt:ErrorCode>
170 </aetgt:WorkflowException>"""
174 """<aetgt:WorkflowException xmlns:aetgt="http://org.openecomp/mso/workflow/schema/v1">
175 <aetgt:ErrorMessage>Internal Error</aetgt:ErrorMessage>
176 <aetgt:ErrorCode>2500</aetgt:ErrorCode>
177 </aetgt:WorkflowException>"""
183 5000 Received error from A&AI ($A&AI_ERROR) Asynchronous During orchestration of the recipe, A&AI returned an error. The error returned by A&AI is passed through in $A&AI_ERROR.
184 5010 Could not communicate with A&AI Asynchronous During orchestration of the recipe, a connection with A&AI could not be established.
185 5020 No response from A&AI Asynchronous During orchestration of the recipe, communication was established with A&AI, but no response was received within the configured timeout.
189 * Utility Method for MapAAIExceptionToWorkflowException
191 *@param - String ErrorMessage
193 *@return - String ErrorCode
196 private String MapErrorCode(String errorMessage)
198 if(errorMessage==null){
201 errorMessage = errorMessage.toLowerCase();
202 if(errorMessage.contains('timed out') || errorMessage.contains('timeout'))
204 else if (errorMessage.contains('connection'))
212 * Utility Method for MapAAIExceptionToWorkflowException
214 *@param - String ErrorMessage
215 *@param - String ErrorCode
217 *@return - String ErrorMessage
220 private String MapErrorMessage(String errorMessage, String errorCode)
222 if(errorMessage == null){
225 if( errorCode.equals('5010')){
226 return 'Could not communicate with A&AI'
227 }else if (errorCode.equals('5020')){
228 return 'No response from A&AI'
230 return 'Received error from A&AI (' +errorMessage +')'
236 * Utility Method for Mapping SDNC
237 * Adapter Response Codes
239 *@param - String sdncResponseCode
241 *@return - String code
244 String MapSDNCResponseCodeToErrorCode(String sdncResponseCode)
246 if (sdncResponseCode == '500') {
248 } else if ( sdncResponseCode == '408') {
250 } else if ( sdncResponseCode == '60010') {
258 * This error handling method builds a WorkflowException Object. It sets it on
259 * the execution as "WorkflowException".
261 * @param execution the execution
262 * @param errorCode the error code
263 * @param errorMessage the error message
265 public void buildWorkflowException(DelegateExecution execution, int errorCode, String errorMessage) {
266 MsoUtils utils = new MsoUtils()
267 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
268 String processKey = getProcessKey(execution);
269 utils.log("DEBUG", "Building a WorkflowException for " + processKey, isDebugLogEnabled)
271 WorkflowException exception = new WorkflowException(processKey, errorCode, errorMessage);
272 execution.setVariable("WorkflowException", exception);
273 utils.log("DEBUG", "Outgoing WorkflowException is " + exception, isDebugLogEnabled)
277 * This error handling method builds a WorkflowException Object and throws a
278 * MSOWorkflowException. It throws a "MSOWorkflowException" BpmnError after
279 * setting the WorkflowException Object on the execution as "WorkflowException".
281 * @param execution the execution
282 * @param errorCode the error code
283 * @param errorMessage the error message
285 public void buildAndThrowWorkflowException(DelegateExecution execution, int errorCode, String errorMessage) {
286 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
287 String processKey = getProcessKey(execution);
288 utils.log("Building a WorkflowException for Subflow " + processKey, isDebugLogEnabled)
290 WorkflowException exception = new WorkflowException(processKey, errorCode, errorMessage);
291 execution.setVariable("WorkflowException", exception);
292 utils.log("DEBUG", "Outgoing WorkflowException is " + exception, isDebugLogEnabled)
293 utils.log("DEBUG", "Throwing MSOWorkflowException", isDebugLogEnabled)
294 throw new BpmnError("MSOWorkflowException")
298 * This method is executed after an MSOWorkflowException is caught by a
299 * subflow (during subflows "Error Handling Sub Process").
300 * It ensures the WorkflowException variable is populated before ending the
301 * subflow and also logs the subflows outgoing WorkflowException Variable.
306 public void processSubflowsBPMNException(DelegateExecution execution){
307 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
308 String processKey = getProcessKey(execution)
310 utils.log("DEBUG", "Started ProcessSubflowsBPMNException Method", isDebugEnabled)
311 if(execution.getVariable("WorkflowException") == null){
312 buildWorkflowException(execution, 2500, "Internal Error - Occured During " + processKey)
315 utils.log("DEBUG", processKey + " Outgoing WorkflowException is: " + execution.getVariable("WorkflowException"), isDebugEnabled)
317 utils.log("DEBUG", "Caught Exception during ProcessSubflowsBPMNException Method: " + e, isDebugEnabled)
319 utils.log("DEBUG", "Completed ProcessSubflowsBPMNException Method", isDebugEnabled)
323 * This method is executed after an MSOWorkflowException is caught by a
324 * Mainflow. It builds and returns a FalloutHandler Request. It also
325 * verifies the WorkflowException variable is populated.
328 * @param - requestInfo
330 * @return - falloutHandlerRequest
333 public String processMainflowsBPMNException(DelegateExecution execution, String requestInfo){
334 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
335 String processKey = getProcessKey(execution)
337 utils.log("DEBUG", "Started ProcessMainflowBPMNException Method", isDebugEnabled)
338 if(execution.getVariable("WorkflowException") == null || isBlank(requestInfo)){
339 buildWorkflowException(execution, 2500, "Internal Error - WorkflowException Object and/or RequestInfo is null! " + processKey)
341 requestInfo = utils.removeXmlPreamble(requestInfo)
342 WorkflowException wfex = execution.getVariable("WorkflowException")
343 String errorMessage = XmlEscapers.xmlContentEscaper().escape(wfex.getErrorMessage())
344 int errorCode = wfex.getErrorCode()
346 String falloutHandlerRequest =
347 """<aetgt:FalloutHandlerRequest xmlns:aetgt="http://org.openecomp/mso/workflow/schema/v1"
348 xmlns:ns="http://org.openecomp/mso/request/types/v1"
349 xmlns:wfsch="http://org.openecomp/mso/workflow/schema/v1">
351 <aetgt:WorkflowException xmlns:aetgt="http://org.openecomp/mso/workflow/schema/v1">
352 <aetgt:ErrorMessage>${errorMessage}</aetgt:ErrorMessage>
353 <aetgt:ErrorCode>${errorCode}</aetgt:ErrorCode>
354 </aetgt:WorkflowException>
355 </aetgt:FalloutHandlerRequest>"""
357 utils.log("DEBUG", processKey + " Outgoing WorkflowException is: " + execution.getVariable("WorkflowException"), isDebugEnabled)
358 utils.log("DEBUG", processKey + " Outgoing FalloutHandler Request is: " + falloutHandlerRequest, isDebugEnabled)
359 return falloutHandlerRequest
362 utils.log("DEBUG", "Caught Exception during ProcessMainflowBPMNException Method: " + e, isDebugEnabled)
365 utils.log("DEBUG", "Completed ProcessMainflowBPMNException Method", isDebugEnabled)
370 * This method is executed after an Java Exception is caught
371 * It sets the WorkflowException variable. The method can be used in either mainflow or subflows.
376 public void processJavaException(DelegateExecution execution){
377 def isDebugEnabled=execution.getVariable("isDebugLogEnabled")
378 String processKey = getProcessKey(execution)
380 utils.log("DEBUG", "Caught a Java Exception in " + processKey, isDebugEnabled)
381 utils.log("DEBUG", "Started processJavaException Method", isDebugEnabled)
382 buildWorkflowException(execution, 2500, "Catch a Java Lang Exception in " + processKey)
387 utils.log("DEBUG", "Caught Exception during processJavaException Method: " + e, isDebugEnabled)
388 buildWorkflowException(execution, 2500, "Internal Error - During Process Java Exception")
390 utils.log("DEBUG", "Completed processJavaException Method", isDebugEnabled)
394 public void preProcessRequest(DelegateExecution execution) {
395 // TODO Auto-generated method stub