프로세스 인스턴스 실행에 대한 작업을 수동으로 변경합니다
-
21-12-2019 - |
문제
사용자 정의 BPM 응용 프로그램을 개발하는 순서대로 다른 BPM 엔진 공급자와 함께 사용한 한 가지 기능이 하나 있고 Camunda 와도 사용하고 싶습니다. 대상 기능은 프로세스 인스턴스를 현재 활성 상태 이외의 지정된 태스크로 설정 / 재설정하는 것입니다. 예를 들어,
에 필요한 우리의 관점에서- 프로세스 버전 마이그레이션으로 인한 프로세스 인스턴스 제작
- 사건 해결
- 사용자 에 의한 탁월하게 잘못된 사용을 해결하기
마침내 나는 이것을하기위한 간단한 기능을 발견하지 못했지만 몇 가지 제한 사항과 일하는 사용자 정의 코드를 해결하지 못했습니다. 이 코드 내에서 약점과 불확실성이 있으므로 다음 질문이 있습니다 :
이를 달성하기위한 다른 방법을 놓치거나 다음과 같은 접근법이 정확하거나 순간에 완전히 지원되지 않는 것입니까?
현재 약점이 IMHO :
- 역사적인 태스크 인스턴스가 저장되지 않습니다 . 이 작업이 트리거되거나 활성화 / 시작된 WHO 또는 STARTION을 추적 할 수 없거나 추적 할 수 없게됩니다. Camunda Google 그룹 ( 게시물 이는 그것이 말합니다 프로세스 정의 범위에서 작업이 없기 때문에이 시점에서 정확하지만 기본 프로세스 정의에서 작업 정의를 사용하여해야합니다. "범위"가되어야합니까?!
- 코드는 공식 인터페이스 에없는 내부 구현을 기반으로합니다.
- 이 시점에서 "부트 스트랩"/ 초기화가 수동으로 수행되어야합니다. 그러나 사용자로서 (camunda의 개발자가 아님) 나는 필요한 것을 완전히 알지 못하고 선택적 는 무엇입니까?
- 작업 정의에서 구문 분석 표현식과 같은 일부 일부가 실패했습니다 (코드를 참조하십시오) 그러나 그것은 잘못된 사용법으로 인해 발생할 수 있습니다
여기 코드가 있습니다 (Camunda Service Facade의 실험적 스 니펫) :
@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;
}
}
.
힌트 나 조언에 감사드립니다. -)
해결책
해당 레벨에서 프로세스 인스턴스를 망치지 않으려면 이미 알아 차리면 Camundas Services를 우회하고 있습니다.비슷한 문제로 직면했을 때, 우리는 다음과 같이갔습니다.
- 이전 프로세스 버전의 프로세스 인스턴스를 취소
- 확장 프로세스의 새로운 인스턴스를 시작하고 프로그래밍 방식으로 원하는 상태로 전달 ...
다른 옵션 : 새 프로세스 버전 내에서 진입 점 (메시지 시작 이벤트)을 모델링합니다.그런 다음 프로그래밍 방식으로 인스턴스를 원하는 상태로 전달하는 대신 이벤트를 통해 새 인스턴스를 시작하고 이전 인스턴스의 모든 프로세스 변수를 전달하십시오 ...
다른 팁
Camunda 7.3부터는 프로세스 인스턴스 수정을 사용하여 프로세스에서 모든 활동을 시작하고 활성 활동 인스턴스를 취소 할 수 있습니다.
예 :
runtimeService.createProcessInstanceModification(processInstanceId)
.startBeforeActivity("someActivityId")
.cancelActivityInstance("someActivityInstanceId")
.execute();
.
http : // docs.camunda.org/7.3/guides/user-guide/#process-engine-process-instance-modification 문서를 위해