Skip to content

Commit

Permalink
Merge pull request #16350 from camunda/backport-16342-to-release-8.4.3
Browse files Browse the repository at this point in the history
[Backport release-8.4.3] Forms Linked to User Tasks Are Sometimes Wrong
  • Loading branch information
korthout authored Feb 14, 2024
2 parents 92f84a6 + 3b6ac9c commit bf4f4b7
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ public Optional<PersistedForm> findLatestFormById(
return Optional.empty();
}

formByTenantAndIdCache.put(new TenantIdAndFormId(tenantId, formId), persistedForm);
return Optional.of(persistedForm).map(PersistedForm::copy);
final PersistedForm copiedForm = persistedForm.copy();
formByTenantAndIdCache.put(new TenantIdAndFormId(tenantId, formId), copiedForm);
return Optional.of(copiedForm);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* 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.it.processing;

import static org.assertj.core.api.Assertions.assertThat;

import io.camunda.zeebe.client.ZeebeClient;
import io.camunda.zeebe.client.api.response.DeploymentEvent;
import io.camunda.zeebe.model.bpmn.Bpmn;
import io.camunda.zeebe.protocol.record.intent.JobIntent;
import io.camunda.zeebe.qa.util.actuator.PartitionsActuator;
import io.camunda.zeebe.qa.util.cluster.TestStandaloneBroker;
import io.camunda.zeebe.qa.util.junit.ZeebeIntegration;
import io.camunda.zeebe.qa.util.junit.ZeebeIntegration.TestZeebe;
import io.camunda.zeebe.snapshots.impl.FileBasedSnapshotId;
import io.camunda.zeebe.test.util.junit.AutoCloseResources;
import io.camunda.zeebe.test.util.junit.AutoCloseResources.AutoCloseResource;
import io.camunda.zeebe.test.util.junit.RegressionTest;
import io.camunda.zeebe.test.util.record.RecordingExporter;
import java.time.Duration;
import java.util.Optional;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeEach;

@AutoCloseResources
@ZeebeIntegration
final class FormLinkingIT {

@TestZeebe private final TestStandaloneBroker zeebe = new TestStandaloneBroker();
private final PartitionsActuator partitions = PartitionsActuator.of(zeebe);
@AutoCloseResource private ZeebeClient client;

@BeforeEach
void beforeEach() {
client = zeebe.newClientBuilder().build();
}

@RegressionTest("https://github.com/camunda/zeebe/issues/16311")
public void shouldActivateUserTaskWithCorrectFormKey() {
// given
final DeploymentEvent deployment =
client
.newDeployResourceCommand()
.addProcessModel(
Bpmn.createExecutableProcess("form_linking_test")
.startEvent()
.userTask()
.zeebeFormId("formId1")
.endEvent()
.done(),
"form_linking_test.bpmn")
.addProcessModel(
Bpmn.createExecutableProcess("form_linking_test2")
.startEvent()
.userTask()
.zeebeFormId("formId2")
.endEvent()
.done(),
"form_linking_test2.bpmn")
.addResourceFromClasspath("form/form-linking-test-form-1.form")
.addResourceFromClasspath("form/form-linking-test-form-2.form")
.send()
.join();

final var formKey = deployment.getForm().getFirst().getFormKey();
final var formKey2 = deployment.getForm().getLast().getFormKey();

// take snapshot and start the engine from snapshot
partitions.takeSnapshot();
Awaitility.await("Snapshot is taken")
.atMost(Duration.ofSeconds(60))
.until(
() ->
Optional.ofNullable(partitions.query().get(1).snapshotId())
.flatMap(FileBasedSnapshotId::ofFileName),
Optional::isPresent)
.orElseThrow();
zeebe.stop();

// when
zeebe.withRecordingExporter(true).start().awaitCompleteTopology();

// then

// fills the cache correctly
assertCorrectFormLinkedForProcess("form_linking_test", formKey);

// previously corrupted the cache
assertCorrectFormLinkedForProcess("form_linking_test2", formKey2);

// failed previously because of corrupted cache
assertCorrectFormLinkedForProcess("form_linking_test", formKey);
}

private void assertCorrectFormLinkedForProcess(final String processId, final long formKey) {
final long processInstanceKey =
client
.newCreateInstanceCommand()
.bpmnProcessId(processId)
.latestVersion()
.send()
.join()
.getProcessInstanceKey();
assertThat(
RecordingExporter.jobRecords(JobIntent.CREATED)
.withProcessInstanceKey(processInstanceKey)
.getFirst()
.getValue()
.getCustomHeaders())
.containsValue(String.valueOf(formKey));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"components": [
{
"label": "Text field",
"type": "textfield",
"layout": {
"row": "Row_0hpohpx",
"columns": null
},
"id": "Field_19qoinx",
"key": "textfield_3c2arb"
}
],
"type": "default",
"id": "formId1",
"executionPlatform": "Camunda Cloud",
"executionPlatformVersion": "8.3.0",
"exporter": {
"name": "Camunda Modeler",
"version": "5.17.0"
},
"schemaVersion": 12
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"components": [
{
"values": [
{
"label": "Value",
"value": "value"
}
],
"label": "Radio",
"type": "radio",
"layout": {
"row": "Row_0th2vqr",
"columns": null
},
"id": "Field_1fslkgq",
"key": "radio_8tm2d7"
}
],
"type": "default",
"id": "formId2",
"executionPlatform": "Camunda Cloud",
"executionPlatformVersion": "8.3.0",
"exporter": {
"name": "Camunda Modeler",
"version": "5.17.0"
},
"schemaVersion": 12
}

0 comments on commit bf4f4b7

Please sign in to comment.