Search in sources :

Example 1 with Either

use of io.camunda.zeebe.util.Either in project zeebe by zeebe-io.

the class BpmnDecisionBehavior method evaluateDecision.

/**
 * Evaluate a decision during the processing of a bpmn element.
 *
 * @param element the called decision of the current bpmn element
 * @param context process instance-related data of the element that is executed
 * @return either an evaluated decision's result or a failure
 */
public Either<Failure, DecisionEvaluationResult> evaluateDecision(final ExecutableCalledDecision element, final BpmnElementContext context) {
    final var scopeKey = context.getElementInstanceKey();
    final var decisionIdOrFailure = evalDecisionIdExpression(element, scopeKey);
    if (decisionIdOrFailure.isLeft()) {
        return Either.left(decisionIdOrFailure.getLeft());
    }
    final var decisionId = decisionIdOrFailure.get();
    // todo(#8571): avoid parsing drg every time
    final var decisionOrFailure = findDecisionById(decisionId);
    final var resultOrFailure = decisionOrFailure.flatMap(this::findDrgByDecision).mapLeft(failure -> new Failure("Expected to evaluate decision '%s', but %s".formatted(decisionId, failure.getMessage()))).flatMap(drg -> parseDrg(drg.getResource())).mapLeft(f -> new Failure(f.getMessage(), ErrorType.CALLED_DECISION_ERROR, scopeKey)).flatMap(drg -> {
        final var evaluationResult = evaluateDecisionInDrg(drg, decisionId, scopeKey);
        final var decision = decisionOrFailure.get();
        writeDecisionEvaluationEvent(decision, evaluationResult, context);
        if (evaluationResult.isFailure()) {
            metrics.increaseFailedEvaluatedDmnElements(evaluationResult.getEvaluatedDecisions().size());
            return Either.left(new Failure(evaluationResult.getFailureMessage(), ErrorType.DECISION_EVALUATION_ERROR, scopeKey));
        } else {
            metrics.increaseSuccessfullyEvaluatedDmnElements(evaluationResult.getEvaluatedDecisions().size());
            return Either.right(evaluationResult);
        }
    });
    resultOrFailure.ifRight(result -> {
        // The output mapping behavior determines what to do with the decision result. Since the
        // output mapping may fail and raise an incident, we need to write the variable to a
        // record. This is because we want to evaluate the decision on element activation, while
        // the output mapping happens on element completion. We don't want to re-evaluate the
        // decision for output mapping related incidents.
        triggerProcessEventWithResultVariable(context, element.getResultVariable(), result);
    });
    return resultOrFailure;
}
Also used : BpmnElementContext(io.camunda.zeebe.engine.processing.bpmn.BpmnElementContext) ErrorType(io.camunda.zeebe.protocol.record.value.ErrorType) DecisionEvaluationResult(io.camunda.zeebe.dmn.DecisionEvaluationResult) ExecutableCalledDecision(io.camunda.zeebe.engine.processing.deployment.model.element.ExecutableCalledDecision) VariableState(io.camunda.zeebe.engine.state.immutable.VariableState) ZeebeState(io.camunda.zeebe.engine.state.immutable.ZeebeState) MatchedRule(io.camunda.zeebe.dmn.MatchedRule) ByteArrayInputStream(java.io.ByteArrayInputStream) Failure(io.camunda.zeebe.engine.processing.common.Failure) DecisionEngine(io.camunda.zeebe.dmn.DecisionEngine) Either(io.camunda.zeebe.util.Either) DecisionState(io.camunda.zeebe.engine.state.immutable.DecisionState) StateWriter(io.camunda.zeebe.engine.processing.streamprocessor.writers.StateWriter) EvaluatedInput(io.camunda.zeebe.dmn.EvaluatedInput) MsgPackConverter(io.camunda.zeebe.protocol.impl.encoding.MsgPackConverter) BufferUtil.bufferAsString(io.camunda.zeebe.util.buffer.BufferUtil.bufferAsString) EvaluatedDecision(io.camunda.zeebe.dmn.EvaluatedDecision) MatchedRuleRecord(io.camunda.zeebe.protocol.impl.record.value.decision.MatchedRuleRecord) EvaluatedDecisionRecord(io.camunda.zeebe.protocol.impl.record.value.decision.EvaluatedDecisionRecord) PersistedDecisionRequirements(io.camunda.zeebe.engine.state.deployment.PersistedDecisionRequirements) KeyGenerator(io.camunda.zeebe.engine.state.KeyGenerator) DecisionEvaluationIntent(io.camunda.zeebe.protocol.record.intent.DecisionEvaluationIntent) ExpandableArrayBuffer(org.agrona.ExpandableArrayBuffer) Collectors(java.util.stream.Collectors) MsgPackWriter(io.camunda.zeebe.msgpack.spec.MsgPackWriter) ExpressionProcessor(io.camunda.zeebe.engine.processing.common.ExpressionProcessor) VariablesContext(io.camunda.zeebe.dmn.impl.VariablesContext) ParsedDecisionRequirementsGraph(io.camunda.zeebe.dmn.ParsedDecisionRequirementsGraph) DecisionEvaluationRecord(io.camunda.zeebe.protocol.impl.record.value.decision.DecisionEvaluationRecord) ProcessEngineMetrics(io.camunda.zeebe.engine.metrics.ProcessEngineMetrics) PersistedDecision(io.camunda.zeebe.engine.state.deployment.PersistedDecision) EventTriggerBehavior(io.camunda.zeebe.engine.processing.common.EventTriggerBehavior) EvaluatedOutput(io.camunda.zeebe.dmn.EvaluatedOutput) BufferUtil(io.camunda.zeebe.util.buffer.BufferUtil) DirectBuffer(org.agrona.DirectBuffer) Failure(io.camunda.zeebe.engine.processing.common.Failure)

Example 2 with Either

use of io.camunda.zeebe.util.Either in project zeebe by camunda.

the class QueryApiRequestHandlerTest method processFound.

@DisplayName("should respond with bpmnProcessId when process found")
@Test
void processFound() throws ClosedServiceException {
    // given
    final QueryApiRequestHandler sut = createQueryApiRequestHandler(true);
    final var bpmnProcessId = BufferUtil.wrapString("OneProcessToFindThem");
    final var queryService = mock(QueryService.class);
    sut.addPartition(1, queryService);
    when(queryService.getBpmnProcessIdForProcess(1)).thenReturn(Optional.of(bpmnProcessId));
    // when
    final Either<ErrorResponse, ExecuteQueryResponse> response = new AsyncExecuteQueryRequestSender(sut).sendRequest(new ExecuteQueryRequest().setPartitionId(1).setKey(1).setValueType(ValueType.PROCESS)).join();
    // then
    EitherAssert.assertThat(response).isRight().extracting(Either::get).extracting(ExecuteQueryResponse::getBpmnProcessId).isEqualTo("OneProcessToFindThem");
}
Also used : ExecuteQueryRequest(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryRequest) ExecuteQueryResponse(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryResponse) Either(io.camunda.zeebe.util.Either) ErrorResponse(io.camunda.zeebe.protocol.impl.encoding.ErrorResponse) Test(org.junit.jupiter.api.Test) DisplayName(org.junit.jupiter.api.DisplayName)

Example 3 with Either

use of io.camunda.zeebe.util.Either in project zeebe by camunda.

the class QueryApiRequestHandlerTest method processNotFound.

@DisplayName("should respond with PROCESS_NOT_FOUND when no process with key exists")
@Test
void processNotFound() {
    // given
    final QueryApiRequestHandler sut = createQueryApiRequestHandler(true);
    sut.addPartition(1, mock(QueryService.class));
    // when
    final Either<ErrorResponse, ExecuteQueryResponse> response = new AsyncExecuteQueryRequestSender(sut).sendRequest(new ExecuteQueryRequest().setPartitionId(1).setKey(1).setValueType(ValueType.PROCESS)).join();
    // then
    EitherAssert.assertThat(response).isLeft().extracting(Either::getLeft).extracting(ErrorResponse::getErrorCode, error -> BufferUtil.bufferAsString(error.getErrorData())).containsExactly(ErrorCode.PROCESS_NOT_FOUND, "Expected to find the process ID for resource of type PROCESS with key 1, but no such " + "resource was found");
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) ErrorCode(io.camunda.zeebe.protocol.record.ErrorCode) ClosedServiceException(io.camunda.zeebe.engine.state.QueryService.ClosedServiceException) UnsafeBuffer(org.agrona.concurrent.UnsafeBuffer) ValueType(io.camunda.zeebe.protocol.record.ValueType) CompletableFuture(java.util.concurrent.CompletableFuture) ErrorResponse(io.camunda.zeebe.protocol.impl.encoding.ErrorResponse) ExecuteQueryResponse(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryResponse) ServerOutput(io.camunda.zeebe.transport.ServerOutput) Either(io.camunda.zeebe.util.Either) QueryApiCfg(io.camunda.zeebe.broker.system.configuration.QueryApiCfg) ExecutionMode(org.junit.jupiter.api.parallel.ExecutionMode) Mockito.when(org.mockito.Mockito.when) ExpandableArrayBuffer(org.agrona.ExpandableArrayBuffer) DisplayName(org.junit.jupiter.api.DisplayName) ExecuteQueryRequest(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryRequest) EitherAssert(io.camunda.zeebe.test.util.asserts.EitherAssert) Test(org.junit.jupiter.api.Test) AfterEach(org.junit.jupiter.api.AfterEach) QueryService(io.camunda.zeebe.engine.state.QueryService) Optional(java.util.Optional) Execution(org.junit.jupiter.api.parallel.Execution) BufferUtil(io.camunda.zeebe.util.buffer.BufferUtil) Mockito.mock(org.mockito.Mockito.mock) ActorScheduler(io.camunda.zeebe.util.sched.ActorScheduler) ExecuteQueryRequest(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryRequest) QueryService(io.camunda.zeebe.engine.state.QueryService) ExecuteQueryResponse(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryResponse) Either(io.camunda.zeebe.util.Either) ErrorResponse(io.camunda.zeebe.protocol.impl.encoding.ErrorResponse) Test(org.junit.jupiter.api.Test) DisplayName(org.junit.jupiter.api.DisplayName)

Example 4 with Either

use of io.camunda.zeebe.util.Either in project zeebe by camunda.

the class QueryApiRequestHandlerTest method jobNotFound.

@DisplayName("should respond with PROCESS_NOT_FOUND when no job with key exists")
@Test
void jobNotFound() {
    // given
    final QueryApiRequestHandler sut = createQueryApiRequestHandler(true);
    sut.addPartition(1, mock(QueryService.class));
    // when
    final Either<ErrorResponse, ExecuteQueryResponse> response = new AsyncExecuteQueryRequestSender(sut).sendRequest(new ExecuteQueryRequest().setPartitionId(1).setKey(1).setValueType(ValueType.JOB)).join();
    // then
    EitherAssert.assertThat(response).isLeft().extracting(Either::getLeft).extracting(ErrorResponse::getErrorCode, error -> BufferUtil.bufferAsString(error.getErrorData())).containsExactly(ErrorCode.PROCESS_NOT_FOUND, "Expected to find the process ID for resource of type JOB with key 1, but no such " + "resource was found");
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) ErrorCode(io.camunda.zeebe.protocol.record.ErrorCode) ClosedServiceException(io.camunda.zeebe.engine.state.QueryService.ClosedServiceException) UnsafeBuffer(org.agrona.concurrent.UnsafeBuffer) ValueType(io.camunda.zeebe.protocol.record.ValueType) CompletableFuture(java.util.concurrent.CompletableFuture) ErrorResponse(io.camunda.zeebe.protocol.impl.encoding.ErrorResponse) ExecuteQueryResponse(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryResponse) ServerOutput(io.camunda.zeebe.transport.ServerOutput) Either(io.camunda.zeebe.util.Either) QueryApiCfg(io.camunda.zeebe.broker.system.configuration.QueryApiCfg) ExecutionMode(org.junit.jupiter.api.parallel.ExecutionMode) Mockito.when(org.mockito.Mockito.when) ExpandableArrayBuffer(org.agrona.ExpandableArrayBuffer) DisplayName(org.junit.jupiter.api.DisplayName) ExecuteQueryRequest(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryRequest) EitherAssert(io.camunda.zeebe.test.util.asserts.EitherAssert) Test(org.junit.jupiter.api.Test) AfterEach(org.junit.jupiter.api.AfterEach) QueryService(io.camunda.zeebe.engine.state.QueryService) Optional(java.util.Optional) Execution(org.junit.jupiter.api.parallel.Execution) BufferUtil(io.camunda.zeebe.util.buffer.BufferUtil) Mockito.mock(org.mockito.Mockito.mock) ActorScheduler(io.camunda.zeebe.util.sched.ActorScheduler) ExecuteQueryRequest(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryRequest) QueryService(io.camunda.zeebe.engine.state.QueryService) ExecuteQueryResponse(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryResponse) Either(io.camunda.zeebe.util.Either) ErrorResponse(io.camunda.zeebe.protocol.impl.encoding.ErrorResponse) Test(org.junit.jupiter.api.Test) DisplayName(org.junit.jupiter.api.DisplayName)

Example 5 with Either

use of io.camunda.zeebe.util.Either in project zeebe by camunda.

the class QueryApiRequestHandlerTest method processInstanceNotFound.

@DisplayName("should respond with PROCESS_NOT_FOUND when no process instance with key exists")
@Test
void processInstanceNotFound() {
    // given
    final QueryApiRequestHandler sut = createQueryApiRequestHandler(true);
    sut.addPartition(1, mock(QueryService.class));
    // when
    final Either<ErrorResponse, ExecuteQueryResponse> response = new AsyncExecuteQueryRequestSender(sut).sendRequest(new ExecuteQueryRequest().setPartitionId(1).setKey(1).setValueType(ValueType.PROCESS_INSTANCE)).join();
    // then
    EitherAssert.assertThat(response).isLeft().extracting(Either::getLeft).extracting(ErrorResponse::getErrorCode, error -> BufferUtil.bufferAsString(error.getErrorData())).containsExactly(ErrorCode.PROCESS_NOT_FOUND, "Expected to find the process ID for resource of type PROCESS_INSTANCE with key 1, but " + "no such resource was found");
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) ErrorCode(io.camunda.zeebe.protocol.record.ErrorCode) ClosedServiceException(io.camunda.zeebe.engine.state.QueryService.ClosedServiceException) UnsafeBuffer(org.agrona.concurrent.UnsafeBuffer) ValueType(io.camunda.zeebe.protocol.record.ValueType) CompletableFuture(java.util.concurrent.CompletableFuture) ErrorResponse(io.camunda.zeebe.protocol.impl.encoding.ErrorResponse) ExecuteQueryResponse(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryResponse) ServerOutput(io.camunda.zeebe.transport.ServerOutput) Either(io.camunda.zeebe.util.Either) QueryApiCfg(io.camunda.zeebe.broker.system.configuration.QueryApiCfg) ExecutionMode(org.junit.jupiter.api.parallel.ExecutionMode) Mockito.when(org.mockito.Mockito.when) ExpandableArrayBuffer(org.agrona.ExpandableArrayBuffer) DisplayName(org.junit.jupiter.api.DisplayName) ExecuteQueryRequest(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryRequest) EitherAssert(io.camunda.zeebe.test.util.asserts.EitherAssert) Test(org.junit.jupiter.api.Test) AfterEach(org.junit.jupiter.api.AfterEach) QueryService(io.camunda.zeebe.engine.state.QueryService) Optional(java.util.Optional) Execution(org.junit.jupiter.api.parallel.Execution) BufferUtil(io.camunda.zeebe.util.buffer.BufferUtil) Mockito.mock(org.mockito.Mockito.mock) ActorScheduler(io.camunda.zeebe.util.sched.ActorScheduler) ExecuteQueryRequest(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryRequest) QueryService(io.camunda.zeebe.engine.state.QueryService) ExecuteQueryResponse(io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryResponse) Either(io.camunda.zeebe.util.Either) ErrorResponse(io.camunda.zeebe.protocol.impl.encoding.ErrorResponse) Test(org.junit.jupiter.api.Test) DisplayName(org.junit.jupiter.api.DisplayName)

Aggregations

Either (io.camunda.zeebe.util.Either)28 ErrorResponse (io.camunda.zeebe.protocol.impl.encoding.ErrorResponse)24 ExecuteQueryRequest (io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryRequest)24 ExecuteQueryResponse (io.camunda.zeebe.protocol.impl.encoding.ExecuteQueryResponse)24 DisplayName (org.junit.jupiter.api.DisplayName)24 Test (org.junit.jupiter.api.Test)24 BufferUtil (io.camunda.zeebe.util.buffer.BufferUtil)16 ExpandableArrayBuffer (org.agrona.ExpandableArrayBuffer)16 QueryApiCfg (io.camunda.zeebe.broker.system.configuration.QueryApiCfg)15 QueryService (io.camunda.zeebe.engine.state.QueryService)15 ClosedServiceException (io.camunda.zeebe.engine.state.QueryService.ClosedServiceException)15 ErrorCode (io.camunda.zeebe.protocol.record.ErrorCode)15 ValueType (io.camunda.zeebe.protocol.record.ValueType)15 EitherAssert (io.camunda.zeebe.test.util.asserts.EitherAssert)15 ServerOutput (io.camunda.zeebe.transport.ServerOutput)15 ActorScheduler (io.camunda.zeebe.util.sched.ActorScheduler)15 Optional (java.util.Optional)15 CompletableFuture (java.util.concurrent.CompletableFuture)15 UnsafeBuffer (org.agrona.concurrent.UnsafeBuffer)15 AfterEach (org.junit.jupiter.api.AfterEach)15