未验证 提交 c4a0e1e5 编写于 作者: V Vito 提交者: GitHub

[DW-1665] - added api call to start a created process instance (#3224)

* [DW-1665] - added api call to start a created process instance

* [DW-1665] - reverted wrong pom change

* [DW-1665] - fixed imports

* [DW-1665] - added peer review change requests

* [DW-1665] - fixed failing tests

* [DW-1665] - fixed code quality issues
上级 c7de3f1a
......@@ -73,6 +73,11 @@ public interface ProcessRuntime {
*/
ProcessInstance start(StartProcessPayload startProcessPayload);
/**
* Start an already created Process Instance based on the process instance id
*/
ProcessInstance startCreatedProcess(String processInstanceId);
/**
* Create a new Process Instance based on the payload parameters
*/
......
......@@ -255,6 +255,22 @@ public class ProcessRuntimeImpl implements ProcessRuntime {
return processInstanceConverter.from(this.createProcessInstanceBuilder(startProcessPayload).start());
}
@Override
public ProcessInstance startCreatedProcess(String processInstanceId) {
org.activiti.engine.runtime.ProcessInstance internalProcessInstance = runtimeService
.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
if (internalProcessInstance == null) {
throw new NotFoundException("Unable to find process instance for the given id:'" + processInstanceId + "'");
}
if (!securityPoliciesManager.canRead(internalProcessInstance.getProcessDefinitionKey())) {
throw new ActivitiObjectNotFoundException("You cannot read the process instance with Id:'" + processInstanceId + "' due to security policies violation");
}
return processInstanceConverter.from(runtimeService.startCreatedProcessInstance(internalProcessInstance));
}
@Override
public ProcessInstance create(StartProcessPayload startProcessPayload) {
return processInstanceConverter.from(this.createProcessInstanceBuilder(startProcessPayload).create());
......
......@@ -26,6 +26,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import java.util.Collections;
......@@ -38,6 +39,7 @@ import org.activiti.api.process.model.payloads.UpdateProcessPayload;
import org.activiti.api.runtime.model.impl.DeploymentImpl;
import org.activiti.api.runtime.model.impl.ProcessDefinitionImpl;
import org.activiti.api.runtime.model.impl.ProcessInstanceImpl;
import org.activiti.api.runtime.shared.NotFoundException;
import org.activiti.api.runtime.shared.UnprocessableEntityException;
import org.activiti.core.common.spring.security.policies.ProcessSecurityPoliciesManager;
import org.activiti.engine.ActivitiObjectNotFoundException;
......@@ -45,6 +47,7 @@ import org.activiti.engine.RuntimeService;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.persistence.entity.DeploymentEntityImpl;
import org.activiti.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntityImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
......@@ -128,7 +131,7 @@ public class ProcessRuntimeImplTest {
.build();
//when
ProcessInstance updatedProcess = processRuntime.update(updateProcessPayload);
processRuntime.update(updateProcessPayload);
//then
verify(runtimeService).updateBusinessKey("processId", "businessKey");
......@@ -251,4 +254,45 @@ public class ProcessRuntimeImplTest {
verify(processInstanceBuilder).name(startPayload.getName());
}
@Test
public void should_startAnAlreadyCreatedProcessInstance_whenCalled() {
//given
String processInstanceId = "process-instance-id";
ProcessInstanceQuery processQuery = mock(ProcessInstanceQuery.class);
doReturn(processQuery).when(processQuery).processInstanceId(processInstanceId);
doReturn(processQuery).when(runtimeService).createProcessInstanceQuery();
org.activiti.engine.runtime.ProcessInstance internalProcess = new ExecutionEntityImpl();
internalProcess.setAppVersion(1);
doReturn(internalProcess).when(processQuery).singleResult();
when(runtimeService.startCreatedProcessInstance(internalProcess)).thenReturn(internalProcess);
ProcessInstanceImpl apiProcessInstance = new ProcessInstanceImpl();
apiProcessInstance.setBusinessKey("business-result");
apiProcessInstance.setId("999-999");
given(processInstanceConverter.from(internalProcess)).willReturn(apiProcessInstance);
given(securityPoliciesManager.canRead(any())).willReturn(true);
//when
ProcessInstance createdProcessInstance = processRuntime.startCreatedProcess(processInstanceId);
//then
assertThat(createdProcessInstance.getId()).isEqualTo("999-999");
assertThat(createdProcessInstance.getBusinessKey()).isEqualTo("business-result");
}
@Test
public void should_throwAndException_whenProcessIdDoesNotExists() {
//given
String processInstanceId = "process-instance-id";
ProcessInstanceQuery processQuery = mock(ProcessInstanceQuery.class);
doReturn(processQuery).when(processQuery).processInstanceId(processInstanceId);
doReturn(processQuery).when(runtimeService).createProcessInstanceQuery();
doReturn(null).when(processQuery).singleResult();
Throwable exception = catchThrowable(() -> processRuntime.startCreatedProcess(processInstanceId));
assertThat(exception)
.isInstanceOf(NotFoundException.class)
.hasMessage("Unable to find process instance for the given id:'process-instance-id'");
}
}
package org.activiti.engine.impl.cmd;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.util.ProcessInstanceHelper;
import org.activiti.engine.runtime.ProcessInstance;
import java.io.Serializable;
public class StartCreatedProcessInstanceCmd<T> implements Command<ProcessInstance>, Serializable {
private static final long serialVersionUID = 1L;
private ProcessInstance internalProcessInstance;
public StartCreatedProcessInstanceCmd(ProcessInstance internalProcessInstance){
this.internalProcessInstance = internalProcessInstance;
}
@Override
public ProcessInstance execute(CommandContext commandContext) {
if(this.internalProcessInstance.getStartTime() != null){
throw new ActivitiIllegalArgumentException("Process instance " + this.internalProcessInstance.getProcessInstanceId() + " has already been started");
}
ExecutionEntity processExecution = (ExecutionEntity) this.internalProcessInstance;
ProcessInstanceHelper processInstanceHelper = commandContext.getProcessEngineConfiguration().getProcessInstanceHelper();
processInstanceHelper.startProcessInstance(processExecution, commandContext, processExecution.getVariables(), processExecution.getCurrentFlowElement());
return processExecution;
}
}
......@@ -7,7 +7,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import org.activiti.api.process.model.Deployment;
import org.activiti.api.process.model.ProcessDefinition;
import org.activiti.api.process.model.ProcessInstance;
......@@ -19,7 +18,11 @@ import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.process.runtime.conf.ProcessRuntimeConfiguration;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.core.common.spring.security.policies.ProcessSecurityPoliciesManager;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.runtime.api.impl.ProcessAdminRuntimeImpl;
......@@ -48,6 +51,7 @@ public class ProcessRuntimeIT {
private static final String CATEGORIZE_PROCESS = "categorizeProcess";
private static final String CATEGORIZE_HUMAN_PROCESS = "categorizeHumanProcess";
private static final String SINGLE_TASK_PROCESS = "SingleTaskProcess";
private static final String ONE_STEP_PROCESS = "OneStepProcess";
private static final String SUB_PROCESS = "subProcess";
......@@ -101,6 +105,9 @@ public class ProcessRuntimeIT {
@Autowired
private ProcessCleanUpUtil processCleanUpUtil;
@Autowired
private TaskRuntime taskRuntime;
@After
public void cleanUp(){
processCleanUpUtil.cleanUpWithAdmin();
......@@ -201,6 +208,61 @@ public class ProcessRuntimeIT {
assertThat(categorizeProcess.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.CREATED);
}
@Test
public void should_startAnAlreadyCreatedProcess_when_startCreatedProcessIsCalled() {
securityUtil.logInAs("garth");
ProcessInstance singleTaskProcessCreated = processRuntime.create(ProcessPayloadBuilder.start()
.withProcessDefinitionKey(SINGLE_TASK_PROCESS)
.build());
assertThat(singleTaskProcessCreated.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.CREATED);
Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 50),
TaskPayloadBuilder
.tasks()
.withProcessInstanceId(singleTaskProcessCreated.getId())
.build());
assertThat(tasks.getTotalItems()).isEqualTo(0);
ProcessInstance singleTaskProcessStarted = processRuntime.startCreatedProcess(singleTaskProcessCreated.getId());
tasks = taskRuntime.tasks(Pageable.of(0, 50),
TaskPayloadBuilder
.tasks()
.withProcessInstanceId(singleTaskProcessCreated.getId())
.build());
assertThat(tasks.getTotalItems()).isEqualTo(1);
assertThat(tasks.getContent().get(0).getName()).isEqualTo("my-task");
assertThat(RuntimeTestConfiguration.createdTasks).contains(tasks.getContent().get(0).getId());
assertThat(singleTaskProcessStarted).isNotNull();
assertThat(singleTaskProcessStarted.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.RUNNING);
}
@Test
public void should_throwAnError_when_ProcessInstanceIsAlreadyStartedOrCompleted() {
securityUtil.logInAs("user");
ProcessInstance categorizeProcess = processRuntime.start(ProcessPayloadBuilder.start()
.withProcessDefinitionKey(CATEGORIZE_HUMAN_PROCESS)
.withVariable("expectedKey",
true)
.withVariable("name","garth")
.withVariable("age",45)
.withBusinessKey("my business key")
.build());
assertThat(categorizeProcess.getStatus()).isEqualTo(ProcessInstance.ProcessInstanceStatus.RUNNING);
Throwable throwable = catchThrowable(() -> processRuntime.startCreatedProcess(categorizeProcess.getId()));
assertThat(throwable)
.isInstanceOf(ActivitiIllegalArgumentException.class)
.hasMessage("Process instance "+categorizeProcess.getId()+" has already been started");
}
@Test
public void createProcessInstanceAndValidateDiscardPath() {
......
......@@ -168,7 +168,7 @@ public class ExecutionListenerOnTransactionTest extends SpringActivitiTestCase {
}
@Deployment
public void testOnCloseFailureExecutionListenersWithTransactionalOperation() {
public void testOnCloseFailureExecutionListenersWithTransactionalOperation() throws InterruptedException {
MyTransactionalOperationTransactionDependentExecutionListener.clear();
......@@ -183,6 +183,7 @@ public class ExecutionListenerOnTransactionTest extends SpringActivitiTestCase {
historicProcessInstances.get(0).getProcessDefinitionKey());
}
Thread.sleep(3);
ProcessInstance secondProcessInstance = runtimeService.startProcessInstanceByKey("secondTransactionDependentExecutionListenerProcess");
assertProcessEnded(secondProcessInstance.getId());
......
......@@ -31,14 +31,14 @@ public class MyTransactionalOperationTransactionDependentExecutionListener exten
@Override
public void notify(String processInstanceId, String executionId, FlowElement currentFlowElement,
Map<String, Object> executionVariables, Map<String, Object> customPropertiesMap) {
super.notify(processInstanceId, executionId, currentFlowElement, executionVariables, customPropertiesMap);
if (Context.getProcessEngineConfiguration().getHistoryLevel().isAtLeast(HistoryLevel.ACTIVITY)) {
HistoryService historyService = Context.getProcessEngineConfiguration().getHistoryService();
// delete first historic instance
List<HistoricProcessInstance> historicProcessInstances = historyService.createHistoricProcessInstanceQuery().list();
List<HistoricProcessInstance> historicProcessInstances = historyService.createHistoricProcessInstanceQuery().orderByProcessInstanceStartTime().asc().list();
historyService.deleteHistoricProcessInstance(historicProcessInstances.get(0).getId());
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册