All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cloudfoundry.multiapps.controller.process.steps.ProcessStepHelper Maven / Gradle / Ivy

There is a newer version: 1.183.0
Show newest version
package org.cloudfoundry.multiapps.controller.process.steps;

import java.text.MessageFormat;
import java.util.List;
import java.util.stream.Collectors;

import org.cloudfoundry.multiapps.common.ContentException;
import org.cloudfoundry.multiapps.common.SLException;
import org.cloudfoundry.multiapps.controller.core.model.ErrorType;
import org.cloudfoundry.multiapps.controller.persistence.model.HistoricOperationEvent;
import org.cloudfoundry.multiapps.controller.persistence.model.ImmutableProgressMessage;
import org.cloudfoundry.multiapps.controller.persistence.model.ProgressMessage.ProgressMessageType;
import org.cloudfoundry.multiapps.controller.persistence.services.ProcessLogger;
import org.cloudfoundry.multiapps.controller.persistence.services.ProcessLoggerPersister;
import org.cloudfoundry.multiapps.controller.persistence.services.ProgressMessageService;
import org.cloudfoundry.multiapps.controller.process.Messages;
import org.cloudfoundry.multiapps.controller.process.util.ProcessHelper;
import org.cloudfoundry.multiapps.controller.process.util.StepLogger;
import org.cloudfoundry.multiapps.controller.process.variables.Variables;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.runtime.Execution;
import org.immutables.value.Value;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Value.Immutable
public abstract class ProcessStepHelper {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProcessStepHelper.class);

    public static boolean isProcessAborted(List historicOperationEvents) {
        return historicOperationEvents.stream()
                                      .map(HistoricOperationEvent::getType)
                                      .anyMatch(HistoricOperationEvent.EventType.ABORT_EXECUTED::equals);
    }

    protected void postExecuteStep(ProcessContext context, StepPhase state) {
        logDebug(MessageFormat.format(Messages.STEP_FINISHED, context.getExecution()
                                                                     .getCurrentFlowElement()
                                                                     .getName()));

        getProcessLoggerPersister().persistLogs(context.getVariable(Variables.CORRELATION_ID), context.getVariable(Variables.TASK_ID));
        context.setVariable(Variables.STEP_EXECUTION, state.toString());
    }

    void preExecuteStep(ProcessContext context, StepPhase initialPhase) {
        String taskId = context.getExecution()
                               .getCurrentActivityId();
        context.setVariable(Variables.TASK_ID, taskId);

        deletePreviousErrorType(context);
        getStepLogger().logFlowableTask();
        context.setVariable(Variables.STEP_PHASE, initialPhase);
    }

    protected void deletePreviousErrorType(ProcessContext context) {
        String processId = context.getExecution()
                                  .getProcessInstanceId();
        ErrorType errorType = context.getVariable(Variables.ERROR_TYPE);
        if (errorType == null) {
            return;
        }
        LOGGER.debug(MessageFormat.format(Messages.DELETING_ERROR_TYPE_O_FOR_PROCESS_1, errorType, processId));
        context.removeVariable(Variables.ERROR_TYPE);
    }

    protected void logExceptionAndStoreProgressMessage(ProcessContext context, Throwable t) {
        logException(context, t);
        storeExceptionInProgressMessageService(context, t);
    }

    private void logException(ProcessContext context, Throwable t) {
        LOGGER.error(Messages.EXCEPTION_CAUGHT, t);
        getProcessLogger().error(Messages.EXCEPTION_CAUGHT, t);

        if (t instanceof ContentException) {
            context.setVariable(Variables.ERROR_TYPE, ErrorType.CONTENT_ERROR);
        } else {
            context.setVariable(Variables.ERROR_TYPE, ErrorType.UNKNOWN_ERROR);
        }
    }

    private void storeExceptionInProgressMessageService(ProcessContext context, Throwable throwable) {
        try {
            getProgressMessageService().add(ImmutableProgressMessage.builder()
                                                                    .processId(context.getVariable(Variables.CORRELATION_ID))
                                                                    .taskId(getCurrentActivityId(context.getExecution()))
                                                                    .type(ProgressMessageType.ERROR)
                                                                    .text(throwable.getMessage())
                                                                    .build());
        } catch (SLException e) {
            getProcessLogger().error(Messages.SAVING_ERROR_MESSAGE_FAILED, e);
        }
    }

    // This method is needed because sometimes the DelegateExecution::getCurrentActivityId returns null
    // Check the issue: https://github.com/flowable/flowable-engine/issues/1280
    private String getCurrentActivityId(DelegateExecution execution) {
        List processExecutions = getProcessEngineConfiguration().getRuntimeService()
                                                                           .createExecutionQuery()
                                                                           .processInstanceId(execution.getProcessInstanceId())
                                                                           .list();
        List processExecutionsWithActivityIds = processExecutions.stream()
                                                                            .filter(e -> e.getActivityId() != null)
                                                                            .collect(Collectors.toList());
        if (processExecutionsWithActivityIds.isEmpty()) {
            // if this happen then there is a really big problem with Flowable :)
            throw new SLException("There are no executions for process with id: " + execution.getProcessInstanceId());
        }
        return processExecutionsWithActivityIds.get(0)
                                               .getActivityId();
    }

    private void logDebug(String message) {
        getProcessLogger().debug(message);
    }

    private ProcessLogger getProcessLogger() {
        return getStepLogger().getProcessLogger();
    }

    public void failStepIfProcessIsAborted(ProcessContext context) {
        String correlationId = context.getVariable(Variables.CORRELATION_ID);
        List historicOperationEvents = getProcessHelper().getHistoricOperationEventByProcessId(correlationId);
        if (isProcessAborted(historicOperationEvents)) {
            throw new SLException(Messages.PROCESS_WAS_ABORTED);
        }
    }

    public abstract ProgressMessageService getProgressMessageService();

    public abstract StepLogger getStepLogger();

    public abstract ProcessLoggerPersister getProcessLoggerPersister();

    public abstract ProcessEngineConfiguration getProcessEngineConfiguration();

    public abstract ProcessHelper getProcessHelper();

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy