Skip to content

Commit

Permalink
test: add should replay running service task integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
igdianov committed Oct 28, 2022
1 parent 5f9aa8e commit 1226cae
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@
@EnableBinding(CanFailConnectorChannels.class)
public class CanFailConnector {

private boolean shouldSendError = true;
private boolean shouldSendError = false;
private boolean shouldSendResult = true;
private AtomicBoolean integrationErrorSent = new AtomicBoolean(false);
private AtomicBoolean resultSent = new AtomicBoolean(false);
private AtomicBoolean resultNotSent = new AtomicBoolean(false);
private IntegrationRequest latestReceivedIntegrationRequest;

private final IntegrationResultSender integrationResultSender;
Expand All @@ -42,20 +45,33 @@ public CanFailConnector(IntegrationResultSender integrationResultSender,

public void setShouldSendError(boolean shouldSendError) {
this.shouldSendError = shouldSendError;
this.integrationErrorSent.set(false);
}

@StreamListener(value = CanFailConnectorChannels.CAN_FAIL_CONNECTOR)
public void canFailConnector(IntegrationRequest integrationRequest) {
latestReceivedIntegrationRequest = integrationRequest;
integrationErrorSent.set(false);
if (shouldSendError) {
integrationErrorSent.set(true);
integrationErrorSender.send(integrationRequest,
new RuntimeException("task failed"));
} else {
integrationErrorSent.set(true);
} else if (shouldSendResult){
integrationResultSender.send(integrationRequest,
integrationRequest.getIntegrationContext());
resultSent.set(true);
} else {
resultNotSent.set(true);
}

}

public AtomicBoolean resultSent() {
return resultSent;
}

public AtomicBoolean resultNotSent() {
return resultNotSent;
}

public AtomicBoolean errorSent() {
Expand All @@ -65,4 +81,15 @@ public AtomicBoolean errorSent() {
public IntegrationRequest getLatestReceivedIntegrationRequest() {
return latestReceivedIntegrationRequest;
}

public void setShouldSendResult(boolean shouldSendResult) {
this.shouldSendResult = shouldSendResult;
this.resultSent.set(false);
this.resultNotSent.set(false);
}

public void reset() {
setShouldSendResult(true);
setShouldSendError(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.activiti.cloud.starter.tests.runtime;

import org.activiti.api.process.model.IntegrationContext;
import org.activiti.api.task.model.builders.CompleteTaskPayloadBuilder;
import org.activiti.cloud.services.rest.api.ReplayServiceTaskRequest;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
Expand All @@ -24,17 +25,17 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.stream.config.BindingProperties;

import java.util.AbstractMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import java.util.AbstractMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.activiti.cloud.starter.tests.helper.ProcessInstanceRestTemplate.CONTENT_TYPE_HEADER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
Expand Down Expand Up @@ -73,7 +74,10 @@ public void shouldConfigureDefaultConnectorBindingProperties() {

@Test
public void shouldRecoverFromFailure() {
canFailConnector.reset();

//given
canFailConnector.setShouldSendError(true);
Map<String, Object> variables = new HashMap<>();
variables.put("firstName", "John");
ProcessInstance procInst = runtimeService.startProcessInstanceByKey("MQServiceTaskErrorRecoverProcess",
Expand All @@ -92,6 +96,9 @@ public void shouldRecoverFromFailure() {
canFailConnector.setShouldSendError(false);
replayServiceTask(integrationContext);

await("the service task should send the result the second try")
.untilTrue(canFailConnector.resultSent());

//then
await("the execution should arrive in the human tasks which follows the service task")
.untilAsserted(() -> {
Expand All @@ -102,6 +109,55 @@ public void shouldRecoverFromFailure() {
);
}

@Test
public void shouldReplayRunningServiceTask() {
canFailConnector.reset();

//given
canFailConnector.setShouldSendResult(false);
Map<String, Object> variables = new HashMap<>();
variables.put("firstName", "John");
ProcessInstance procInst = runtimeService.startProcessInstanceByKey("MQServiceTaskErrorRecoverProcess",
"businessKey",
variables);
assertThat(procInst).isNotNull();
await("the service task should not send the result on the first try")
.untilTrue(canFailConnector.resultNotSent());

assertThat(taskService.createTaskQuery()
.processInstanceId(procInst.getProcessInstanceId())
.list()).isEmpty();
//when
IntegrationContext integrationContext = canFailConnector.getLatestReceivedIntegrationRequest()
.getIntegrationContext();
canFailConnector.setShouldSendResult(true);
replayServiceTask(integrationContext);

await("the service task should send the result the second try")
.untilTrue(canFailConnector.resultSent());

//then
await("the execution should arrive in the human tasks which follows the service task")
.untilAsserted(() -> {
List<Task> tasks = taskService.createTaskQuery().processInstanceId(procInst.getProcessInstanceId()).list();
assertThat(tasks).isNotNull();
assertThat(tasks).extracting(Task::getName).containsExactly("Schedule meeting after service");
}
);

// and given
Task task = taskService.createTaskQuery()
.processInstanceId(procInst.getProcessInstanceId())
.singleResult();
// when
complete(task);

// then
assertThat(runtimeService.createProcessInstanceQuery()
.processInstanceId(procInst.getProcessInstanceId())
.list()).isEmpty();
}

private void replayServiceTask(IntegrationContext integrationContext) {
identityTokenProducer.withTestUser("testadmin");
final ResponseEntity<Void> responseEntity = testRestTemplate.exchange("/admin/v1/executions/{executionId}/replay/service-task",
Expand All @@ -113,4 +169,15 @@ private void replayServiceTask(IntegrationContext integrationContext) {
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
}

private void complete(Task task) {
identityTokenProducer.withTestUser(keycloakTestUser);
final ResponseEntity<Void> responseEntity = testRestTemplate.exchange("/v1/tasks/{taskId}/complete",
HttpMethod.POST,
new HttpEntity<>(new CompleteTaskPayloadBuilder()
.withTaskId(task.getId())
.build(), CONTENT_TYPE_HEADER),
new ParameterizedTypeReference<>() {
}, task.getId());
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">

<bpmn2:process id="MQServiceTaskErrorRecoverProcess" name="MQServiceTaskProcess">

Expand All @@ -10,7 +10,7 @@

<bpmn2:sequenceFlow id="flow2" sourceRef="serviceTask" targetRef="userTask"/>

<bpmn2:userTask id="userTask" name="Schedule meeting after service"/>
<bpmn2:userTask id="userTask" name="Schedule meeting after service" activiti:assignee="hruser"/>
<bpmn2:sequenceFlow id="flow3" sourceRef="userTask" targetRef="end"/>

<bpmn2:endEvent id="end"/>
Expand Down

0 comments on commit 1226cae

Please sign in to comment.