public WorkflowInstanceAssert hasEntered(String... elementIds) { final List<String> ids = Arrays.asList(elementIds); final List<String> enteredElements = RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.ELEMENT_ACTIVATED) .withWorkflowInstanceKey(workflowInstanceKey) .filter(elementId(ids)) .map(r -> r.getValue().getElementId()) .limit(ids.size()) .collect(Collectors.toList()); if (enteredElements.size() < ids.size()) { final List<String> notEntered = new ArrayList<>(ids); notEntered.removeAll(enteredElements); failWithMessage("Expected <%s> to be entered but could not find <%s>", ids, notEntered); } return this; }
public List<Record<WorkflowInstanceRecordValue>> receiveElementInstancesInState( Intent intent, BpmnElementType elementType, int expectedNumber) { return receiveWorkflowInstances() .withIntent(intent) .withElementType(elementType) .limit(expectedNumber) .collect(Collectors.toList()); }
public Record<WorkflowInstanceRecordValue> receiveFirstWorkflowInstanceEvent( final long wfInstanceKey, final String elementId, final Intent intent) { return receiveWorkflowInstances() .withIntent(intent) .withWorkflowInstanceKey(wfInstanceKey) .withElementId(elementId) .getFirst(); }
public Record<WorkflowInstanceRecordValue> receiveFirstWorkflowInstanceEvent( final long wfInstanceKey, final Intent intent, BpmnElementType elementType) { return receiveWorkflowInstances() .withIntent(intent) .withWorkflowInstanceKey(wfInstanceKey) .withElementType(elementType) .getFirst(); }
public Record<WorkflowInstanceRecordValue> receiveFirstWorkflowInstanceEvent( final long wfInstanceKey, final Intent intent) { return receiveWorkflowInstances() .withIntent(intent) .withWorkflowInstanceKey(wfInstanceKey) .getFirst(); }
@Test public void shouldActivateTasksOnParallelBranches() { // given testClient.deploy(FORK_PROCESS); // when testClient.createWorkflowInstance(PROCESS_ID); // then final List<Record<WorkflowInstanceRecordValue>> taskEvents = testClient .receiveWorkflowInstances() .withIntent(WorkflowInstanceIntent.ELEMENT_ACTIVATED) .filter(e -> isServiceTaskInProcess(e.getValue().getElementId(), FORK_PROCESS)) .limit(2) .collect(Collectors.toList()); assertThat(taskEvents).hasSize(2); assertThat(taskEvents) .extracting(e -> e.getValue().getElementId()) .containsExactlyInAnyOrder("task1", "task2"); assertThat(taskEvents.get(0).getKey()).isNotEqualTo(taskEvents.get(1).getKey()); }
private void assertThatWorkflowInstanceCompletedAfter( String elementId, WorkflowInstanceIntent intent) { final Record<WorkflowInstanceRecordValue> lastEvent = RecordingExporter.workflowInstanceRecords(intent).withElementId(elementId).getFirst(); final Record<WorkflowInstanceRecordValue> completedEvent = RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.ELEMENT_COMPLETED) .withElementId(PROCESS_ID) .getFirst(); assertThat(completedEvent.getPosition()).isGreaterThan(lastEvent.getPosition()); } }
@Test public void shouldCorrelateMessageToAllSubscriptions() { // given testClient.deploy(SINGLE_MESSAGE_WORKFLOW); final long workflowInstanceKey1 = testClient.createWorkflowInstance(PROCESS_ID, asMsgPack("key", "order-123")); final long workflowInstanceKey2 = testClient.createWorkflowInstance(PROCESS_ID, asMsgPack("key", "order-123")); // when testClient.publishMessage("message", "order-123"); // then final List<Record<WorkflowInstanceRecordValue>> events = testClient .receiveWorkflowInstances() .withIntent(WorkflowInstanceIntent.EVENT_TRIGGERED) .withElementId("receive-message") .limit(2) .collect(Collectors.toList()); assertThat(events) .extracting(r -> r.getValue().getWorkflowInstanceKey()) .contains(workflowInstanceKey1, workflowInstanceKey2); }
testClient .receiveWorkflowInstances() .withIntent(WorkflowInstanceIntent.SEQUENCE_FLOW_TAKEN) .withWorkflowInstanceKey(workflowInstance1) .limit(3) .map(s -> s.getValue().getElementId()) .collect(Collectors.toList()); assertThat(takenSequenceFlows).contains("s1").doesNotContain("s2"); testClient .receiveWorkflowInstances() .withIntent(WorkflowInstanceIntent.SEQUENCE_FLOW_TAKEN) .withWorkflowInstanceKey(workflowInstance2) .limit(3) .map(s -> s.getValue().getElementId()) .collect(Collectors.toList()); assertThat(takenSequenceFlows).contains("s2").doesNotContain("s1");
@Test public void shouldCreateMultipleInstanceAtTheCorrectTimes() { // when testClient.deploy(MULTI_TIMER_START_MODEL); assertThat(RecordingExporter.timerRecords(TimerIntent.CREATED).limit(2).count()).isEqualTo(2); brokerRule.getClock().addTime(Duration.ofSeconds(2)); // then assertThat( RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.EVENT_TRIGGERED) .withElementId("start_4") .exists()) .isTrue(); assertThat( RecordingExporter.workflowInstanceRecords(EVENT_ACTIVATED) .withElementId("end_4") .exists()) .isTrue(); brokerRule.getClock().addTime(Duration.ofSeconds(1)); assertThat( RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.EVENT_TRIGGERED) .withElementId("start_5") .exists()) .isTrue(); assertThat( RecordingExporter.workflowInstanceRecords(EVENT_ACTIVATED) .withElementId("end_5") .exists()) .isTrue(); }
public WorkflowInstanceAssert hasElementPayload( String elementId, String key, Object expectedValue) { final Optional<Record<WorkflowInstanceRecordValue>> record = RecordingExporter.workflowInstanceRecords() .withWorkflowInstanceKey(workflowInstanceKey) .withElementId(elementId) .filter(r -> ELEMENT_PASSED_INTENTS.contains(r.getMetadata().getIntent())) .findFirst(); if (record.isPresent()) { hasPayload(record.get(), key, expectedValue); } else { failWithMessage("Expected <%s> to contain payload but element was not passed", elementId); } return this; }
@Test public void shouldCreateMultipleWorkflowInstancesForDifferentBpmnProcessIds() { // given testClient.deploy(Bpmn.createExecutableProcess("foo").startEvent().endEvent().done()); testClient.deploy(Bpmn.createExecutableProcess("bar").startEvent().endEvent().done()); // when final long workflowInstanceKeyFoo = testClient.createWorkflowInstance("foo"); final long workflowInstanceKeyBar = testClient.createWorkflowInstance("bar"); // then final List<Record<WorkflowInstanceRecordValue>> workflowInstanceEvents = testClient .receiveWorkflowInstances() .filterRootScope() .withIntent(WorkflowInstanceIntent.ELEMENT_READY) .limit(2) .collect(Collectors.toList()); assertWorkflowInstanceRecord( "foo", 1, workflowInstanceKeyFoo, "foo", workflowInstanceEvents.get(0)); assertWorkflowInstanceRecord( "bar", 1, workflowInstanceKeyBar, "bar", workflowInstanceEvents.get(1)); }
@Test public void shouldCreateMultipleWorkflowInstancesWithRepeatingTimer() { // when testClient.deployWithResponse(THREE_SEC_MODEL); // then assertThat(RecordingExporter.timerRecords(TimerIntent.CREATED).exists()).isTrue(); brokerRule.getClock().addTime(Duration.ofSeconds(3)); assertThat(RecordingExporter.timerRecords(TimerIntent.TRIGGERED).exists()).isTrue(); assertThat( RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.ELEMENT_ACTIVATING) .withElementId("process_3") .exists()) .isTrue(); assertThat(RecordingExporter.timerRecords(TimerIntent.CREATED).limit(2).count()).isEqualTo(2); brokerRule.getClock().addTime(Duration.ofSeconds(3)); assertThat(RecordingExporter.timerRecords(TimerIntent.TRIGGERED).limit(2).count()).isEqualTo(2); assertThat( RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.ELEMENT_ACTIVATING) .withElementId("process_3") .limit(2) .count()) .isEqualTo(2); }
@Test public void shouldContinueWhenMessageIsCorrelated() { // given testClient.deploy(WORKFLOW_WITH_MESSAGES); testClient.createWorkflowInstance(PROCESS_ID, asMsgPack("key", "123")); final Record<WorkflowInstanceRecordValue> gatewayEvent = RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.ELEMENT_ACTIVATED) .withElementType(BpmnElementType.EVENT_BASED_GATEWAY) .getFirst(); // when testClient.publishMessage("msg-1", "123"); // then final Record<WorkflowInstanceSubscriptionRecordValue> triggeredEvent = RecordingExporter.workflowInstanceSubscriptionRecords( WorkflowInstanceSubscriptionIntent.CORRELATED) .getFirst(); Assertions.assertThat(triggeredEvent.getValue()) .hasElementInstanceKey(gatewayEvent.getKey()) .hasMessageName("msg-1"); assertThat( RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.SEQUENCE_FLOW_TAKEN) .withElementId("to-end1") .exists()) .isTrue(); assertThat( RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.ELEMENT_COMPLETED) .withElementId(PROCESS_ID) .exists()) .isTrue(); }
public List<Record<WorkflowInstanceRecordValue>> receiveElementInstancesInState( Intent intent, int expectedNumber) { return receiveWorkflowInstances() .withIntent(intent) .limit(expectedNumber) .collect(Collectors.toList()); }
public Record<WorkflowInstanceRecordValue> receiveElementInState( final String elementId, final WorkflowInstanceIntent intent) { return receiveWorkflowInstances().withIntent(intent).withElementId(elementId).getFirst(); }
public WorkflowInstanceAssert hasPayload(String key, Object expectedValue) { final Optional<Record<WorkflowInstanceRecordValue>> record = RecordingExporter.workflowInstanceRecords() .withWorkflowInstanceKey(workflowInstanceKey) .withKey(workflowInstanceKey) .filter(intent(INSTANCE_ENDED_INTENTS)) .findFirst(); if (record.isPresent()) { hasPayload(record.get(), key, expectedValue); } else { failWithMessage("Expected workflow instance to contain payload but instance is not ended"); } return this; }
public WorkflowInstanceAssert isEnded() { final boolean isEnded = exists( RecordingExporter.workflowInstanceRecords() .withWorkflowInstanceKey(workflowInstanceKey) .withKey(workflowInstanceKey) .filter(intent(INSTANCE_ENDED_INTENTS))); if (!isEnded) { failWithMessage("Expected workflow instance to be <ended> but was <active>"); } return this; }
@Test public void shouldCorrelateMessageOnlyOnceIfPublishedBefore() { // given testClient.deploy(TWO_MESSAGES_WORKFLOW); testClient.publishMessage("ping", "123", asMsgPack("nr", 1)); testClient.publishMessage("ping", "123", asMsgPack("nr", 2)); // when testClient.createWorkflowInstance(PROCESS_ID, asMsgPack("key", "123")); // then assertThat( RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.EVENT_TRIGGERED) .filter(r -> r.getValue().getElementId().startsWith("message")) .limit(2) .asList()) .extracting( r -> tuple(r.getValue().getElementId(), r.getValue().getPayloadAsMap().get("nr"))) .contains(tuple("message1", 1), tuple("message2", 2)); }
@Test public void shouldContinueWhenMessageIsCorrelated() { // given testClient.deploy(WORKFLOW_WITH_MESSAGES); testClient.createWorkflowInstance(PROCESS_ID, asMsgPack("key", "123")); final Record<WorkflowInstanceRecordValue> gatewayEvent = RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.GATEWAY_ACTIVATED) .getFirst(); // when testClient.publishMessage("msg-1", "123"); // then final Record<WorkflowInstanceSubscriptionRecordValue> triggeredEvent = RecordingExporter.workflowInstanceSubscriptionRecords( WorkflowInstanceSubscriptionIntent.CORRELATED) .getFirst(); Assertions.assertThat(triggeredEvent.getValue()) .hasElementInstanceKey(gatewayEvent.getKey()) .hasMessageName("msg-1"); assertThat( RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.SEQUENCE_FLOW_TAKEN) .withElementId("to-end1") .exists()) .isTrue(); assertThat( RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.ELEMENT_COMPLETED) .withElementId(PROCESS_ID) .exists()); }