Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(MQServiceTaskIT): add should replay running service task integration test #887

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
Comment on lines +156 to +158
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you, please, also add an assertion to check that no integration context related to this process instance was left behind?

}

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