io.camunda.zeebe.process.test.engine.GrpcResponseMapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zeebe-process-test-engine Show documentation
Show all versions of zeebe-process-test-engine Show documentation
Test engine for running process tests. This a minimized version of the real Zeebe engine and
should be used for testing purposes only.
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
* one or more contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright ownership.
* Licensed under the Zeebe Community License 1.1. You may not use this file
* except in compliance with the Zeebe Community License 1.1.
*/
package io.camunda.zeebe.process.test.engine;
import com.google.protobuf.GeneratedMessageV3;
import com.google.rpc.Code;
import com.google.rpc.Status;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.ActivateJobsRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.ActivateJobsResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.ActivatedJob;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.BroadcastSignalRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.BroadcastSignalResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.CancelProcessInstanceRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.CancelProcessInstanceResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.CompleteJobRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.CompleteJobResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.CreateProcessInstanceRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.CreateProcessInstanceResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.CreateProcessInstanceWithResultRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.CreateProcessInstanceWithResultResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.DecisionMetadata;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.DecisionRequirementsMetadata;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.DeployProcessRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.DeployProcessResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.DeployResourceRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.DeployResourceResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.DeployResourceResponse.Builder;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.EvaluateDecisionRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.EvaluateDecisionResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.EvaluatedDecision;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.EvaluatedDecisionInput;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.EvaluatedDecisionOutput;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.FailJobRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.FailJobResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.FormMetadata;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.MatchedDecisionRule;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.MigrateProcessInstanceRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.MigrateProcessInstanceResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.ModifyProcessInstanceRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.ModifyProcessInstanceResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.ProcessMetadata;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.PublishMessageRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.PublishMessageResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.ResolveIncidentRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.ResolveIncidentResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.SetVariablesRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.SetVariablesResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.ThrowErrorRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.ThrowErrorResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.UpdateJobRetriesRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.UpdateJobRetriesResponse;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.UpdateJobTimeoutRequest;
import io.camunda.zeebe.gateway.protocol.GatewayOuterClass.UpdateJobTimeoutResponse;
import io.camunda.zeebe.protocol.impl.encoding.MsgPackConverter;
import io.camunda.zeebe.protocol.impl.record.value.decision.DecisionEvaluationRecord;
import io.camunda.zeebe.protocol.impl.record.value.deployment.DeploymentRecord;
import io.camunda.zeebe.protocol.impl.record.value.incident.IncidentRecord;
import io.camunda.zeebe.protocol.impl.record.value.job.JobBatchRecord;
import io.camunda.zeebe.protocol.impl.record.value.job.JobRecord;
import io.camunda.zeebe.protocol.impl.record.value.processinstance.ProcessInstanceCreationRecord;
import io.camunda.zeebe.protocol.impl.record.value.processinstance.ProcessInstanceResultRecord;
import io.camunda.zeebe.protocol.impl.record.value.signal.SignalRecord;
import io.camunda.zeebe.protocol.impl.record.value.variable.VariableDocumentRecord;
import io.camunda.zeebe.protocol.record.RejectionType;
import io.camunda.zeebe.protocol.record.intent.Intent;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import org.agrona.DirectBuffer;
class GrpcResponseMapper {
private DirectBuffer valueBufferView;
private long key;
private Intent intent;
private final Map, Callable> mappers =
Map.ofEntries(
Map.entry(ActivateJobsRequest.class, this::createJobBatchResponse),
Map.entry(CancelProcessInstanceRequest.class, this::createCancelInstanceResponse),
Map.entry(CompleteJobRequest.class, this::createCompleteJobResponse),
Map.entry(CreateProcessInstanceRequest.class, this::createProcessInstanceResponse),
Map.entry(
CreateProcessInstanceWithResultRequest.class,
this::createProcessInstanceWithResultResponse),
Map.entry(EvaluateDecisionRequest.class, this::evaluateDecisionResponse),
Map.entry(DeployProcessRequest.class, this::createDeployResponse),
Map.entry(DeployResourceRequest.class, this::createDeployResourceResponse),
Map.entry(FailJobRequest.class, this::createFailJobResponse),
Map.entry(ThrowErrorRequest.class, this::createJobThrowErrorResponse),
Map.entry(PublishMessageRequest.class, this::createMessageResponse),
Map.entry(ResolveIncidentRequest.class, this::createResolveIncidentResponse),
Map.entry(SetVariablesRequest.class, this::createSetVariablesResponse),
Map.entry(UpdateJobRetriesRequest.class, this::createJobUpdateRetriesResponse),
Map.entry(UpdateJobTimeoutRequest.class, this::createJobUpdateTimeOutResponse),
Map.entry(ModifyProcessInstanceRequest.class, this::createModifyProcessInstanceResponse),
Map.entry(
MigrateProcessInstanceRequest.class, this::createMigrateProcessInstanceResponse),
Map.entry(BroadcastSignalRequest.class, this::createBroadcastSignalResponse));
GeneratedMessageV3 map(
final Class extends GeneratedMessageV3> requestType,
final DirectBuffer valueBufferView,
final long key,
final Intent intent) {
try {
this.valueBufferView = valueBufferView;
this.key = key;
this.intent = intent;
return mappers.get(requestType).call();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
@Deprecated(since = "8.0.0")
private DeployProcessResponse createDeployResponse() {
final DeploymentRecord deployment = new DeploymentRecord();
deployment.wrap(valueBufferView);
return DeployProcessResponse.newBuilder()
.setKey(key)
.addAllProcesses(
deployment.getProcessesMetadata().stream()
.map(
metadata ->
ProcessMetadata.newBuilder()
.setProcessDefinitionKey(metadata.getProcessDefinitionKey())
.setBpmnProcessId(metadata.getBpmnProcessId())
.setVersion(metadata.getVersion())
.setResourceName(metadata.getResourceName())
.build())
.collect(Collectors.toList()))
.build();
}
private GeneratedMessageV3 createDeployResourceResponse() {
final DeploymentRecord deployment = new DeploymentRecord();
deployment.wrap(valueBufferView);
final Builder builder = DeployResourceResponse.newBuilder().setKey(key);
deployment.getProcessesMetadata().stream()
.map(
metadata ->
ProcessMetadata.newBuilder()
.setBpmnProcessId(metadata.getBpmnProcessId())
.setVersion(metadata.getVersion())
.setProcessDefinitionKey(metadata.getProcessDefinitionKey())
.setResourceName(metadata.getResourceName())
.build())
.forEach(metadata -> builder.addDeploymentsBuilder().setProcess(metadata));
deployment.decisionsMetadata().stream()
.map(
metadata ->
DecisionMetadata.newBuilder()
.setDmnDecisionId(metadata.getDecisionId())
.setDmnDecisionName(metadata.getDecisionName())
.setVersion(metadata.getVersion())
.setDecisionKey(metadata.getDecisionKey())
.setDmnDecisionRequirementsId(metadata.getDecisionRequirementsId())
.setDecisionRequirementsKey(metadata.getDecisionRequirementsKey())
.build())
.forEach(metadata -> builder.addDeploymentsBuilder().setDecision(metadata));
deployment.decisionRequirementsMetadata().stream()
.map(
metadata ->
DecisionRequirementsMetadata.newBuilder()
.setDmnDecisionRequirementsId(metadata.getDecisionRequirementsId())
.setDmnDecisionRequirementsName(metadata.getDecisionRequirementsName())
.setVersion(metadata.getDecisionRequirementsVersion())
.setDecisionRequirementsKey(metadata.getDecisionRequirementsKey())
.setResourceName(metadata.getResourceName())
.build())
.forEach(metadata -> builder.addDeploymentsBuilder().setDecisionRequirements(metadata));
deployment.formMetadata().stream()
.map(
metadata ->
FormMetadata.newBuilder()
.setFormId(metadata.getFormId())
.setVersion(metadata.getVersion())
.setFormKey(metadata.getFormKey())
.setResourceName(metadata.getResourceName())
.setTenantId(metadata.getTenantId()))
.forEach(metadata -> builder.addDeploymentsBuilder().setForm(metadata));
return builder.build();
}
private GeneratedMessageV3 evaluateDecisionResponse() {
final DecisionEvaluationRecord evaluationRecord = new DecisionEvaluationRecord();
evaluationRecord.wrap(valueBufferView);
final List evaluatedDecisions =
evaluationRecord.evaluatedDecisions().stream()
.map(
evaluatedDecision ->
EvaluatedDecision.newBuilder()
.setDecisionId(evaluatedDecision.getDecisionId())
.setDecisionKey(evaluatedDecision.getDecisionKey())
.setDecisionName(evaluatedDecision.getDecisionName())
.setDecisionVersion(evaluatedDecision.getDecisionVersion())
.setDecisionType(evaluatedDecision.getDecisionType())
.setDecisionOutput(evaluatedDecision.getDecisionOutput())
// map evaluated decision inputs
.addAllEvaluatedInputs(
evaluatedDecision.evaluatedInputs().stream()
.map(
evaluatedInput ->
EvaluatedDecisionInput.newBuilder()
.setInputValue(evaluatedInput.getInputValue())
.setInputName(evaluatedInput.getInputName())
.setInputId(evaluatedInput.getInputId())
.build())
.collect(Collectors.toList()))
// map matched decision rules
.addAllMatchedRules(
evaluatedDecision.matchedRules().stream()
.map(
matchedRule ->
MatchedDecisionRule.newBuilder()
.setRuleIndex(matchedRule.getRuleIndex())
.setRuleId(matchedRule.getRuleId())
// map evaluated decision outputs
.addAllEvaluatedOutputs(
matchedRule.evaluatedOutputs().stream()
.map(
evaluatedOutput ->
EvaluatedDecisionOutput.newBuilder()
.setOutputValue(
evaluatedOutput
.getOutputValue())
.setOutputName(
evaluatedOutput.getOutputName())
.setOutputId(
evaluatedOutput.getOutputId())
.build())
.collect(Collectors.toList()))
.build())
.collect(Collectors.toList()))
.build())
.collect(Collectors.toList());
return EvaluateDecisionResponse.newBuilder()
.setDecisionId(evaluationRecord.getDecisionId())
.setDecisionKey(evaluationRecord.getDecisionKey())
.setDecisionName(evaluationRecord.getDecisionName())
.setDecisionVersion(evaluationRecord.getDecisionVersion())
.setDecisionRequirementsId(evaluationRecord.getDecisionRequirementsId())
.setDecisionRequirementsKey(evaluationRecord.getDecisionRequirementsKey())
.setDecisionOutput(evaluationRecord.getDecisionOutput())
.setFailedDecisionId(evaluationRecord.getFailedDecisionId())
.setFailureMessage(evaluationRecord.getEvaluationFailureMessage())
.addAllEvaluatedDecisions(evaluatedDecisions)
.build();
}
private GeneratedMessageV3 createProcessInstanceResponse() {
final ProcessInstanceCreationRecord processInstance = new ProcessInstanceCreationRecord();
processInstance.wrap(valueBufferView);
return CreateProcessInstanceResponse.newBuilder()
.setProcessInstanceKey(processInstance.getProcessInstanceKey())
.setProcessDefinitionKey(processInstance.getProcessDefinitionKey())
.setBpmnProcessId(processInstance.getBpmnProcessId())
.setVersion(processInstance.getVersion())
.build();
}
private GeneratedMessageV3 createProcessInstanceWithResultResponse() {
final ProcessInstanceResultRecord processInstanceResult = new ProcessInstanceResultRecord();
processInstanceResult.wrap(valueBufferView);
return CreateProcessInstanceWithResultResponse.newBuilder()
.setProcessInstanceKey(processInstanceResult.getProcessInstanceKey())
.setProcessDefinitionKey(processInstanceResult.getProcessDefinitionKey())
.setBpmnProcessId(processInstanceResult.getBpmnProcessId())
.setVersion(processInstanceResult.getVersion())
.setVariables(MsgPackConverter.convertToJson(processInstanceResult.getVariablesBuffer()))
.build();
}
private GeneratedMessageV3 createCancelInstanceResponse() {
return CancelProcessInstanceResponse.newBuilder().build();
}
private GeneratedMessageV3 createModifyProcessInstanceResponse() {
return ModifyProcessInstanceResponse.newBuilder().build();
}
private GeneratedMessageV3 createMigrateProcessInstanceResponse() {
return MigrateProcessInstanceResponse.getDefaultInstance();
}
private GeneratedMessageV3 createBroadcastSignalResponse() {
final SignalRecord signal = new SignalRecord();
signal.wrap(valueBufferView);
return BroadcastSignalResponse.newBuilder().setKey(key).build();
}
private GeneratedMessageV3 createResolveIncidentResponse() {
final IncidentRecord incident = new IncidentRecord();
incident.wrap(valueBufferView);
return ResolveIncidentResponse.newBuilder().build();
}
private GeneratedMessageV3 createSetVariablesResponse() {
final VariableDocumentRecord variableDocumentRecord = new VariableDocumentRecord();
variableDocumentRecord.wrap(valueBufferView);
return SetVariablesResponse.newBuilder().setKey(key).build();
}
private GeneratedMessageV3 createMessageResponse() {
return PublishMessageResponse.newBuilder().setKey(key).build();
}
private GeneratedMessageV3 createJobBatchResponse() {
final JobBatchRecord jobBatch = new JobBatchRecord();
jobBatch.wrap(valueBufferView);
final Map jobsWithKeys = new HashMap<>();
for (int index = 0; index < jobBatch.getJobKeys().size(); index++) {
final Long key = jobBatch.getJobKeys().get(index);
final JobRecord value = (JobRecord) jobBatch.getJobs().get(index);
jobsWithKeys.put(key, value);
}
return ActivateJobsResponse.newBuilder()
.addAllJobs(
jobsWithKeys.entrySet().stream()
.map((entry) -> mapToActivatedJob(entry.getKey(), entry.getValue()))
.collect(Collectors.toList()))
.build();
}
static ActivatedJob mapToActivatedJob(final long key, final JobRecord job) {
return ActivatedJob.newBuilder()
.setKey(key)
.setType(job.getType())
.setRetries(job.getRetries())
.setWorker(job.getWorker())
.setDeadline(job.getDeadline())
.setProcessDefinitionKey(job.getProcessDefinitionKey())
.setBpmnProcessId(job.getBpmnProcessId())
.setProcessDefinitionVersion(job.getProcessDefinitionVersion())
.setProcessInstanceKey(job.getProcessInstanceKey())
.setElementId(job.getElementId())
.setElementInstanceKey(job.getElementInstanceKey())
.setCustomHeaders(MsgPackConverter.convertToJson(job.getCustomHeadersBuffer()))
.setVariables(MsgPackConverter.convertToJson(job.getVariablesBuffer()))
.build();
}
private GeneratedMessageV3 createCompleteJobResponse() {
return CompleteJobResponse.newBuilder().build();
}
private GeneratedMessageV3 createFailJobResponse() {
return FailJobResponse.newBuilder().build();
}
private GeneratedMessageV3 createJobThrowErrorResponse() {
return ThrowErrorResponse.newBuilder().build();
}
private GeneratedMessageV3 createJobUpdateRetriesResponse() {
return UpdateJobRetriesResponse.newBuilder().build();
}
private GeneratedMessageV3 createJobUpdateTimeOutResponse() {
return UpdateJobTimeoutResponse.newBuilder().build();
}
Status createRejectionResponse(
final RejectionType rejectionType, final Intent intent, final String rejectionReason) {
final int statusCode =
switch (rejectionType) {
case INVALID_ARGUMENT -> Code.INVALID_ARGUMENT_VALUE;
case NOT_FOUND -> Code.NOT_FOUND_VALUE;
case ALREADY_EXISTS -> Code.ALREADY_EXISTS_VALUE;
case INVALID_STATE -> Code.FAILED_PRECONDITION_VALUE;
case PROCESSING_ERROR -> Code.INTERNAL_VALUE;
default -> Code.UNKNOWN_VALUE;
};
return Status.newBuilder()
.setMessage(
String.format(
"Command '%s' rejected with code '%s': %s", intent, rejectionType, rejectionReason))
.setCode(statusCode)
.build();
}
}