Pergunta

para desenvolver um aplicativo BPM personalizado, há um recurso que usamos com outro fornecedor de mecanismo de BPM e também gostamos de usá-lo com camunda.A funcionalidade direcionada trata de configurar/redefinir instâncias de processo em execução para uma tarefa especificada diferente da ativa no momento.Da nossa perspectiva, é necessário quando, por exemplo:

  • criação de instâncias de processo devido à migração de versão de processo
  • resolver incidentes
  • resolver o uso acidentalmente errado por um usuário

Por fim, não encontrei uma função simples para fazer isso, mas desenvolvi um código personalizado que funcionava com algumas limitações.Existem algumas fraquezas e incertezas neste código, de modo que Eu tenho a seguinte pergunta:

Perdi uma maneira alternativa de conseguir isso ou a abordagem a seguir está correta ou é totalmente sem suporte no momento?

Os pontos fracos atuais:

  • primeiro e mais importante: nenhuma instância de tarefa histórica é armazenada.Isso faz com que não seja rastreável quem ou mesmo quando a tarefa foi acionada/ativada/iniciada.Encontrei a seguinte postagem no grupo camunda google (publicar) que diz que está correto neste momento, porque é uma tarefa fora do escopo da definição de processo, mas usando uma definição de tarefa da definição de processo subjacente, eu deveria estar "no escopo"?!
  • o código é baseado na implementação interna e não na interface oficial
  • Nesse ponto
  • Algumas peças como a análise de expressões da definição de tarefas falharam (consulte o código comentado), mas isso pode ser causado por uso errado

Aqui está o código (trecho experimental da nossa fachada de serviço camunda):

@Inject
protected HistoryService histService;
@Inject
protected TaskService taskService;
@Inject
protected ManagementService managementService;
@Inject
protected RuntimeService runtimeService;
@Inject
protected IdentityService identityService;
@Inject
protected RepositoryService repositoryService;
@Inject
protected FormService formService;
@Inject
protected ProcessEngine processEngine;


public void startTask(String processInstanceId, String taskKey) {
    Collection<TaskDefinition> taskDefs = getAvailableTasks(
            processInstanceId);
    TaskEntity newTask = null;
    TaskDefinition taskDef = null;
    for (TaskDefinition taskDefinition : taskDefs) {
        if (taskDefinition.getKey().equals(taskKey)) {
            taskDef = taskDefinition;
            break;
        }
    }
    boolean taskDefExists = taskDef != null;
    List<Task> runningTasksByKey = getTasksByKey(taskKey, processInstanceId);
    boolean taskIsAlreadyRunning = runningTasksByKey != null
            && runningTasksByKey.size() > 0;
    if (taskDefExists && !taskIsAlreadyRunning) {
        newTask = (TaskEntity) taskService.newTask();
        ProcessInstance procInst = getProcessInstance(processInstanceId);
        ExecutionEntity procInstEntity = (ExecutionEntity) procInst;
        String taskName = (String) taskDef.getNameExpression().
                getExpressionText();
//            String taskAssigne = (String) taskDef.getAssigneeExpression().
//                    getValue(
//                            procInstEntity);
//            newTask.setAssignee(taskAssigne);
            newTask.setTaskDefinitionKey(taskDef.getKey());
            newTask.setProcessInstance(procInstEntity);
            newTask.setTaskDefinition(taskDef);
            newTask.setName(taskName);
            newTask.setProcessInstanceId(processInstanceId);
            newTask.setProcessDefinitionId(procInstEntity.
                    getProcessDefinitionId());
            taskService.saveTask(newTask);

        TaskServiceImpl taskServiceImpl = (TaskServiceImpl) BpmPlatform.
                getProcessEngineService().getDefaultProcessEngine().
                getTaskService();
        CommandExecutor commandExecutor = taskServiceImpl.
                getCommandExecutor();
        ExecutionEntity executionEntity = commandExecutor.execute(
                new SaveTaskActivityInstanceCmd(newTask,
                        procInstEntity));
//            commandExecutor.execute(new `SaveTaskHistoricActivityInstanceCmd(executionEntity, newTask));`
    }
}

public Collection<TaskDefinition> getAvailableTasks(String processInstanceId) {
            Map<String, TaskDefinition> taskDefs = null;
            Collection<TaskDefinition> taskDefObjects = null;
            if (processInstanceId != null) {
                ProcessInstanceQuery procInstQuery = runtimeService.
                        createProcessInstanceQuery().processInstanceId(
                                processInstanceId);
                ProcessDefinitionEntity procDefEntity = getProcessDefinitionEager(
                        processInstanceId);
                taskDefs = procDefEntity.getTaskDefinitions();
            }
            taskDefObjects = (Collection<TaskDefinition>) (taskDefs != null ? taskDefs.
                    values() : new ArrayList<TaskDefinition>());
            return taskDefObjects;
}

public ProcessDefinitionEntity getProcessDefinitionEager(
        String processInstanceId) {
    ProcessInstanceQuery procInstQuery = runtimeService.
            createProcessInstanceQuery().processInstanceId(
                    processInstanceId);
    ProcessInstance procInst = procInstQuery.singleResult();
    String procDefId = procInst.getProcessDefinitionId();
    return (ProcessDefinitionEntity) repositoryService.getProcessDefinition(
            procDefId);
}

public List<Task> getTasksByKey(String taskKey, String processInstanceId) {
    List<Task> tasks = taskService.createTaskQuery().processInstanceId(
            processInstanceId).taskDefinitionKey(taskKey).list();
    return tasks;
}


public class SaveTaskActivityInstanceCmd implements Command<ExecutionEntity>,  
      Serializable {

    private TaskEntity newTask;
    private ExecutionEntity procInstEntity;

    public SaveTaskActivityInstanceCmd(TaskEntity newTaskInit,
            ExecutionEntity procInstEntityInit) {
        this.newTask = newTaskInit;
        this.procInstEntity = procInstEntityInit;
    }


    public ExecutionEntity execute(CommandContext commandContext) {
          ActivityImpl actImpl = new ActivityImpl(newTask.
                getTaskDefinitionKey(),
                procInstEntity.getProcessDefinition());
          actImpl.setActivityBehavior(new UserTaskActivityBehavior(
                new CdiExpressionManager(), newTask.getTaskDefinition()));
          ExecutionEntity execEntity = new ExecutionEntity();
          execEntity.setActivity(actImpl);
          execEntity.setActivityInstanceId(newTask.getTaskDefinitionKey()
                + ":" + newTask.getId());
          execEntity.setEventName(newTask.getEventName());
          execEntity.setProcessDefinitionId(newTask.getProcessDefinitionId());
          execEntity.setActive(true);
          execEntity.setProcessInstance(procInstEntity);
          commandContext.getExecutionManager().insert(execEntity);
          return execEntity;
     }
}

Agradeço qualquer dica ou conselho :-)

Foi útil?

Solução

Eu não mexeria na instância do processo nesse nível, como você já percebeu, você está contornando os serviços camundas.Quando nos deparamos com um problema semelhante, optamos pelo seguinte:

  1. cancelar a instância do processo da versão antiga do processo
  2. inicie uma nova instância do processo estendido e encaminhe-o programaticamente para o estado desejado...

Outra opção:modelar um ponto de entrada (evento de início de mensagem) dentro da nova versão do processo.Então, ao invés de encaminhar programaticamente a instância para o estado desejado, basta iniciar a nova instância através do evento e passar todas as variáveis ​​de processo da instância antiga...

Outras dicas

A partir do Camunda 7.3, você pode usar a modificação de instância de processo para iniciar qualquer atividade em um processo e cancelar qualquer instância de atividade ativa.

Exemplo:

runtimeService.createProcessInstanceModification(processInstanceId)
  .startBeforeActivity("someActivityId")
  .cancelActivityInstance("someActivityInstanceId")
  .execute();

Ver http://docs.camunda.org/7.3/guides/user-guide/#process-engine-process-instance-modification para documentação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top