Merge "updated camunda springboot version"
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / workflow / tasks / WorkflowActionBBTasks.java
index d3f817c..2e91a52 100644 (file)
 
 package org.onap.so.bpmn.infrastructure.workflow.tasks;
 
+import java.sql.Timestamp;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
+import java.util.Optional;
 
 import org.camunda.bpm.engine.delegate.BpmnError;
 import org.camunda.bpm.engine.delegate.DelegateExecution;
@@ -38,6 +41,7 @@ import org.onap.so.serviceinstancebeans.ServiceInstancesResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Component;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -50,12 +54,18 @@ public class WorkflowActionBBTasks {
        private static final String G_REQUEST_ID = "mso-request-id";
        private static final String G_ALACARTE = "aLaCarte";
        private static final String G_ACTION = "requestAction";
+       private static final String RETRY_COUNT = "retryCount";
+       protected String maxRetries = "mso.rainyDay.maxRetries";
        private static final Logger logger = LoggerFactory.getLogger(WorkflowActionBBTasks.class);
 
        @Autowired
        private RequestsDbClient requestDbclient;
        @Autowired
        private WorkflowAction workflowAction;
+       @Autowired
+       private WorkflowActionBBFailure workflowActionBBFailure;
+       @Autowired
+       private Environment environment;
        
        public void selectBB(DelegateExecution execution) {
                List<ExecuteBuildingBlock> flowsToExecute = (List<ExecuteBuildingBlock>) execution
@@ -79,8 +89,8 @@ public class WorkflowActionBBTasks {
                        execution.setVariable("completed", true);
                } else {
                        execution.setVariable("completed", false);
-                       execution.setVariable(G_CURRENT_SEQUENCE, currentSequence);
                }
+               execution.setVariable(G_CURRENT_SEQUENCE, currentSequence);
        }
        
        public void updateFlowStatistics(DelegateExecution execution) {
@@ -108,7 +118,7 @@ public class WorkflowActionBBTasks {
                String statusMessage = this.getStatusMessage(completedBB.getBuildingBlock().getBpmnFlowName(), 
                                nextBB.getBuildingBlock().getBpmnFlowName(), completedBBs, remainingBBs);
                Long percentProgress = this.getPercentProgress(completedBBs, totalBBs);
-               request.setStatusMessage(statusMessage);
+               request.setFlowStatus(statusMessage);
                request.setProgress(percentProgress);
                request.setLastModifiedBy("CamundaBPMN");
                return request;
@@ -177,57 +187,64 @@ public class WorkflowActionBBTasks {
                }
        }
 
-       public void setupCompleteMsoProcess(DelegateExecution execution) {
-               final String requestId = (String) execution.getVariable(G_REQUEST_ID);
-               final String action = (String) execution.getVariable(G_ACTION);
-               final String resourceId = (String) execution.getVariable("resourceId");
-               final boolean aLaCarte = (boolean) execution.getVariable(G_ALACARTE);
-               final String resourceName = (String) execution.getVariable("resourceName");
-               final String source = (String) execution.getVariable("source");
-               String macroAction = "";
-               if (aLaCarte) {
-                       macroAction = "ALaCarte-" + resourceName + "-" + action;
-               } else {
-                       macroAction = "Macro-" + resourceName + "-" + action;
-               }
-               String msoCompletionRequest = "<aetgt:MsoCompletionRequest xmlns:aetgt=\"http://org.onap/so/workflow/schema/v1\" xmlns:ns=\"http://org.onap/so/request/types/v1\"><request-info xmlns=\"http://org.onap/so/infra/vnf-request/v1\"><request-id>"
-                               + requestId + "</request-id><action>" + action + "</action><source>" + source
-                               + "</source></request-info><status-message>" + macroAction
-                               + " request was executed correctly.</status-message><serviceInstanceId>" + resourceId
-                               + "</serviceInstanceId><mso-bpel-name>WorkflowActionBB</mso-bpel-name></aetgt:MsoCompletionRequest>";
-               execution.setVariable("CompleteMsoProcessRequest", msoCompletionRequest);
-               execution.setVariable("mso-request-id", requestId);
-               execution.setVariable("mso-service-instance-id", resourceId);
-       }
-
-       public void setupFalloutHandler(DelegateExecution execution) {
-               final String requestId = (String) execution.getVariable(G_REQUEST_ID);
-               final String action = (String) execution.getVariable(G_ACTION);
-               final String resourceId = (String) execution.getVariable("resourceId");
-               String exceptionMsg = "";
-               if (execution.getVariable("WorkflowActionErrorMessage") != null) {
-                       exceptionMsg = (String) execution.getVariable("WorkflowActionErrorMessage");
-               } else {
-                       exceptionMsg = "Error in WorkflowAction";
+       public void updateRequestStatusToComplete(DelegateExecution execution) {
+               try{
+                       final String requestId = (String) execution.getVariable(G_REQUEST_ID);
+                       InfraActiveRequests request = requestDbclient.getInfraActiveRequestbyRequestId(requestId);
+                       final String action = (String) execution.getVariable(G_ACTION);
+                       final boolean aLaCarte = (boolean) execution.getVariable(G_ALACARTE);
+                       final String resourceName = (String) execution.getVariable("resourceName");
+                       String macroAction = "";
+                       if (aLaCarte) {
+                               macroAction = "ALaCarte-" + resourceName + "-" + action + " request was executed correctly.";
+                       } else {
+                               macroAction = "Macro-" + resourceName + "-" + action + " request was executed correctly.";
+                       }
+                       execution.setVariable("finalStatusMessage", macroAction);
+                       Timestamp endTime = new Timestamp(System.currentTimeMillis());
+                       request.setEndTime(endTime);
+                       request.setFlowStatus("Successfully completed all Building Blocks");
+                       request.setStatusMessage(macroAction);
+                       request.setProgress(Long.valueOf(100));
+                       request.setRequestStatus("COMPLETE");
+                       request.setLastModifiedBy("CamundaBPMN");
+                       requestDbclient.updateInfraActiveRequests(request);
+               }catch (Exception ex) {
+                       workflowAction.buildAndThrowException(execution, "Error Updating Request Database", ex);
                }
-               execution.setVariable("mso-service-instance-id", resourceId);
-               execution.setVariable("mso-request-id", requestId);
-               String falloutRequest = "<aetgt:FalloutHandlerRequest xmlns:aetgt=\"http://org.onap/so/workflow/schema/v1\"xmlns:ns=\"http://org.onap/so/request/types/v1\"xmlns:wfsch=\"http://org.onap/so/workflow/schema/v1\"><request-info xmlns=\"http://org.onap/so/infra/vnf-request/v1\"><request-id>"
-                               + requestId + "</request-id><action>" + action
-                               + "</action><source>VID</source></request-info><aetgt:WorkflowException xmlns:aetgt=\"http://org.onap/so/workflow/schema/v1\"><aetgt:ErrorMessage>"
-                               + exceptionMsg
-                               + "</aetgt:ErrorMessage><aetgt:ErrorCode>7000</aetgt:ErrorCode></aetgt:WorkflowException></aetgt:FalloutHandlerRequest>";
-               execution.setVariable("falloutRequest", falloutRequest);
        }
 
        public void checkRetryStatus(DelegateExecution execution) {
-               if (execution.getVariable("handlingCode").equals("Retry")) {
-                       int currSequence = (int) execution.getVariable("gCurrentSequence");
-                       currSequence--;
-                       execution.setVariable("gCurrentSequence", currSequence);
-                       int currRetryCount = (int) execution.getVariable("retryCount");
-                       currRetryCount++;
-                       execution.setVariable("retryCount", currRetryCount);
+               String handlingCode = (String) execution.getVariable("handlingCode");
+               String requestId = (String) execution.getVariable(G_REQUEST_ID);
+               String retryDuration = (String) execution.getVariable("RetryDuration");
+               int retryCount = (int) execution.getVariable(RETRY_COUNT);
+               int envMaxRetries;
+               try{
+                       envMaxRetries = Integer.parseInt(this.environment.getProperty(maxRetries));     
+               } catch (Exception ex) {
+                       logger.error("Could not read maxRetries from config file. Setting max to 5 retries");
+                       envMaxRetries = 5;
+               }
+               int nextCount = retryCount +1;
+               if (handlingCode.equals("Retry")){
+                       workflowActionBBFailure.updateRequestErrorStatusMessage(execution);
+                       try{
+                               InfraActiveRequests request = requestDbclient.getInfraActiveRequestbyRequestId(requestId);
+                               request.setRetryStatusMessage("Retry " + nextCount + "/" + envMaxRetries + " will be started in " + retryDuration);
+                               requestDbclient.updateInfraActiveRequests(request); 
+                       } catch(Exception ex){
+                               logger.warn("Failed to update Request Db Infra Active Requests with Retry Status",ex);
+                       }
+                       if(retryCount<envMaxRetries){
+                               int currSequence = (int) execution.getVariable("gCurrentSequence");
+                               execution.setVariable("gCurrentSequence", currSequence-1);
+                               execution.setVariable(RETRY_COUNT, nextCount);
+                       }else{
+                               workflowAction.buildAndThrowException(execution, "Exceeded maximum retries. Ending flow with status Abort");
+                       }
+               }else{
+                       execution.setVariable(RETRY_COUNT, 0);
                }
        }
 
@@ -236,37 +253,71 @@ public class WorkflowActionBBTasks {
         * layer will rollback the flow its currently working on.
         */
        public void rollbackExecutionPath(DelegateExecution execution) {
-               List<ExecuteBuildingBlock> flowsToExecute = (List<ExecuteBuildingBlock>) execution
-                               .getVariable("flowsToExecute");
-               List<ExecuteBuildingBlock> rollbackFlows = new ArrayList();
-               int currentSequence = (int) execution.getVariable(G_CURRENT_SEQUENCE) + 1;
-               int listSize = flowsToExecute.size();
-               for (int i = listSize - 1; i >= 0; i--) {
-                       if (i >= currentSequence) {
-                               flowsToExecute.remove(i);
-                       } else {
-                               ExecuteBuildingBlock ebb = flowsToExecute.get(i);
-                               BuildingBlock bb = flowsToExecute.get(i).getBuildingBlock();
-                               String flowName = flowsToExecute.get(i).getBuildingBlock().getBpmnFlowName();
-                               if (flowName.contains("Assign")) {
-                                       flowName = "Unassign" + flowName.substring(6, flowName.length());
-                               } else if (flowName.contains("Create")) {
-                                       flowName = "Delete" + flowName.substring(6, flowName.length());
-                               } else if (flowName.contains("Activate")) {
-                                       flowName = "Deactivate" + flowName.substring(8, flowName.length());
-                               }else{
-                                       continue;
+               if(!(boolean)execution.getVariable("isRollback")){
+                       List<ExecuteBuildingBlock> flowsToExecute = (List<ExecuteBuildingBlock>) execution
+                                       .getVariable("flowsToExecute");
+                       List<ExecuteBuildingBlock> rollbackFlows = new ArrayList();
+                       int currentSequence = (int) execution.getVariable(G_CURRENT_SEQUENCE);
+                       int listSize = flowsToExecute.size();
+                       for (int i = listSize - 1; i >= 0; i--) {
+                               if (i > currentSequence - 1) {
+                                       flowsToExecute.remove(i);
+                               } else {
+                                       String flowName = flowsToExecute.get(i).getBuildingBlock().getBpmnFlowName();
+                                       if (flowName.contains("Assign")) {
+                                               flowName = "Unassign" + flowName.substring(6, flowName.length());
+                                       } else if (flowName.contains("Create")) {
+                                               flowName = "Delete" + flowName.substring(6, flowName.length());
+                                       } else if (flowName.contains("Activate")) {
+                                               flowName = "Deactivate" + flowName.substring(8, flowName.length());
+                                       }else{
+                                               continue;
+                                       }
+                                       flowsToExecute.get(i).getBuildingBlock().setBpmnFlowName(flowName);
+                                       rollbackFlows.add(flowsToExecute.get(i));
+                               }
+                       }
+                       
+                       int flowSize = rollbackFlows.size();
+                       String handlingCode = (String) execution.getVariable("handlingCode");
+                       if(handlingCode.equals("RollbackToAssigned")){
+                               for(int i = 0; i<flowSize; i++){
+                                       if(rollbackFlows.get(i).getBuildingBlock().getBpmnFlowName().contains("Unassign")){
+                                               rollbackFlows.remove(i);
+                                       }
                                }
-                               flowsToExecute.get(i).getBuildingBlock().setBpmnFlowName(flowName);
-                               rollbackFlows.add(flowsToExecute.get(i));
                        }
+                       
+                       workflowActionBBFailure.updateRequestErrorStatusMessage(execution);
+                       
+                       if (rollbackFlows.isEmpty())
+                               execution.setVariable("isRollbackNeeded", false);
+                       else
+                               execution.setVariable("isRollbackNeeded", true);
+                       execution.setVariable("flowsToExecute", rollbackFlows);
+                       execution.setVariable("handlingCode", "PreformingRollback");
+                       execution.setVariable("isRollback", true);
+                       execution.setVariable("gCurrentSequence", 0);
+                       execution.setVariable(RETRY_COUNT, 0);
+               }else{
+                       workflowAction.buildAndThrowException(execution, "Rollback has already been called. Cannot rollback a request that is currently in the rollback state.");
+               }
+       }
+
+       protected void updateRequestErrorStatusMessage(DelegateExecution execution) {
+               try {
+                       String requestId = (String) execution.getVariable(G_REQUEST_ID);
+                       InfraActiveRequests request = requestDbclient.getInfraActiveRequestbyRequestId(requestId);
+                       String errorMsg = retrieveErrorMessage(execution);
+                       if(errorMsg == null || errorMsg.equals("")){
+                               errorMsg = "Failed to determine error message";
+                       }
+                       request.setStatusMessage(errorMsg);
+                       logger.debug("Updating RequestDB to failed: errorMsg = " + errorMsg);
+                       requestDbclient.updateInfraActiveRequests(request);
+               } catch (Exception e) {
+                       logger.error("Failed to update Request db with the status message after retry or rollback has been initialized.",e);
                }
-               if (rollbackFlows.isEmpty())
-                       execution.setVariable("isRollbackNeeded", false);
-               else
-                       execution.setVariable("isRollbackNeeded", true);
-               execution.setVariable("flowsToExecute", rollbackFlows);
-               execution.setVariable("handlingCode", "PreformingRollback");
        }
 
        public void abortCallErrorHandling(DelegateExecution execution) {
@@ -274,28 +325,45 @@ public class WorkflowActionBBTasks {
                logger.error(msg);
                throw new BpmnError(msg);
        }
-
+       
        public void updateRequestStatusToFailed(DelegateExecution execution) {
                try {
                        String requestId = (String) execution.getVariable(G_REQUEST_ID);
                        InfraActiveRequests request = requestDbclient.getInfraActiveRequestbyRequestId(requestId);
                        String errorMsg = null;
-                       try {
-                               WorkflowException exception = (WorkflowException) execution.getVariable("WorkflowException");
-                               request.setStatusMessage(exception.getErrorMessage());
-                       } catch (Exception ex) {
-                               //log error and attempt to extact WorkflowExceptionMessage
-                               logger.error("Failed to extract workflow exception from execution.",ex);
-                       }
-                       if (errorMsg == null){
-                               try {
-                                       errorMsg = (String) execution.getVariable("WorkflowExceptionErrorMessage");
+                       String rollbackErrorMsg = null;
+                       boolean rollbackCompleted = (boolean) execution.getVariable("isRollbackComplete");
+                       boolean isRollbackFailure = (boolean) execution.getVariable("isRollback");
+                       ExecuteBuildingBlock ebb = (ExecuteBuildingBlock) execution.getVariable("buildingBlock");
+                       
+                       if(rollbackCompleted){
+                               rollbackErrorMsg = "Rollback has been completed successfully.";
+                               request.setRollbackStatusMessage(rollbackErrorMsg);
+                               logger.debug("Updating RequestDB to failed: Rollback has been completed successfully");
+                       }else{
+                               if(isRollbackFailure){
+                                       rollbackErrorMsg = retrieveErrorMessage(execution);
+                                       if(rollbackErrorMsg == null || rollbackErrorMsg.equals("")){
+                                               rollbackErrorMsg = "Failed to determine rollback error message.";
+                                       }
+                                       request.setRollbackStatusMessage(rollbackErrorMsg);
+                                       logger.debug("Updating RequestDB to failed: rollbackErrorMsg = " + rollbackErrorMsg);
+                               }else{
+                                       errorMsg = retrieveErrorMessage(execution);
+                                       if(errorMsg == null || errorMsg.equals("")){
+                                               errorMsg = "Failed to determine error message";
+                                       }
                                        request.setStatusMessage(errorMsg);
-                               } catch (Exception ex) {
-                                       logger.error("Failed to extract workflow exception message from WorkflowException",ex);
-                                       request.setStatusMessage("Unexpected Error in BPMN");
+                                       logger.debug("Updating RequestDB to failed: errorMsg = " + errorMsg);
                                }
                        }
+                       if(ebb!=null && ebb.getBuildingBlock()!=null){
+                               String flowStatus = ebb.getBuildingBlock().getBpmnFlowName() + " has failed.";
+                               request.setFlowStatus(flowStatus);
+                               execution.setVariable("flowStatus", flowStatus);
+                       }
+
+                       request.setProgress(Long.valueOf(100));
                        request.setRequestStatus("FAILED");
                        request.setLastModifiedBy("CamundaBPMN");
                        requestDbclient.updateInfraActiveRequests(request);
@@ -303,4 +371,32 @@ public class WorkflowActionBBTasks {
                        workflowAction.buildAndThrowException(execution, "Error Updating Request Database", e);
                }
        }
+       
+       private String retrieveErrorMessage (DelegateExecution execution){
+               String errorMsg = "";
+               try {
+                       WorkflowException exception = (WorkflowException) execution.getVariable("WorkflowException");
+                       if(exception != null && (exception.getErrorMessage()!=null || !exception.getErrorMessage().equals(""))){
+                               errorMsg = exception.getErrorMessage();
+                       }
+               } catch (Exception ex) {
+                       //log error and attempt to extact WorkflowExceptionMessage
+                       logger.error("Failed to extract workflow exception from execution.",ex);
+               }
+               
+               if (errorMsg == null || errorMsg.equals("")){
+                       try {
+                               errorMsg = (String) execution.getVariable("WorkflowExceptionErrorMessage");
+                       } catch (Exception ex) {
+                               logger.error("Failed to extract workflow exception message from WorkflowException",ex);
+                               errorMsg = "Unexpected Error in BPMN.";
+                       }
+               }
+               return errorMsg;
+       }
+       
+       public void updateRequestStatusToFailedWithRollback(DelegateExecution execution) {
+               execution.setVariable("isRollbackComplete", true);
+               updateRequestStatusToFailed(execution);
+       }
 }