Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(client) don't expose executionId to public API #4611

Merged
merged 8 commits into from
Sep 20, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@
import org.camunda.bpm.client.util.RecordingExternalTaskHandler;
import org.camunda.bpm.client.util.RecordingInvocationHandler;
import org.camunda.bpm.client.util.RecordingInvocationHandler.RecordedInvocation;
import org.camunda.bpm.client.variable.impl.value.DeferredFileValueImpl;
import org.camunda.bpm.client.variable.value.DeferredFileValue;
import org.camunda.bpm.engine.variable.Variables;
import org.camunda.bpm.engine.variable.value.FileValue;
import org.camunda.bpm.engine.variable.value.TypedValue;
import org.camunda.bpm.model.bpmn.Bpmn;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;
import org.camunda.commons.utils.IoUtil;
import org.junit.Before;
Expand All @@ -63,6 +65,8 @@ public class FileSerializationIT {
protected static final String VARIABLE_NAME_FILE = "fileVariable";
protected static final String VARIABLE_VALUE_FILE_NAME = "aFileName.txt";
protected static final byte[] VARIABLE_VALUE_FILE_VALUE = "ABC".getBytes();
protected static final String LOCAL_VARIABLE_NAME_FILE = "localFileName.txt";

protected static final String VARIABLE_VALUE_FILE_ENCODING = "UTF-8";
protected static final String VARIABLE_VALUE_FILE_MIME_TYPE = "text/plain";

Expand Down Expand Up @@ -117,6 +121,41 @@ public void shouldGet() {
.isEqualTo(new String(VARIABLE_VALUE_FILE_VALUE));
}

@Test
public void shouldGetLocalAndGlobalVariables() {
// given
ProcessDefinitionDto processDefinitionDto = engineRule.deploy(
Bpmn.createExecutableProcess("process")
.startEvent("startEvent")
.serviceTask("serviceTaskFoo")
.camundaExternalTask(EXTERNAL_TASK_TOPIC_FOO)
// create the local file variable with the same content but different name
.camundaInputParameter(LOCAL_VARIABLE_NAME_FILE, "${execution.getVariableTyped('fileVariable')}")
.serviceTask("serviceTaskBar")
.camundaExternalTask(EXTERNAL_TASK_TOPIC_BAR)
.endEvent("endEvent")
.done()
).get(0);

engineRule.startProcessInstance(processDefinitionDto.getId(), VARIABLE_NAME_FILE, VARIABLE_VALUE_FILE);

// when
client.subscribe(EXTERNAL_TASK_TOPIC_FOO)
.handler(handler)
.open();

clientRule.waitForFetchAndLockUntil(() -> !handler.getHandledTasks().isEmpty());

ExternalTask task = handler.getHandledTasks().get(0);

// then
assertThat(task.getAllVariables().size()).isEqualTo(2);
assertThat(IoUtil.inputStreamAsString(task.getVariable(VARIABLE_NAME_FILE)))
.isEqualTo(new String(VARIABLE_VALUE_FILE_VALUE));
assertThat(IoUtil.inputStreamAsString(task.getVariable(LOCAL_VARIABLE_NAME_FILE)))
.isEqualTo(new String(VARIABLE_VALUE_FILE_VALUE));
}

@Test
public void shouldGetAll() {
// given
Expand Down Expand Up @@ -145,7 +184,9 @@ public void shouldGetAll() {
@Test
public void shouldGetTyped_Deferred() {
// given
engineRule.startProcessInstance(processDefinition.getId(), VARIABLE_NAME_FILE, VARIABLE_VALUE_FILE);
ProcessInstanceDto processInstanceDto = engineRule.startProcessInstance(processDefinition.getId(),
VARIABLE_NAME_FILE,
VARIABLE_VALUE_FILE);

client.subscribe(EXTERNAL_TASK_TOPIC_FOO)
.handler(handler)
Expand All @@ -163,6 +204,48 @@ public void shouldGetTyped_Deferred() {
assertThat(typedValue.isLoaded()).isFalse();
assertThat(typedValue.getEncoding()).isNull();
assertThat(typedValue.getMimeType()).isNull();

DeferredFileValueImpl typedValueImpl = (DeferredFileValueImpl) typedValue;
assertThat(typedValueImpl.getExecutionId()).isEqualTo(task.getExecutionId());
}

@Test
public void shouldGetVariableTypedForLocalVariable() {
// given
ProcessDefinitionDto processDefinitionDto = engineRule.deploy(
Bpmn.createExecutableProcess("process")
.startEvent("startEvent")
.serviceTask("serviceTaskFoo")
.camundaExternalTask(EXTERNAL_TASK_TOPIC_FOO)
// create the local file variable with the same content but different name
.camundaInputParameter(LOCAL_VARIABLE_NAME_FILE, "${execution.getVariableTyped('fileVariable')}")
.serviceTask("serviceTaskBar")
.camundaExternalTask(EXTERNAL_TASK_TOPIC_BAR)
.endEvent("endEvent")
.done()
).get(0);

ProcessInstanceDto processInstanceDto = engineRule.startProcessInstance(processDefinitionDto.getId(), VARIABLE_NAME_FILE, VARIABLE_VALUE_FILE);

// when
client.subscribe(EXTERNAL_TASK_TOPIC_FOO)
.handler(handler)
.open();

clientRule.waitForFetchAndLockUntil(() -> !handler.getHandledTasks().isEmpty());

ExternalTask task = handler.getHandledTasks().get(0);

// then
DeferredFileValue typedValue = task.getVariableTyped(LOCAL_VARIABLE_NAME_FILE);
assertThat(typedValue.getFilename()).isEqualTo(VARIABLE_VALUE_FILE_NAME);
assertThat(typedValue.getType()).isEqualTo(FILE);
assertThat(typedValue.isLoaded()).isFalse();
assertThat(typedValue.getEncoding()).isNull();
assertThat(typedValue.getMimeType()).isNull();

DeferredFileValueImpl typedValueImpl = (DeferredFileValueImpl) typedValue;
assertThat(typedValueImpl.getExecutionId()).isEqualTo(task.getExecutionId());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 Let's keep using a white box test approach to a minimum. A black box should be the way to go.
We can fall back on white box tests only when a black box test is too difficult to achieve.

}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.camunda.bpm.client.task.ExternalTask;
import org.camunda.bpm.client.variable.impl.TypedValueField;
import org.camunda.bpm.client.variable.impl.VariableValue;
import org.camunda.bpm.client.variable.impl.value.DeferredFileValueImpl;
import org.camunda.bpm.client.variable.value.DeferredFileValue;
import org.camunda.bpm.engine.variable.VariableMap;
import org.camunda.bpm.engine.variable.Variables;
Expand Down Expand Up @@ -258,8 +259,8 @@ public <T> T getVariable(String variableName) {

VariableValue variableValue = receivedVariableMap.get(variableName);
if (variableValue != null) {
if(variableValue.getTypedValue() instanceof DeferredFileValue) {
DeferredFileValue deferredFileValue = (DeferredFileValue) variableValue.getTypedValue();
if(variableValue.getTypedValue() instanceof DeferredFileValueImpl) {
DeferredFileValueImpl deferredFileValue = (DeferredFileValueImpl) variableValue.getTypedValue();
deferredFileValue.setExecutionId(this.executionId);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Can't we get rid of this code now that we pass the execution id to VariableValue?

value = (T) variableValue.getValue();
Expand Down Expand Up @@ -300,8 +301,8 @@ public <T extends TypedValue> T getVariableTyped(String variableName, boolean de
VariableValue variableValue = receivedVariableMap.get(variableName);
if (variableValue != null) {
typedValue = variableValue.getTypedValue(deserializeObjectValues);
if(typedValue instanceof DeferredFileValue) {
DeferredFileValue deferredFileValue = (DeferredFileValue) typedValue;
if(typedValue instanceof DeferredFileValueImpl) {
DeferredFileValueImpl deferredFileValue = (DeferredFileValueImpl) typedValue;
deferredFileValue.setExecutionId(this.executionId);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Can't we get rid of this code now that we pass the execution id to VariableValue?

Copy link
Member Author

@venetrius venetrius Sep 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me check.

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public Map<String, TypedValueField> serializeVariables(Map<String, Object> varia

@SuppressWarnings("rawtypes")
public Map<String, VariableValue> wrapVariables(ExternalTask externalTask, Map<String, TypedValueField> variables) {
String processInstanceId = externalTask.getProcessInstanceId();
String executionId = externalTask.getExecutionId();

Map<String, VariableValue> result = new HashMap<>();

Expand All @@ -80,7 +80,7 @@ public Map<String, VariableValue> wrapVariables(ExternalTask externalTask, Map<S
typeName = Character.toLowerCase(typeName.charAt(0)) + typeName.substring(1);
variableValue.setType(typeName);

VariableValue value = new VariableValue(processInstanceId, variableName, variableValue, serializers);
VariableValue value = new VariableValue(executionId, variableName, variableValue, serializers);
result.put(variableName, value);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@

public class VariableValue<T extends TypedValue> {

protected String processInstanceId;
protected String executionId;
protected String variableName;
protected TypedValueField typedValueField;
protected ValueMappers mappers;

protected ValueMapper<T> serializer;
protected T cachedValue;

public VariableValue(String processInstanceId, String variableName, TypedValueField typedValueField, ValueMappers mappers) {
this.processInstanceId = processInstanceId;
public VariableValue(String executionId, String variableName, TypedValueField typedValueField, ValueMappers mappers) {
this.executionId = executionId;
this.variableName = variableName;
this.typedValueField = typedValueField;
this.mappers = mappers;
Expand Down Expand Up @@ -63,7 +63,7 @@ public T getTypedValue(boolean deserializeValue) {

if (cachedValue instanceof DeferredFileValueImpl) {
DeferredFileValueImpl fileValue = (DeferredFileValueImpl) cachedValue;
fileValue.setProcessInstanceId(processInstanceId);
fileValue.setExecutionId(executionId);
fileValue.setVariableName(variableName);
}
}
Expand All @@ -83,7 +83,7 @@ public ValueMapper<T> getSerializer() {
public String toString() {
return "VariableValue ["
+ "cachedValue=" + cachedValue + ", "
+ "processInstanceId=" + processInstanceId + ", "
+ "executionId=" + executionId + ", "
+ "variableName=" + variableName + ", "
+ "typedValueField=" + typedValueField + "]";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,28 +72,22 @@ public InputStream getValue() {
return super.getValue();
}

public void setProcessInstanceId(String processInstanceId) {
this.processInstanceId = processInstanceId;
}

public void setVariableName(String variableName) {
this.variableName = variableName;
}

@Override
public void setExecutionId(String executionId){
this.executionId = executionId;
};

@Override
public String getExecutionId() {
return executionId;
}

@Override
public String toString() {
return "DeferredFileValueImpl [mimeType=" + mimeType + ", filename=" + filename + ", type=" + type + ", "
+ "isTransient=" + isTransient + ", isLoaded=" + isLoaded + ", processInstanceId" + processInstanceId + ", executionId" + executionId + "]";
+ "isTransient=" + isTransient + ", isLoaded=" + isLoaded + "]";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,4 @@ public interface DeferredFileValue extends FileValue {
*/
boolean isLoaded();

/**
* Sets the executionId, which defines the scope of the DeferredFileValue.
* This identifier ensures that the correct scope is applied when loading the file value.
*
* @param executionId defines the scope of the DeferredFileValue
*/
void setExecutionId(String executionId);

/**
* Returns the executionId, which specifies the scope of the DeferredFileValue.
* This identifier ensures that the correct scope is applied when loading the file value.
*
* @return the executionId which defines the scope of the DeferredFileValue
*/
String getExecutionId();

}
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ public void shouldDisplayAttributesIncludingMapsInToString() {
task.setWorkerId("wi");

Map<String, VariableValue> receivedVariables = new LinkedHashMap<>();
receivedVariables.put("rv1", generateVariableValue("pii", "variable1", ValueType.STRING.getName(), "value1", 42, "vi2"));
receivedVariables.put("rv2", generateVariableValue("pii", "variable2", ValueType.INTEGER.getName(), 99, 42, "vi2", 87L));
receivedVariables.put("rv1", generateVariableValue(task.getExecutionId(), "variable1", ValueType.STRING.getName(), "value1", 42, "vi2"));
receivedVariables.put("rv2", generateVariableValue(task.getExecutionId(), "variable2", ValueType.INTEGER.getName(), 99, 42, "vi2", 87L));
task.setReceivedVariableMap(receivedVariables);

Map<String, TypedValueField> variables = new LinkedHashMap<>();
Expand All @@ -163,9 +163,9 @@ public void shouldDisplayAttributesIncludingMapsInToString() {
+ "processDefinitionVersionTag=versionTag, "
+ "processInstanceId=pii, "
+ "receivedVariableMap={"
+ "rv1=VariableValue [cachedValue=null, processInstanceId=pii, variableName=variable1, typedValueField="
+ "rv1=VariableValue [cachedValue=null, executionId=ei, variableName=variable1, typedValueField="
+ "TypedValueField [type=string, value=value1, valueInfo={vi1=42, vi2=vi2}]], "
+ "rv2=VariableValue [cachedValue=null, processInstanceId=pii, variableName=variable2, typedValueField="
+ "rv2=VariableValue [cachedValue=null, executionId=ei, variableName=variable2, typedValueField="
+ "TypedValueField [type=integer, value=99, valueInfo={vi1=42, vi2=vi2, vi3=87}]]"
+ "}, "
+ "retries=34, "
Expand All @@ -184,10 +184,10 @@ public void shouldDisplayAttributesIncludingMapsInToString() {
private static final ValueMappers DEFAULT_MAPPERS = new DefaultValueMappers(Variables.SerializationDataFormats.JSON.getName());

@SuppressWarnings("rawtypes")
private static VariableValue generateVariableValue(String processInstanceId, String variableName,
private static VariableValue generateVariableValue(String executionId, String variableName,
final String typeI, final Object valueI, Object... valueInfos) {
TypedValueField typedValueField = generateTypedValueField(typeI, valueI, valueInfos);
return new VariableValue(processInstanceId, variableName, typedValueField, DEFAULT_MAPPERS);
return new VariableValue(executionId, variableName, typedValueField, DEFAULT_MAPPERS);
}

private static TypedValueField generateTypedValueField(final String typeI, final Object valueI, Object... valueInfos) {
Expand Down