1. 程式人生 > >流程定義和部署管理——啟用、掛起

流程定義和部署管理——啟用、掛起

我們之前已經看了流程定義列表頁面process-list.jsp和執行流程列表頁面running-manage.jsp,這兩個頁面都有啟用和掛起,那麼有什麼不同呢?

首先是流程定義掛起的url

http://localhost:8080/kft-activiti-demo-no-maven/workflow/processdefinition/update/suspend/leave:1:20

其次是流程例項掛起的url

http://localhost:8080/kft-activiti-demo-no-maven/workflow/processinstance/update/suspend/14

從現象上看,當流程定義啟用或者掛起時,對應的流程執行例項的suspended狀態會跟著改變;

                        當流程執行例項啟用或者掛起時,對應的流程定義的suspended狀態不會跟著改變。

一、流程定義的啟用、掛起

ActivitiController中:

/**
     * 掛起、啟用流程定義
     */
    @RequestMapping(value = "processdefinition/update/{state}/{processDefinitionId}")
    public String updateState(@PathVariable("state") String state, @PathVariable("processDefinitionId") String processDefinitionId,
                              RedirectAttributes redirectAttributes) {
        if (state.equals("active")) {
            redirectAttributes.addFlashAttribute("message", "已啟用ID為[" + processDefinitionId + "]的流程定義。");
            repositoryService.activateProcessDefinitionById(processDefinitionId, true, null);
        } else if (state.equals("suspend")) {
            repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null);
            redirectAttributes.addFlashAttribute("message", "已掛起ID為[" + processDefinitionId + "]的流程定義。");
        }
        return "redirect:/workflow/process-list";
    }

請注意suspendProcessDefinitionById和activateProcessDefinitionById方法的第二個引數,我們來看一下RepositoryServiceImpl中這個方法的定義:
public void suspendProcessDefinitionById(String processDefinitionId, boolean suspendProcessInstances, Date suspensionDate) {
    this.commandExecutor.execute(new SuspendProcessDefinitionCmd(processDefinitionId, null, suspendProcessInstances, suspensionDate, null));
  }

原來它就是用來控制在掛起流程定義時,是否同時掛起對應的流程例項。
public class SuspendProcessDefinitionCmd extends AbstractSetProcessDefinitionStateCmd
{

  public SuspendProcessDefinitionCmd(String processDefinitionId, String processDefinitionKey, boolean suspendProcessInstances, Date suspensionDate, String tenantId)
  {
    super(processDefinitionId, processDefinitionKey, suspendProcessInstances, suspensionDate, tenantId);
  }

}

public abstract class AbstractSetProcessDefinitionStateCmd
  implements Command<Void>
{
public AbstractSetProcessDefinitionStateCmd(String processDefinitionId, String processDefinitionKey, boolean includeProcessInstances, Date executionDate, String tenantId)
  {
    this.processDefinitionId = processDefinitionId;
    this.processDefinitionKey = processDefinitionKey;
    this.includeProcessInstances = includeProcessInstances;
    this.executionDate = executionDate;
    this.tenantId = tenantId;
  }

  public Void execute(CommandContext commandContext)
  {
    List processDefinitions = findProcessDefinition(commandContext);

    if (this.executionDate != null)
      createTimerForDelayedExecution(commandContext, processDefinitions);
    else {
      changeProcessDefinitionState(commandContext, processDefinitions);
    }

    return null;
  }

  protected void changeProcessDefinitionState(CommandContext commandContext, List<ProcessDefinitionEntity> processDefinitions) {
    for (ProcessDefinitionEntity processDefinition : processDefinitions)
    {
      SuspensionState.SuspensionStateUtil.setSuspensionState(processDefinition, getProcessDefinitionSuspensionState());

      commandContext.getProcessEngineConfiguration().getDeploymentManager().getProcessDefinitionCache().remove(processDefinition.getId());

      if (this.includeProcessInstances)
      {
        int currentStartIndex = 0;
        List processInstances = fetchProcessInstancesPage(commandContext, processDefinition, currentStartIndex);
        while (processInstances.size() > 0)
        {
          for (ProcessInstance processInstance : processInstances) {
            AbstractSetProcessInstanceStateCmd processInstanceCmd = getProcessInstanceChangeStateCmd(processInstance);
            processInstanceCmd.execute(commandContext);
          }

          currentStartIndex += processInstances.size();
          processInstances = fetchProcessInstancesPage(commandContext, processDefinition, currentStartIndex);
        }
      }
    }
  }
}

activateProcessDefinitionById呼叫層次類似,不重複。

二、流程例項的啟用、掛起

ProcessInstanceController中:

/**
     * 掛起、啟用流程例項
     */
    @RequestMapping(value = "update/{state}/{processInstanceId}")
    public String updateState(@PathVariable("state") String state, @PathVariable("processInstanceId") String processInstanceId,
                              RedirectAttributes redirectAttributes) {
        if (state.equals("active")) {
            redirectAttributes.addFlashAttribute("message", "已啟用ID為[" + processInstanceId + "]的流程例項。");
            runtimeService.activateProcessInstanceById(processInstanceId);
        } else if (state.equals("suspend")) {
            runtimeService.suspendProcessInstanceById(processInstanceId);
            redirectAttributes.addFlashAttribute("message", "已掛起ID為[" + processInstanceId + "]的流程例項。");
        }
        return "redirect:/workflow/processinstance/running";
    }

這個就暫時沒有過多介紹了,就看一下RuntimeServiceImpl中的實現
public void suspendProcessInstanceById(String processInstanceId) {
    this.commandExecutor.execute(new SuspendProcessInstanceCmd(processInstanceId));
  }

  public void activateProcessInstanceById(String processInstanceId) {
    this.commandExecutor.execute(new ActivateProcessInstanceCmd(processInstanceId));
  }
public class SuspendProcessInstanceCmd extends AbstractSetProcessInstanceStateCmd
{
  public SuspendProcessInstanceCmd(String executionId)
  {
    super(executionId);
  }

}

public abstract class AbstractSetProcessInstanceStateCmd
  implements Command<Void>
{
  protected final String executionId;

  public AbstractSetProcessInstanceStateCmd(String executionId)
  {
    this.executionId = executionId;
  }

  public Void execute(CommandContext commandContext)
  {
    if (this.executionId == null) {
      throw new ActivitiIllegalArgumentException("ProcessInstanceId cannot be null.");
    }

    ExecutionEntity executionEntity = commandContext.getExecutionEntityManager().findExecutionById(this.executionId);

    if (executionEntity == null) {
      throw new ActivitiObjectNotFoundException("Cannot find processInstance for id '" + this.executionId + "'.", Execution.class);
    }
    if (!executionEntity.isProcessInstanceType()) {
      throw new ActivitiException("Cannot set suspension state for execution '" + this.executionId + "': not a process instance.");
    }

    SuspensionState.SuspensionStateUtil.setSuspensionState(executionEntity, getNewState());

    List childExecutions = commandContext.getExecutionEntityManager().findChildExecutionsByProcessInstanceId(this.executionId);
    for (ExecutionEntity childExecution : childExecutions) {
      if (!childExecution.getId().equals(this.executionId)) {
        SuspensionState.SuspensionStateUtil.setSuspensionState(childExecution, getNewState());
      }

    }

    List tasks = commandContext.getTaskEntityManager().findTasksByProcessInstanceId(this.executionId);
    for (TaskEntity taskEntity : tasks) {
      SuspensionState.SuspensionStateUtil.setSuspensionState(taskEntity, getNewState());
    }

    return null;
  }

  protected abstract SuspensionState getNewState();
}