Pregunta

Para desarrollar una aplicación BPM personalizada, hay una característica que usamos con otro proveedor de motores BPM y también nos gusta usarla con Camunda.La funcionalidad objetivo consiste en configurar/restablecer instancias de procesos en ejecución para una tarea específica distinta de la activa actual.Desde nuestra perspectiva es necesario cuando, por ejemplo:

  • creación de instancias de proceso debido a la migración de la versión del proceso
  • resolviendo incidencias
  • resolver el uso accidentalmente incorrecto por parte de un usuario

Finalmente, no encontré una función simple para hacer esto, sino que elaboré un código personalizado que funcionaba con algunas limitaciones.Hay algunas debilidades e incertidumbres dentro de este código por lo que Tengo la siguiente pregunta:

¿Me perdí una forma alternativa de lograr esto o el siguiente enfoque es correcto o incluso no es totalmente compatible en este momento?

Las debilidades actuales en mi humilde opinión:

  • primero y más importante: no se almacena ninguna instancia de tarea histórica.Esto provoca que no sea rastreable quién o incluso cuando la tarea se activó/activó/inició.Encontré la siguiente publicación en el grupo camunda de Google (correo) que dice que es correcto en este punto porque es una tarea fuera del alcance de la definición del proceso pero al usar una definición de tarea de la definición de proceso subyacente, debería estar "en alcance".
  • el código se basa en una implementación interna y no en una interfaz oficial
  • En este punto, se debe hacer una gran cantidad de "bootstrap"/inicialización manualmente, pero como usuario (no desarrollador de Camunda) no soy plenamente consciente de lo que se requiere y lo que es opcional
  • Algunas partes como las expresiones de análisis de la definición de la tarea fallaron (ver código comentado) pero eso puede ser causado por un uso incorrecto

Aquí está el código (fragmento experimental de nuestra fachada de servicio 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;
     }
}

Agradezco cualquier sugerencia o consejo :-)

¿Fue útil?

Solución

No me metería con la instancia de proceso en ese nivel, como ya habrás notado, estás pasando por alto los servicios de camundas.Cuando nos enfrentamos a un problema similar, optamos por lo siguiente:

  1. cancelar la instancia de proceso de la versión anterior del proceso
  2. iniciar una nueva instancia del proceso extendido y reenviarlo mediante programación al estado deseado...

Otra opción:Modele un punto de entrada (evento de inicio del mensaje) dentro de la nueva versión del proceso.Luego, en lugar de reenviar la instancia mediante programación al estado deseado, simplemente inicie la nueva instancia a través del evento y pase todas las variables de proceso de la instancia anterior...

Otros consejos

A partir de Camunda 7.3, puede utilizar la modificación de instancia de proceso para iniciar cualquier actividad en un proceso y cancelar cualquier instancia de actividad activa.

Ejemplo:

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

Ver http://docs.camunda.org/7.3/guides/user-guide/#process-engine-process-instance-modification para documentación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top