Skip to content

Commit

Permalink
merge: #9475
Browse files Browse the repository at this point in the history
9475: [Backport stable/8.0] Increase DRG version if another DRG was deployed with the same decisions r=saig0 a=backport-action

# Description
Backport of #9466 to `stable/8.0`.

relates to #9272

Co-authored-by: Philipp Ossler <philipp.ossler@gmail.com>
  • Loading branch information
zeebe-bors-camunda[bot] and saig0 committed Jun 1, 2022
2 parents 21fbfa2 + b46efcb commit 37cc931
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import io.camunda.zeebe.engine.processing.common.Failure;
import io.camunda.zeebe.engine.processing.streamprocessor.writers.StateWriter;
import io.camunda.zeebe.engine.state.KeyGenerator;
import io.camunda.zeebe.engine.state.deployment.PersistedDecision;
import io.camunda.zeebe.engine.state.deployment.PersistedDecisionRequirements;
import io.camunda.zeebe.engine.state.immutable.DecisionState;
import io.camunda.zeebe.protocol.impl.record.value.deployment.DecisionRecord;
Expand All @@ -28,7 +29,9 @@
import io.camunda.zeebe.protocol.record.intent.DecisionRequirementsIntent;
import io.camunda.zeebe.protocol.record.value.deployment.DecisionRequirementsMetadataValue;
import io.camunda.zeebe.util.Either;
import io.camunda.zeebe.util.buffer.BufferUtil;
import java.io.ByteArrayInputStream;
import java.util.Collection;
import java.util.function.Function;
import java.util.function.LongSupplier;
import java.util.stream.Collectors;
Expand All @@ -38,6 +41,8 @@ public final class DmnResourceTransformer implements DeploymentResourceTransform

private static final int INITIAL_VERSION = 1;

private static final long UNKNOWN_DECISION_REQUIREMENTS_KEY = -1L;

private static final Either<Failure, Object> NO_DUPLICATES = Either.right(null);

private final DecisionEngine decisionEngine = DecisionEngineFactory.createDecisionEngine();
Expand Down Expand Up @@ -170,7 +175,11 @@ private long appendMetadataToDeploymentEvent(
.ifPresentOrElse(
latestDrg -> {
final int latestVersion = latestDrg.getDecisionRequirementsVersion();
final boolean isDuplicate = isDuplicate(resource, checksum, latestDrg);
final boolean isDuplicate =
hasSameResourceNameAs(resource, latestDrg)
&& hasSameChecksumAs(checksum, latestDrg)
&& hasSameDecisionRequirementsKeyAs(parsedDrg.getDecisions(), latestDrg);

if (isDuplicate) {
drgRecord
.setDecisionRequirementsKey(latestDrg.getDecisionRequirementsKey())
Expand Down Expand Up @@ -228,13 +237,28 @@ private long appendMetadataToDeploymentEvent(
return drgRecord.getDecisionRequirementsKey();
}

private boolean isDuplicate(
final DeploymentResource resource,
final DirectBuffer checksum,
final PersistedDecisionRequirements drg) {
private boolean hasSameResourceNameAs(
final DeploymentResource resource, final PersistedDecisionRequirements drg) {
return drg.getResourceName().equals(resource.getResourceNameBuffer());
}

return drg.getResourceName().equals(resource.getResourceNameBuffer())
&& drg.getChecksum().equals(checksum);
private boolean hasSameChecksumAs(
final DirectBuffer checksum, final PersistedDecisionRequirements drg) {
return drg.getChecksum().equals(checksum);
}

private boolean hasSameDecisionRequirementsKeyAs(
final Collection<ParsedDecision> decisions, final PersistedDecisionRequirements drg) {
return decisions.stream()
.map(ParsedDecision::getId)
.map(BufferUtil::wrapString)
.map(
decisionId ->
decisionState
.findLatestDecisionById(decisionId)
.map(PersistedDecision::getDecisionRequirementsKey)
.orElse(UNKNOWN_DECISION_REQUIREMENTS_KEY))
.allMatch(drgKey -> drgKey == drg.getDecisionRequirementsKey());
}

private void writeRecords(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ public final class BusinessRuleTaskTest {
private static final String DMN_RESOURCE = "/dmn/drg-force-user.dmn";
private static final String DMN_RESOURCE_WITH_NAMELESS_OUTPUTS =
"/dmn/drg-force-user-nameless-input-outputs.dmn";

private static final String DMN_DECISION_TABLE = "/dmn/decision-table.dmn";
private static final String DMN_DECISION_TABLE_RENAMED_DRG =
"/dmn/decision-table-with-renamed-drg.dmn";
private static final String PROCESS_ID = "process";
private static final String TASK_ID = "task";
private static final String RESULT_VARIABLE = "result";
Expand Down Expand Up @@ -511,4 +515,59 @@ public void shouldWriteDecisionEvaluationEventIfInputOutputNamesAreNull() {
.describedAs("Expect that evaluated output's name is empty string")
.containsOnly("");
}

/**
* Regression test for https://github.com/camunda/zeebe/issues/9272. An exception occurred if two
* DRGs were deployed with a different id but the same decision id.
*/
@Test
public void shouldEvaluateDecisionIfMultipleDrgsWithSameDecisionId() {
// given
ENGINE.deployment().withXmlClasspathResource(DMN_DECISION_TABLE).deploy();

ENGINE.deployment().withXmlClasspathResource(DMN_DECISION_TABLE_RENAMED_DRG).deploy();

final var deploymentCreated =
ENGINE
.deployment()
.withXmlClasspathResource(DMN_DECISION_TABLE)
.withXmlResource(
processWithBusinessRuleTask(
t ->
t.zeebeCalledDecisionId("jedi_or_sith")
.zeebeResultVariable(RESULT_VARIABLE)))
.deploy();

final var lastDeployment = deploymentCreated.getValue();
final var lastDeployedDecisionRequirements =
lastDeployment.getDecisionRequirementsMetadata().get(0);
final var lastDeployedDecision = lastDeployment.getDecisionsMetadata().get(0);

// when
final long processInstanceKey =
ENGINE
.processInstance()
.ofBpmnProcessId(PROCESS_ID)
.withVariables(Map.ofEntries(entry("lightsaberColor", "blue")))
.create();

// then
assertThat(
RecordingExporter.processInstanceRecords()
.withProcessInstanceKey(processInstanceKey)
.limitToProcessInstanceCompleted()
.withElementType(BpmnElementType.BUSINESS_RULE_TASK))
.describedAs("expected the business rule task to be completed")
.extracting(Record::getIntent)
.contains(ProcessInstanceIntent.ELEMENT_COMPLETED);

final var decisionEvaluationRecord =
RecordingExporter.decisionEvaluationRecords()
.withProcessInstanceKey(processInstanceKey)
.getFirst();

assertThat(decisionEvaluationRecord.getValue())
.hasDecisionKey(lastDeployedDecision.getDecisionKey())
.hasDecisionRequirementsKey(lastDeployedDecisionRequirements.getDecisionRequirementsKey());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,8 @@ public void shouldDeployDecisionWithTwoDrg() {
.extracting(
DecisionRequirementsMetadataValue::getDecisionRequirementsVersion,
DecisionRequirementsMetadataValue::isDuplicate)
.describedAs("Expect that the DRG is a duplicate")
.containsOnly(tuple(1, true));
.describedAs("Expect that the DRG version is increased")
.containsOnly(tuple(2, false));

assertThat(deploymentEvent.getValue().getDecisionsMetadata())
.extracting(DecisionRecordValue::getVersion, DecisionRecordValue::isDuplicate)
Expand Down

0 comments on commit 37cc931

Please sign in to comment.