/** * Verifies that the actual IncidentRecordValue's elementInstanceKey is equal to the given one. * @param elementInstanceKey the given elementInstanceKey to compare the actual IncidentRecordValue's elementInstanceKey to. * @return this assertion object. * @throws AssertionError - if the actual IncidentRecordValue's elementInstanceKey is not equal to the given one. */ public S hasElementInstanceKey(long elementInstanceKey) { // check that actual IncidentRecordValue we want to make assertions on is not null. isNotNull(); // overrides the default error message with a more explicit one String assertjErrorMessage = "\nExpecting elementInstanceKey of:\n <%s>\nto be:\n <%s>\nbut was:\n <%s>"; // check long actualElementInstanceKey = actual.getElementInstanceKey(); if (actualElementInstanceKey != elementInstanceKey) { failWithMessage(assertjErrorMessage, actual, elementInstanceKey, actualElementInstanceKey); } // return the current assertion for method chaining return myself; }
@Test public void shouldResolveIncidentIfCorrelationKeyNotFound() { // given final long workflowInstance = testClient.createWorkflowInstance(PROCESS_ID); final Record<IncidentRecordValue> incidentCreatedRecord = RecordingExporter.incidentRecords(IncidentIntent.CREATED).getFirst(); testClient.updatePayload( incidentCreatedRecord.getValue().getElementInstanceKey(), "{\"orderId\":\"order123\"}"); // when testClient.resolveIncident(incidentCreatedRecord.getKey()); // then assertThat( RecordingExporter.workflowInstanceSubscriptionRecords( WorkflowInstanceSubscriptionIntent.OPENED) .exists()) .isTrue(); final Record<IncidentRecordValue> incidentResolvedEvent = testClient.receiveFirstIncidentEvent(workflowInstance, RESOLVED); assertThat(incidentResolvedEvent.getKey()).isEqualTo(incidentCreatedRecord.getKey()); } }
@Test public void shouldResolveIncidentIfCorrelationKeyNotFound() { // given final long workflowInstance = testClient.createWorkflowInstance(PROCESS_ID); final Record<IncidentRecordValue> incidentCreatedRecord = RecordingExporter.incidentRecords(IncidentIntent.CREATED).getFirst(); testClient.updatePayload( incidentCreatedRecord.getValue().getElementInstanceKey(), "{\"orderId\":\"order123\"}"); // when testClient.resolveIncident(incidentCreatedRecord.getKey()); // then assertThat( RecordingExporter.workflowInstanceSubscriptionRecords( WorkflowInstanceSubscriptionIntent.OPENED) .exists()); final Record<IncidentRecordValue> incidentResolvedEvent = testClient.receiveFirstIncidentEvent(workflowInstance, RESOLVED); assertThat(incidentResolvedEvent.getKey()).isEqualTo(incidentCreatedRecord.getKey()); } }
@Test public void shouldResolveIncidentIfActivityTerminated() { // given testClient.deploy(WORKFLOW_INPUT_MAPPING); final long workflowInstanceKey = testClient.createWorkflowInstance("process"); final Record incidentCreatedEvent = testClient.receiveFirstIncidentEvent(IncidentIntent.CREATED); // when testClient.cancelWorkflowInstance(workflowInstanceKey); // then final Record activityTerminating = testClient.receiveFirstWorkflowInstanceEvent( workflowInstanceKey, "failingTask", WorkflowInstanceIntent.ELEMENT_TERMINATING); final Record<IncidentRecordValue> incidentResolvedEvent = testClient.receiveFirstIncidentEvent(RESOLVED); assertThat(incidentResolvedEvent.getKey()).isEqualTo(incidentCreatedEvent.getKey()); assertThat(activityTerminating.getPosition()) .isEqualTo(incidentResolvedEvent.getSourceRecordPosition()); assertIncidentRecordValue( ErrorType.IO_MAPPING_ERROR.name(), "No data found for query $.foo.", workflowInstanceKey, "failingTask", incidentResolvedEvent.getValue().getElementInstanceKey(), incidentResolvedEvent); }
@Test public void shouldResolveIncidentIfActivityTerminated() { // given testClient.deploy(WORKFLOW_INPUT_MAPPING); final long workflowInstanceKey = testClient.createWorkflowInstance("process"); final Record incidentCreatedEvent = testClient.receiveFirstIncidentEvent(IncidentIntent.CREATED); // when testClient.cancelWorkflowInstance(workflowInstanceKey); // then final Record activityTerminating = testClient.receiveFirstWorkflowInstanceEvent( workflowInstanceKey, "failingTask", WorkflowInstanceIntent.ELEMENT_TERMINATING); final Record<IncidentRecordValue> incidentResolvedEvent = testClient.receiveFirstIncidentEvent(RESOLVED); assertThat(incidentResolvedEvent.getKey()).isEqualTo(incidentCreatedEvent.getKey()); assertThat(activityTerminating.getPosition()) .isEqualTo(incidentResolvedEvent.getSourceRecordPosition()); assertIncidentRecordValue( ErrorType.IO_MAPPING_ERROR.name(), "No data found for query $.foo.", workflowInstanceKey, "failingTask", incidentResolvedEvent.getValue().getElementInstanceKey(), incidentResolvedEvent); }
@Test public void shouldDeleteIncidentIfJobIsCanceled() { // given testClient.deploy(WORKFLOW_INPUT_MAPPING); final long workflowInstanceKey = testClient.createWorkflowInstance("process", PAYLOAD); failJobWithNoRetriesLeft(); final Record incidentCreatedEvent = testClient.receiveFirstIncidentEvent(IncidentIntent.CREATED); // when testClient.cancelWorkflowInstance(workflowInstanceKey); // then final Record<WorkflowInstanceRecordValue> terminatingTask = testClient.receiveElementInState("failingTask", WorkflowInstanceIntent.ELEMENT_TERMINATING); final Record jobCancelCommand = testClient.receiveFirstJobCommand(JobIntent.CANCEL); final Record<IncidentRecordValue> resolvedIncidentEvent = testClient.receiveFirstIncidentEvent(IncidentIntent.RESOLVED); assertThat(resolvedIncidentEvent.getKey()).isEqualTo(incidentCreatedEvent.getKey()); assertThat(resolvedIncidentEvent.getSourceRecordPosition()) .isEqualTo(terminatingTask.getPosition()); assertThat(jobCancelCommand.getSourceRecordPosition()).isEqualTo(terminatingTask.getPosition()); assertIncidentRecordValue( ErrorType.JOB_NO_RETRIES.name(), "No more retries left.", workflowInstanceKey, "failingTask", resolvedIncidentEvent.getValue().getElementInstanceKey(), jobCancelCommand.getKey(), resolvedIncidentEvent); }
@Test public void shouldDeleteIncidentIfJobIsCanceled() { // given testClient.deploy(WORKFLOW_INPUT_MAPPING); final long workflowInstanceKey = testClient.createWorkflowInstance("process", PAYLOAD); failJobWithNoRetriesLeft(); final Record incidentCreatedEvent = testClient.receiveFirstIncidentEvent(IncidentIntent.CREATED); // when testClient.cancelWorkflowInstance(workflowInstanceKey); // then final Record<WorkflowInstanceRecordValue> terminatingTask = testClient.receiveElementInState("failingTask", WorkflowInstanceIntent.ELEMENT_TERMINATING); final Record jobCancelCommand = testClient.receiveFirstJobCommand(JobIntent.CANCEL); final Record<IncidentRecordValue> resolvedIncidentEvent = testClient.receiveFirstIncidentEvent(IncidentIntent.RESOLVED); assertThat(resolvedIncidentEvent.getKey()).isEqualTo(incidentCreatedEvent.getKey()); assertThat(resolvedIncidentEvent.getSourceRecordPosition()) .isEqualTo(terminatingTask.getPosition()); assertThat(jobCancelCommand.getSourceRecordPosition()).isEqualTo(terminatingTask.getPosition()); assertIncidentRecordValue( ErrorType.JOB_NO_RETRIES.name(), "No more retries left.", workflowInstanceKey, "failingTask", resolvedIncidentEvent.getValue().getElementInstanceKey(), jobCancelCommand.getKey(), resolvedIncidentEvent); }
@Test public void shouldOpenSubscriptionsWhenIncidentIsResolved() { // given testClient.createWorkflowInstance(PROCESS_ID, MsgPackUtil.asMsgPack("key-1", "k1")); final Record<IncidentRecordValue> incidentCreatedRecord = RecordingExporter.incidentRecords(IncidentIntent.CREATED).getFirst(); // when testClient.updatePayload( incidentCreatedRecord.getValue().getElementInstanceKey(), "{'key-1':'k1', 'key-2':'k2'}"); testClient.resolveIncident(incidentCreatedRecord.getKey()); // then assertThat( RecordingExporter.workflowInstanceSubscriptionRecords( WorkflowInstanceSubscriptionIntent.OPENED) .limit(2)) .extracting(Record::getValue) .extracting(WorkflowInstanceSubscriptionRecordValue::getMessageName) .containsExactlyInAnyOrder("msg-1", "msg-2"); // and testClient.publishMessage("msg-2", "k2"); assertThat( RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.ELEMENT_COMPLETED) .withElementId(PROCESS_ID) .exists()) .isTrue(); }
@Test public void shouldOpenSubscriptionsWhenIncidentIsResolved() { // given testClient.createWorkflowInstance(PROCESS_ID, MsgPackUtil.asMsgPack("key-1", "k1")); final Record<IncidentRecordValue> incidentCreatedRecord = RecordingExporter.incidentRecords(IncidentIntent.CREATED).getFirst(); // when testClient.updatePayload( incidentCreatedRecord.getValue().getElementInstanceKey(), "{'key-1':'k1', 'key-2':'k2'}"); testClient.resolveIncident(incidentCreatedRecord.getKey()); // then assertThat( RecordingExporter.workflowInstanceSubscriptionRecords( WorkflowInstanceSubscriptionIntent.OPENED) .limit(2)) .extracting(Record::getValue) .extracting(WorkflowInstanceSubscriptionRecordValue::getMessageName) .containsExactlyInAnyOrder("msg-1", "msg-2"); // and testClient.publishMessage("msg-2", "k2"); assertThat( RecordingExporter.workflowInstanceRecords(WorkflowInstanceIntent.ELEMENT_COMPLETED) .withElementId(PROCESS_ID) .exists()) .isTrue(); }
workflowInstanceKey, "failingTask", incidentEvent.getValue().getElementInstanceKey(), incidentEvent);
workflowInstanceKey, "failingTask", incidentEvent.getValue().getElementInstanceKey(), incidentEvent);
incidentCreatedRecord.getValue().getElementInstanceKey(), "{'key-1':'k1', 'key-2':'k2'}");
incidentCreatedRecord.getValue().getElementInstanceKey(), "{'key-1':'k1', 'key-2':'k2'}");
@Test public void shouldNotCompleteInstanceAfterIncidentIsRaisedOnActivity() { // given testClient.deploy( Bpmn.createExecutableProcess(PROCESS_ID) .startEvent() .parallelGateway() .serviceTask("task-1", t -> t.zeebeTaskType("task-1")) .endEvent("end-1") .moveToLastGateway() .serviceTask("task-2", t -> t.zeebeTaskType("task-2").zeebeOutput("$.result", "$.r")) .endEvent("end-2") .done()); testClient.createWorkflowInstance(PROCESS_ID); // when testClient.completeJobOfType("task-2"); final Record<IncidentRecordValue> incident = RecordingExporter.incidentRecords(IncidentIntent.CREATED).getFirst(); testClient.completeJobOfType("task-1"); testClient.updatePayload(incident.getValue().getElementInstanceKey(), "{'result':'123'}"); testClient.resolveIncident(incident.getKey()); // then assertThatWorkflowInstanceCompletedAfter("end-2", WorkflowInstanceIntent.EVENT_ACTIVATED); }
@Test public void shouldNotCompleteInstanceAfterIncidentIsRaisedOnActivity() { // given testClient.deploy( Bpmn.createExecutableProcess(PROCESS_ID) .startEvent() .parallelGateway() .serviceTask("task-1", t -> t.zeebeTaskType("task-1")) .endEvent("end-1") .moveToLastGateway() .serviceTask("task-2", t -> t.zeebeTaskType("task-2").zeebeOutput("$.result", "$.r")) .endEvent("end-2") .done()); testClient.createWorkflowInstance(PROCESS_ID); // when testClient.completeJobOfType("task-2"); final Record<IncidentRecordValue> incident = RecordingExporter.incidentRecords(IncidentIntent.CREATED).getFirst(); testClient.completeJobOfType("task-1"); testClient.updatePayload(incident.getValue().getElementInstanceKey(), "{'result':'123'}"); testClient.resolveIncident(incident.getKey()); // then assertThatWorkflowInstanceCompletedAfter("end-2", WorkflowInstanceIntent.ELEMENT_COMPLETED); }
@Test public void shouldNotCompleteInstanceAfterIncidentIsRaisedOnEvent() { // given testClient.deploy( Bpmn.createExecutableProcess(PROCESS_ID) .startEvent() .parallelGateway() .serviceTask("task", t -> t.zeebeTaskType("task")) .endEvent("end-1") .moveToLastGateway() .intermediateCatchEvent( "catch", e -> e.message(m -> m.name("msg").zeebeCorrelationKey("$.key"))) .endEvent("end-2") .done()); testClient.createWorkflowInstance(PROCESS_ID); // when final Record<IncidentRecordValue> incident = RecordingExporter.incidentRecords(IncidentIntent.CREATED).getFirst(); testClient.completeJobOfType("task"); testClient.updatePayload(incident.getValue().getElementInstanceKey(), "{'key':'123'}"); testClient.resolveIncident(incident.getKey()); testClient.publishMessage("msg", "123"); // then assertThatWorkflowInstanceCompletedAfter("end-2", WorkflowInstanceIntent.EVENT_ACTIVATED); }
@Test public void shouldNotCompleteInstanceAfterIncidentIsRaisedOnEvent() { // given testClient.deploy( Bpmn.createExecutableProcess(PROCESS_ID) .startEvent() .parallelGateway() .serviceTask("task", t -> t.zeebeTaskType("task")) .endEvent("end-1") .moveToLastGateway() .intermediateCatchEvent( "catch", e -> e.message(m -> m.name("msg").zeebeCorrelationKey("$.key"))) .endEvent("end-2") .done()); testClient.createWorkflowInstance(PROCESS_ID); // when final Record<IncidentRecordValue> incident = RecordingExporter.incidentRecords(IncidentIntent.CREATED).getFirst(); testClient.completeJobOfType("task"); testClient.updatePayload(incident.getValue().getElementInstanceKey(), "{'key':'123'}"); testClient.resolveIncident(incident.getKey()); testClient.publishMessage("msg", "123"); // then assertThatWorkflowInstanceCompletedAfter("end-2", WorkflowInstanceIntent.ELEMENT_COMPLETED); }
@Test public void shouldNotCompleteInstanceAfterIncidentIsRaisedOnExclusiveGateway() { // given testClient.deploy( Bpmn.createExecutableProcess(PROCESS_ID) .startEvent() .parallelGateway() .serviceTask("task", t -> t.zeebeTaskType("task")) .endEvent("end-1") .moveToLastGateway() .exclusiveGateway("gateway") .defaultFlow() .endEvent("end-2") .moveToNode("gateway") .sequenceFlowId("to-end-3") .condition("$.x < 21") .endEvent("end-3") .done()); testClient.createWorkflowInstance(PROCESS_ID); // when final Record<IncidentRecordValue> incident = RecordingExporter.incidentRecords(IncidentIntent.CREATED).getFirst(); testClient.completeJobOfType("task"); testClient.updatePayload(incident.getValue().getElementInstanceKey(), "{'x':123}"); testClient.resolveIncident(incident.getKey()); // then assertThatWorkflowInstanceCompletedAfter("end-2", WorkflowInstanceIntent.EVENT_ACTIVATED); }
@Test public void shouldNotCompleteInstanceAfterIncidentIsRaisedOnExclusiveGateway() { // given testClient.deploy( Bpmn.createExecutableProcess(PROCESS_ID) .startEvent() .parallelGateway() .serviceTask("task", t -> t.zeebeTaskType("task")) .endEvent("end-1") .moveToLastGateway() .exclusiveGateway("gateway") .defaultFlow() .endEvent("end-2") .moveToNode("gateway") .sequenceFlowId("to-end-3") .condition("$.x < 21") .endEvent("end-3") .done()); testClient.createWorkflowInstance(PROCESS_ID); // when final Record<IncidentRecordValue> incident = RecordingExporter.incidentRecords(IncidentIntent.CREATED).getFirst(); testClient.completeJobOfType("task"); testClient.updatePayload(incident.getValue().getElementInstanceKey(), "{'x':123}"); testClient.resolveIncident(incident.getKey()); // then assertThatWorkflowInstanceCompletedAfter("end-2", WorkflowInstanceIntent.ELEMENT_COMPLETED); }