org.camunda.bpm.engine.variable.value.TypedValue Java Examples

The following examples show how to use org.camunda.bpm.engine.variable.value.TypedValue. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: GetCaseExecutionVariableTypedCmd.java    From camunda-bpm-platform with Apache License 2.0 6 votes vote down vote up
public TypedValue execute(CommandContext commandContext) {
  ensureNotNull("caseExecutionId", caseExecutionId);
  ensureNotNull("variableName", variableName);

  CaseExecutionEntity caseExecution = commandContext
    .getCaseExecutionManager()
    .findCaseExecutionById(caseExecutionId);

  ensureNotNull(CaseExecutionNotFoundException.class, "case execution " + caseExecutionId + " doesn't exist", "caseExecution", caseExecution);

  for(CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) {
    checker.checkReadCaseInstance(caseExecution);
  }

  TypedValue value;

  if (isLocal) {
    value = caseExecution.getVariableLocalTyped(variableName, deserializeValue);
  } else {
    value = caseExecution.getVariableTyped(variableName, deserializeValue);
  }

  return value;
}
 
Example #2
Source File: PrimitiveVariableIT.java    From camunda-external-task-client-java with Apache License 2.0 6 votes vote down vote up
@Test
public void shoudGetVariableTyped_NullString() {
  // given
  engineRule.startProcessInstance(processDefinition.getId(), VARIABLE_NAME, Variables.stringValue(null));

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

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

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

  TypedValue typedValue = task.getVariableTyped(VARIABLE_NAME);
  assertThat(typedValue.getValue()).isNull();
  assertThat(typedValue.getType()).isEqualTo(STRING);
}
 
Example #3
Source File: VariableContextElResolver.java    From camunda-bpm-platform with Apache License 2.0 6 votes vote down vote up
@Override
public Object getValue(ELContext context, Object base, Object property) {
  if (base == null) {
    VariableContext variableContext = (VariableContext) context.getContext(VariableContext.class);
    if(variableContext != null) {
      if(VARIABLE_CONTEXT_KEY.equals(property)) {
        context.setPropertyResolved(true);
        return variableContext;
      }
      TypedValue typedValue = variableContext.resolve((String) property);
      if(typedValue != null) {
        context.setPropertyResolved(true);
        return unpack(typedValue);
      }
    }
  }
  return null;
}
 
Example #4
Source File: CreateProcessInstanceWithJsonVariablesTest.java    From camunda-bpm-platform with Apache License 2.0 6 votes vote down vote up
@ScenarioUnderTest("initProcessInstance.1")
@Test
public void testCreateProcessInstanceWithVariable() {
  // then
  ProcessInstance processInstance = engineRule.getRuntimeService().createProcessInstanceQuery().processInstanceBusinessKey("processWithJsonVariables79").singleResult();
  List<VariableInstance> variables = engineRule.getRuntimeService().createVariableInstanceQuery().processInstanceIdIn(processInstance.getId()).list();
  assertEquals(4, variables.size());

  final Object objectVariable = engineRule.getRuntimeService().getVariable(processInstance.getId(), "objectVariable");
  assertObjectVariable(objectVariable);

  final Object plainTypeArrayVariable = engineRule.getRuntimeService().getVariable(processInstance.getId(), "plainTypeArrayVariable");
  assertPlainTypeArrayVariable(plainTypeArrayVariable);

  final Object notGenericObjectListVariable = engineRule.getRuntimeService().getVariable(processInstance.getId(), "notGenericObjectListVariable");
  assertNotGenericObjectListVariable(notGenericObjectListVariable);

  final TypedValue serializedObject = engineRule.getRuntimeService().getVariableTyped(processInstance.getId(), "serializedMapVariable", true);
  assertSerializedMap(serializedObject);
}
 
Example #5
Source File: DateFormType.java    From camunda-bpm-platform with Apache License 2.0 6 votes vote down vote up
public TypedValue convertToModelValue(TypedValue propertyValue) {
  Object value = propertyValue.getValue();
  if(value == null) {
    return Variables.dateValue(null, propertyValue.isTransient());
  }
  else if(value instanceof Date) {
    return Variables.dateValue((Date) value, propertyValue.isTransient());
  }
  else if(value instanceof String) {
    String strValue = ((String) value).trim();
    if (strValue.isEmpty()) {
      return Variables.dateValue(null, propertyValue.isTransient());
    }
    try {
      return Variables.dateValue((Date) dateFormat.parseObject(strValue), propertyValue.isTransient());
    } catch (ParseException e) {
      throw new ProcessEngineException("Could not parse value '"+value+"' as date using date format '"+datePattern+"'.");
    }
  }
  else {
    throw new ProcessEngineException("Value '"+value+"' cannot be transformed into a Date.");
  }
}
 
Example #6
Source File: Variables.java    From camunda-bpm-platform with Apache License 2.0 6 votes vote down vote up
/**
 * Creates an untyped value, i.e. {@link TypedValue#getType()} returns <code>null</code>
 * for the returned instance.
 */
public static TypedValue untypedValue(Object value, boolean isTransient) {
  if(value == null) {
    return untypedNullValue(isTransient);
  } else if (value instanceof TypedValueBuilder<?>) {
    return ((TypedValueBuilder<?>) value).setTransient(isTransient).create();
  } else if (value instanceof TypedValue) {
    TypedValue transientValue = (TypedValue) value;
    if (value instanceof NullValueImpl) {
      transientValue = untypedNullValue(isTransient);
    } else if (value instanceof FileValue) {
      ((FileValueImpl) transientValue).setTransient(isTransient);
    } else if (value instanceof AbstractTypedValue<?>) {
      ((AbstractTypedValue<?>) transientValue).setTransient(isTransient);
    }
    return transientValue;
  }
  else {
    // unknown value
    return new UntypedValueImpl(value, isTransient);
  }
}
 
Example #7
Source File: PrimitiveVariableIT.java    From camunda-external-task-client-java with Apache License 2.0 6 votes vote down vote up
@Test
public void shoudGetVariableTyped_NullBytes() {
  // given
  engineRule.startProcessInstance(processDefinition.getId(), VARIABLE_NAME, Variables.byteArrayValue(null));

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

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

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

  TypedValue typedValue = task.getVariableTyped(VARIABLE_NAME);
  assertThat(typedValue.getValue()).isNull();
  assertThat(typedValue.getType()).isEqualTo(BYTES);
}
 
Example #8
Source File: PrimitiveVariableIT.java    From camunda-external-task-client-java with Apache License 2.0 6 votes vote down vote up
@Test
public void shoudGetVariableTyped_NullInteger() {
  // given
  engineRule.startProcessInstance(processDefinition.getId(), VARIABLE_NAME, Variables.integerValue(null));

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

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

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

  TypedValue typedValue = task.getVariableTyped(VARIABLE_NAME);
  assertThat(typedValue.getValue()).isNull();
  assertThat(typedValue.getType()).isEqualTo(INTEGER);
}
 
Example #9
Source File: DecisionTableEvaluationHandler.java    From camunda-engine-dmn with Apache License 2.0 6 votes vote down vote up
protected Map<String, DmnEvaluatedOutput> evaluateOutputEntries(List<DmnDecisionTableOutputImpl> decisionTableOutputs, DmnDecisionTableRuleImpl matchingRule, VariableContext variableContext) {
  Map<String, DmnEvaluatedOutput> outputEntries = new LinkedHashMap<String, DmnEvaluatedOutput>();

  for (int outputIdx = 0; outputIdx < decisionTableOutputs.size(); outputIdx++) {
    // evaluate output entry, skip empty expressions
    DmnExpressionImpl conclusion = matchingRule.getConclusions().get(outputIdx);
    if (isNonEmptyExpression(conclusion)) {
      Object value = evaluateOutputEntry(conclusion, variableContext);

      // transform to output type
      DmnDecisionTableOutputImpl decisionTableOutput = decisionTableOutputs.get(outputIdx);
      TypedValue typedValue = decisionTableOutput.getTypeDefinition().transform(value);

      // set on result
      DmnEvaluatedOutputImpl evaluatedOutput = new DmnEvaluatedOutputImpl(decisionTableOutput, typedValue);
      outputEntries.put(decisionTableOutput.getOutputName(), evaluatedOutput);
    }
  }

  return outputEntries;
}
 
Example #10
Source File: DmnDataTypeTransformerTest.java    From camunda-engine-dmn with Apache License 2.0 5 votes vote down vote up
@Test
public void booleanType() {
  DmnDataTypeTransformer typeTransformer = registry.getTransformer("boolean");

  assertThat(typeTransformer.transform(true), is((TypedValue) Variables.booleanValue(true)));
  assertThat(typeTransformer.transform(false), is((TypedValue) Variables.booleanValue(false)));

  assertThat(typeTransformer.transform("true"), is((TypedValue) Variables.booleanValue(true)));
  assertThat(typeTransformer.transform("false"), is((TypedValue) Variables.booleanValue(false)));
}
 
Example #11
Source File: DmnTypeDefinitionImpl.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
protected TypedValue transformNotNullValue(Object value) {
  ensureNotNull("transformer", transformer);

  try {

    return transformer.transform(value);

  } catch (IllegalArgumentException e) {
    throw LOG.invalidValueForTypeDefinition(typeName, value);
  }
}
 
Example #12
Source File: AbstractCollectNumberHitPolicyHandler.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
protected List<TypedValue> collectSingleValues(DmnDecisionTableEvaluationEvent decisionTableEvaluationEvent) {
  List<TypedValue> values = new ArrayList<TypedValue>();
  for (DmnEvaluatedDecisionRule matchingRule : decisionTableEvaluationEvent.getMatchingRules()) {
    Map<String, DmnEvaluatedOutput> outputEntries = matchingRule.getOutputEntries();
    if (outputEntries.size() > 1) {
      throw LOG.aggregationNotApplicableOnCompoundOutput(getAggregator(), outputEntries);
    }
    else if (outputEntries.size() == 1) {
      TypedValue typedValue = outputEntries.values().iterator().next().getValue();
      values.add(typedValue);
    }
    // ignore empty output entries
  }
  return values;
}
 
Example #13
Source File: ContextVariableWrapper.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
public Option getVariable(String name) {
  if (context.containsVariable(name)) {
    TypedValue typedValue = context.resolve(name);
    Object value = typedValue.getValue();
    return new Some(value);

  } else {
    return scala.None$.MODULE$;

  }
}
 
Example #14
Source File: CallActivityTest.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
/**
 * Test case for handing over process variables to a sub process via the typed
 * api and passing only certain variables
 */
@Deployment(resources = {
  "org/camunda/bpm/engine/test/bpmn/callactivity/CallActivity.testSubProcessLimitedDataInputOutputTypedApi.bpmn20.xml",
  "org/camunda/bpm/engine/test/bpmn/callactivity/simpleSubProcess.bpmn20.xml"})
public void testSubProcessWithLimitedDataInputOutputTypedApi() {

  TypedValue superVariable = Variables.stringValue(null);
  VariableMap vars = Variables.createVariables();
  vars.putValueTyped("superVariable", superVariable);

  ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("subProcessDataInputOutput", vars);

  // one task in the subprocess should be active after starting the process instance
  TaskQuery taskQuery = taskService.createTaskQuery();
  Task taskInSubProcess = taskQuery.singleResult();
  assertThat(taskInSubProcess.getName(), is("Task in subprocess"));
  assertThat(runtimeService.getVariableTyped(taskInSubProcess.getProcessInstanceId(), "subVariable"), is(superVariable));
  assertThat(taskService.getVariableTyped(taskInSubProcess.getId(), "subVariable"), is(superVariable));

  TypedValue subVariable = Variables.stringValue(null);
  runtimeService.setVariable(taskInSubProcess.getProcessInstanceId(), "subVariable", subVariable);

  // super variable is unchanged
  assertThat(runtimeService.getVariableTyped(processInstance.getId(), "superVariable"), is(superVariable));

  // Completing this task ends the subprocess which leads to a task in the super process
  taskService.complete(taskInSubProcess.getId());

  Task taskAfterSubProcess = taskQuery.singleResult();
  assertThat(taskAfterSubProcess.getName(), is("Task in super process"));
  assertThat(runtimeService.getVariableTyped(processInstance.getId(), "superVariable"), is(subVariable));
  assertThat(taskService.getVariableTyped(taskAfterSubProcess.getId(), "superVariable"), is(subVariable));

  // Completing this task ends the super process which leads to a task in the super process
  taskService.complete(taskAfterSubProcess.getId());

  assertProcessEnded(processInstance.getId());
  assertEquals(0, runtimeService.createExecutionQuery().list().size());
}
 
Example #15
Source File: SpinValueTypeImpl.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
public Map<String, Object> getValueInfo(TypedValue typedValue) {
  if(!(typedValue instanceof SpinValue)) {
    throw new IllegalArgumentException("Value not of type Spin Value.");
  }
  SpinValue spinValue = (SpinValue) typedValue;

  Map<String, Object> valueInfo = new HashMap<String, Object>();

  if (spinValue.isTransient()) {
    valueInfo.put(VALUE_INFO_TRANSIENT, spinValue.isTransient());
  }

  return valueInfo;
}
 
Example #16
Source File: DmnDataTypeTransformerTest.java    From camunda-engine-dmn with Apache License 2.0 5 votes vote down vote up
@Test
public void stringType() {
  DmnDataTypeTransformer typeTransformer = registry.getTransformer("string");

  assertThat(typeTransformer.transform("abc"), is((TypedValue) Variables.stringValue("abc")));
  assertThat(typeTransformer.transform(true), is((TypedValue) Variables.stringValue("true")));
  assertThat(typeTransformer.transform(4), is((TypedValue) Variables.stringValue("4")));
  assertThat(typeTransformer.transform(2L), is((TypedValue) Variables.stringValue("2")));
  assertThat(typeTransformer.transform(4.2), is((TypedValue) Variables.stringValue("4.2")));
}
 
Example #17
Source File: DefaultContextAssociationManager.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
@Override
public TypedValue getVariable(String variableName) {
  ExecutionEntity execution = getExecutionFromContext();
  if (execution != null) {
    return execution.getVariableTyped(variableName);
  } else {
    return getScopedAssociation().getVariable(variableName);
  }
}
 
Example #18
Source File: DefaultDmnHistoryEventProducer.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
protected Double getCollectResultValue(TypedValue collectResultValue) {
  // the built-in collect aggregators return only numbers
  if(collectResultValue instanceof IntegerValue) {
    return ((IntegerValue) collectResultValue).getValue().doubleValue();

  } else if(collectResultValue instanceof LongValue) {
    return ((LongValue) collectResultValue).getValue().doubleValue();

  } else if(collectResultValue instanceof DoubleValue) {
    return ((DoubleValue) collectResultValue).getValue();

  } else {
    throw LOG.collectResultValueOfUnsupportedTypeException(collectResultValue);
  }
}
 
Example #19
Source File: Variables.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a {@link TypedValue} with value {@code null} and type {@link ValueType#NULL}
 */
public static TypedValue untypedNullValue(boolean isTransient) {
  if (isTransient) {
    return NullValueImpl.INSTANCE_TRANSIENT;
  }
  else {
    return NullValueImpl.INSTANCE;
  }
}
 
Example #20
Source File: PrimitiveVariableIT.java    From camunda-external-task-client-java with Apache License 2.0 5 votes vote down vote up
@Test
public void shoudSetVariableUntyped_Date() {
  // given
  engineRule.startProcessInstance(processDefinition.getId());

  client.subscribe(EXTERNAL_TASK_TOPIC_FOO)
    .handler(invocationHandler)
    .open();

  clientRule.waitForFetchAndLockUntil(() -> !invocationHandler.getInvocations().isEmpty());

  RecordedInvocation invocation = invocationHandler.getInvocations().get(0);
  ExternalTask fooTask = invocation.getExternalTask();
  ExternalTaskService fooService = invocation.getExternalTaskService();

  client.subscribe(EXTERNAL_TASK_TOPIC_BAR)
    .handler(handler)
    .open();

  // when
  Map<String, Object> variables = Variables.createVariables();
  variables.put(VARIABLE_NAME, Variables.untypedValue(VARIABLE_VALUE_DATE));
  fooService.complete(fooTask, variables);

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

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

  Date variableValue = task.getVariable(VARIABLE_NAME);
  assertThat(variableValue).isEqualTo(VARIABLE_VALUE_DATE);

  TypedValue typedValue = task.getVariableTyped(VARIABLE_NAME);
  assertThat(typedValue.getValue()).isEqualTo(VARIABLE_VALUE_DATE);
  assertThat(typedValue.getType()).isEqualTo(DATE);
}
 
Example #21
Source File: CompositeVariableContext.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
public TypedValue resolve(String variableName) {
  for (VariableContext variableContext : delegateContexts) {
    TypedValue resolvedValue = variableContext.resolve(variableName);
    if(resolvedValue != null) {
      return resolvedValue;
    }
  }

  return null;
}
 
Example #22
Source File: ProcessVariables.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
/**
 * @since 7.3
 */
@Produces
@ProcessVariableTyped
protected TypedValue getProcessVariableTyped(InjectionPoint ip) {
  String processVariableName = getVariableTypedName(ip);

  if (logger.isLoggable(Level.FINE)) {
    logger.fine("Getting typed process variable '" + processVariableName + "' from ProcessInstance[" + businessProcess.getProcessInstanceId() + "].");
  }

  return businessProcess.getVariableTyped(processVariableName);
}
 
Example #23
Source File: CallActivityTest.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
@Override
public void execute(DelegateExecution execution) throws Exception {
  TypedValue typedValue = execution.getVariableTyped("var");
  assertThat(typedValue).isNotNull();
  assertThat(typedValue.getType()).isEqualTo(ValueType.STRING);
  assertThat(typedValue.isTransient()).isTrue();
  assertThat(typedValue.getValue()).isEqualTo("value");
}
 
Example #24
Source File: VariableMapImpl.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
public Object get(Object key) {
  TypedValue typedValue = variables.get(key);

  if(typedValue != null) {
    return typedValue.getValue();
  }
  else {
    return null;
  }
}
 
Example #25
Source File: PrimitiveVariableIT.java    From camunda-external-task-client-java with Apache License 2.0 5 votes vote down vote up
@Test
public void shoudSetVariableUntyped_Short() {
  // given
  engineRule.startProcessInstance(processDefinition.getId());

  client.subscribe(EXTERNAL_TASK_TOPIC_FOO)
    .handler(invocationHandler)
    .open();

  clientRule.waitForFetchAndLockUntil(() -> !invocationHandler.getInvocations().isEmpty());

  RecordedInvocation invocation = invocationHandler.getInvocations().get(0);
  ExternalTask fooTask = invocation.getExternalTask();
  ExternalTaskService fooService = invocation.getExternalTaskService();

  client.subscribe(EXTERNAL_TASK_TOPIC_BAR)
    .handler(handler)
    .open();

  // when
  Map<String, Object> variables = Variables.createVariables();
  variables.put(VARIABLE_NAME, Variables.untypedValue(VARIABLE_VALUE_SHORT));
  fooService.complete(fooTask, variables);

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

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

  short variableValue = task.getVariable(VARIABLE_NAME);
  assertThat(variableValue).isEqualTo(VARIABLE_VALUE_SHORT);

  TypedValue typedValue = task.getVariableTyped(VARIABLE_NAME);
  assertThat(typedValue.getValue()).isEqualTo(VARIABLE_VALUE_SHORT);
  assertThat(typedValue.getType()).isEqualTo(SHORT);
}
 
Example #26
Source File: FeelTypedVariableMapper.java    From camunda-engine-dmn with Apache License 2.0 5 votes vote down vote up
public Object unpackVariable(String variable) {
  TypedValue valueTyped = variableContext.resolve(variable);
  if(valueTyped != null) {
    return valueTyped.getValue();
  }
  return null;
}
 
Example #27
Source File: PrimitiveVariableIT.java    From camunda-external-task-client-java with Apache License 2.0 5 votes vote down vote up
@Test
public void shoudSetVariableUntyped_Boolean() {
  // given
  engineRule.startProcessInstance(processDefinition.getId());

  client.subscribe(EXTERNAL_TASK_TOPIC_FOO)
    .handler(invocationHandler)
    .open();

  clientRule.waitForFetchAndLockUntil(() -> !invocationHandler.getInvocations().isEmpty());

  RecordedInvocation invocation = invocationHandler.getInvocations().get(0);
  ExternalTask fooTask = invocation.getExternalTask();
  ExternalTaskService fooService = invocation.getExternalTaskService();

  client.subscribe(EXTERNAL_TASK_TOPIC_BAR)
    .handler(handler)
    .open();

  // when
  Map<String, Object> variables = Variables.createVariables();
  variables.put(VARIABLE_NAME, Variables.untypedValue(VARIABLE_VALUE_BOOLEAN));
  fooService.complete(fooTask, variables);

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

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

  boolean variableValue = task.getVariable(VARIABLE_NAME);
  assertThat(variableValue).isEqualTo(VARIABLE_VALUE_BOOLEAN);

  TypedValue typedValue = task.getVariableTyped(VARIABLE_NAME);
  assertThat(typedValue.getValue()).isEqualTo(VARIABLE_VALUE_BOOLEAN);
  assertThat(typedValue.getType()).isEqualTo(BOOLEAN);
}
 
Example #28
Source File: DmnDecisionRuleResultImpl.java    From camunda-engine-dmn with Apache License 2.0 5 votes vote down vote up
@Override
public Object get(Object key) {
  TypedValue typedValue = outputValues.get(key);
  if (typedValue != null) {
    return typedValue.getValue();
  } else {
    return null;
  }
}
 
Example #29
Source File: AbstractVariableScope.java    From camunda-bpm-platform with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("unchecked")
private <T extends TypedValue> T getTypedValueFromVariableInstance(boolean deserializeValue, CoreVariableInstance variableInstance) {
  if(variableInstance != null) {
    return (T) variableInstance.getTypedValue(deserializeValue);
  }
  else {
    return null;
  }
}
 
Example #30
Source File: PrimitiveVariableIT.java    From camunda-external-task-client-java with Apache License 2.0 5 votes vote down vote up
@Test
public void shoudSetVariableUntyped_String() {
  // given
  engineRule.startProcessInstance(processDefinition.getId());

  client.subscribe(EXTERNAL_TASK_TOPIC_FOO)
    .handler(invocationHandler)
    .open();

  clientRule.waitForFetchAndLockUntil(() -> !invocationHandler.getInvocations().isEmpty());

  RecordedInvocation invocation = invocationHandler.getInvocations().get(0);
  ExternalTask fooTask = invocation.getExternalTask();
  ExternalTaskService fooService = invocation.getExternalTaskService();

  client.subscribe(EXTERNAL_TASK_TOPIC_BAR)
    .handler(handler)
    .open();

  // when
  Map<String, Object> variables = Variables.createVariables();
  variables.put(VARIABLE_NAME, Variables.untypedValue(VARIABLE_VALUE_STRING));
  fooService.complete(fooTask, variables);

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

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

  String variableValue = task.getVariable(VARIABLE_NAME);
  assertThat(variableValue).isEqualTo(VARIABLE_VALUE_STRING);

  TypedValue typedValue = task.getVariableTyped(VARIABLE_NAME);
  assertThat(typedValue.getValue()).isEqualTo(VARIABLE_VALUE_STRING);
  assertThat(typedValue.getType()).isEqualTo(STRING);
}