Domanda

per sviluppare un'applicazione BPM personalizzata c'è una funzionalità che abbiamo utilizzato con un altro fornitore di motori BPM e ci piace usarla anche con camunda.La funzionalità mirata riguarda l'impostazione/reimpostazione delle istanze del processo in esecuzione su un'attività specifica diversa da quella attualmente attiva.Dal nostro punto di vista è necessario quando ad esempio:

  • creazione di istanze di processo a causa della migrazione della versione del processo
  • risolvere gli incidenti
  • risolvere l'utilizzo accidentalmente errato da parte di un utente

Alla fine non ho trovato una funzione semplice per farlo, ma ho elaborato del codice personalizzato che funzionava con alcune limitazioni.Ci sono alcuni punti deboli e incertezze all'interno di questo codice, quindi Ho la seguente domanda:

Mi sono perso un modo alternativo per raggiungere questo obiettivo o il seguente approccio è corretto o addirittura non è completamente supportato al momento?

I punti deboli attuali, secondo me:

  • primo e più importante: non viene archiviata alcuna istanza di attività storica.Ciò provoca che non è tracciabile chi o anche quando l'attività è stata attivata/attivata/avviata.Ho trovato il seguente post sul gruppo Google Camunda (inviare) che dice che è corretto a questo punto perché è un'attività fuori dall'ambito di definizione del processo ma usando una definizione dell'attività dalla definizione di processo sottostante dovrei essere "nell'ambito"?!
  • il codice si basa sull'implementazione interna e non sull'interfaccia ufficiale
  • A questo punto molti "bootstrap"/inizializzazione devono essere eseguiti manualmente ma come utente (non sviluppatore di Camunda) non sono pienamente consapevole di ciò che è richiesto e di ciò che è facoltativo
  • Alcune parti come l'analisi delle espressioni dalla definizione dell'attività non sono riuscite (vedi codice commentato) ma ciò può essere causato da un utilizzo sbagliato

Ecco il codice (snippet sperimentale della nostra facciata del servizio 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;
     }
}

Accetto qualsiasi suggerimento o consiglio :-)

È stato utile?

Soluzione

Non farei confusione con l'istanza del processo a quel livello, come hai già notato, stai bypassando i servizi camundas.Di fronte a un problema simile, abbiamo proceduto come segue:

  1. annullare l'istanza del processo della vecchia versione del processo
  2. avviare una nuova istanza del processo esteso e inoltrarla a livello di codice allo stato desiderato...

Un'altra opzione:modellare un punto di ingresso (evento di inizio messaggio) all'interno della nuova versione del processo.Quindi, invece di inoltrare a livello di codice l'istanza allo stato desiderato, avvia semplicemente la nuova istanza tramite l'evento e passa tutte le variabili di processo della vecchia istanza...

Altri suggerimenti

A partire da Camunda 7.3, è possibile utilizzare la modifica dell'istanza di processo per avviare qualsiasi attività in un processo e annullare qualsiasi istanza di attività attiva.

Esempio:

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

Vedere http://docs.camunda.org/7.3/guides/user-guide/#process-engine-process-instance-modification per la documentazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top