protected String getObjectTypeName(ObjectValue value, ValueFields valueFields) { String objectTypeName = value.getObjectTypeName(); if (objectTypeName == null && !value.isDeserialized() && value.getValueSerialized() != null) { throw new ProcessEngineException("Cannot write serialized value for variable '" + valueFields.getName() + "': no 'objectTypeName' provided for non-null value."); } // update type name if the object is deserialized if (value.isDeserialized() && value.getValue() != null) { objectTypeName = getTypeNameForDeserialized(value.getValue()); } return objectTypeName; }
@SuppressWarnings("unchecked") protected void verifySerializedValue(Map<String, Object> serializedValue) { ObjectValue exampleValue = MockProvider.EXAMPLE_HISTORIC_DECISION_SERIALIZED_VALUE; assertThat(serializedValue, hasEntry("type", (Object) VariableValueDto.toRestApiTypeName(exampleValue.getType().getName()))); assertThat(serializedValue, hasEntry("value", exampleValue.getValue())); Map<String, String> valueInfo = (Map<String, String>) serializedValue.get("valueInfo"); assertThat(valueInfo, hasEntry("serializationDataFormat", exampleValue.getSerializationDataFormat())); assertThat(valueInfo, hasEntry("objectTypeName", exampleValue.getObjectTypeName())); }
public Map<String, Object> getValueInfo(TypedValue typedValue) { if(!(typedValue instanceof ObjectValue)) { throw new IllegalArgumentException("Value not of type Object."); } ObjectValue objectValue = (ObjectValue) typedValue; Map<String, Object> valueInfo = new HashMap<String, Object>(); String serializationDataFormat = objectValue.getSerializationDataFormat(); if(serializationDataFormat != null) { valueInfo.put(VALUE_INFO_SERIALIZATION_DATA_FORMAT, serializationDataFormat); } String objectTypeName = objectValue.getObjectTypeName(); if(objectTypeName != null) { valueInfo.put(VALUE_INFO_OBJECT_TYPE_NAME, objectTypeName); } if (objectValue.isTransient()) { valueInfo.put(VALUE_INFO_TRANSIENT, objectValue.isTransient()); } return valueInfo; }
public TypedValueSerializer<?> getSerializer(TypedValue value) { if (value instanceof ObjectValue) { ObjectValue objectValue = (ObjectValue) value; if (objectValue.getSerializationDataFormat() != null && !objectValue.isDeserialized()) { return new FallbackSpinObjectValueSerializer(objectValue.getSerializationDataFormat()); } } return null; } }
public void testDisableCustomObjectDeserialization() { // given Task newTask = taskService.newTask(); taskService.saveTask(newTask); Map<String, Object> variables = new HashMap<String, Object>(); variables.put("customSerializable", new CustomSerializable()); variables.put("failingSerializable", new FailingSerializable()); taskService.setVariables(newTask.getId(), variables); // when List<HistoricVariableInstance> variableInstances = historyService.createHistoricVariableInstanceQuery() .disableCustomObjectDeserialization() .list(); // then assertEquals(2, variableInstances.size()); for (HistoricVariableInstance variableInstance : variableInstances) { assertNull(variableInstance.getErrorMessage()); ObjectValue typedValue = (ObjectValue) variableInstance.getTypedValue(); assertNotNull(typedValue); assertFalse(typedValue.isDeserialized()); // cannot access the deserialized value try { typedValue.getValue(); } catch(IllegalStateException e) { assertTextPresent("Object is not deserialized", e.getMessage()); } assertNotNull(typedValue.getValueSerialized()); } taskService.deleteTask(newTask.getId(), true); }
public static void assertObjectValueDeserialized(ObjectValue typedValue, Object value) { Class<? extends Object> expectedObjectType = value.getClass(); assertTrue(typedValue.isDeserialized()); assertEquals(ValueType.OBJECT, typedValue.getType()); assertEquals(value, typedValue.getValue()); assertEquals(value, typedValue.getValue(expectedObjectType)); assertEquals(expectedObjectType, typedValue.getObjectType()); assertEquals(expectedObjectType.getName(), typedValue.getObjectTypeName()); }
@Test public void testFallbackSerializerDoesNotOverrideRegularSerializer() { // given // that the process engine is configured with a serializer for a certain format // and a fallback serializer factory for the same format ProcessEngineConfigurationImpl engineConfiguration = new StandaloneInMemProcessEngineConfiguration() .setJdbcUrl("jdbc:h2:mem:camunda-forceclose") .setProcessEngineName("engine-forceclose"); engineConfiguration.setCustomPreVariableSerializers(Arrays.<TypedValueSerializer>asList(new ExampleConstantSerializer())); engineConfiguration.setFallbackSerializerFactory(new ExampleSerializerFactory()); processEngine = engineConfiguration.buildProcessEngine(); deployOneTaskProcess(processEngine); // when setting a variable that no regular serializer can handle ObjectValue objectValue = Variables.objectValue("foo").serializationDataFormat(ExampleSerializer.FORMAT).create(); ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceByKey("oneTaskProcess", Variables.createVariables().putValueTyped("var", objectValue)); ObjectValue fetchedValue = processEngine.getRuntimeService().getVariableTyped(pi.getId(), "var", true); // then the fallback serializer is used Assert.assertNotNull(fetchedValue); Assert.assertEquals(ExampleSerializer.FORMAT, fetchedValue.getSerializationDataFormat()); Assert.assertEquals(ExampleConstantSerializer.DESERIALIZED_VALUE, fetchedValue.getValue()); }
private void testVariablesWithoutDeserialization(String processDefinitionKey) throws Exception { //given serializable variable JavaSerializable javaSerializable = new JavaSerializable("foo"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); new ObjectOutputStream(baos).writeObject(javaSerializable); String serializedObject = StringUtil.fromBytes(Base64.encodeBase64(baos.toByteArray()), engineRule.getProcessEngine()); //when execute process with serialized variable and wait state ProcessInstanceWithVariables procInstance = engineRule.getRuntimeService() .createProcessInstanceByKey(processDefinitionKey) .setVariable("serializedVar", serializedObjectValue(serializedObject) .serializationDataFormat(Variables.SerializationDataFormats.JAVA) .objectTypeName(JavaSerializable.class.getName()) .create()) .executeWithVariablesInReturn(false, false); //then returned instance contains serialized variable VariableMap map = procInstance.getVariables(); assertNotNull(map); ObjectValue serializedVar = (ObjectValue) map.getValueTyped("serializedVar"); assertFalse(serializedVar.isDeserialized()); assertObjectValueSerializedJava(serializedVar, javaSerializable); //access on value should fail because variable is not deserialized try { serializedVar.getValue(); Assert.fail("Deserialization should fail!"); } catch (IllegalStateException ise) { assertTrue(ise.getMessage().equals("Object is not deserialized.")); } }
protected boolean isDeserializedObjectValue(TypedValue value) { return value instanceof ObjectValue && ((ObjectValue) value).isDeserialized(); }
@Test public void testPaLocalJodaConfiguration() throws JsonProcessingException, IOException { // given a process instance final ProcessInstance pi = runtimeService.startProcessInstanceByKey("testProcess"); // when setting a variable in the context of a process application Date date = new Date(JodaJsonSerializable.ONE_DAY_IN_MILLIS * 10); // 10th of January 1970 JodaJsonSerializable jsonSerializable = new JodaJsonSerializable(new DateTime(date.getTime())); try { ProcessApplicationContext.setCurrentProcessApplication(ReferenceStoringProcessApplication.INSTANCE); runtimeService.setVariable(pi.getId(), "jsonSerializable", Variables.objectValue(jsonSerializable).serializationDataFormat(SerializationDataFormats.JSON).create()); } finally { ProcessApplicationContext.clear(); } // then the process-application-local data format has been used to serialize the value ObjectValue objectValue = runtimeService.getVariableTyped(pi.getId(), "jsonSerializable", false); String serializedValue = objectValue.getValueSerialized(); String expectedSerializedValue = jsonSerializable.toExpectedJsonString(); ObjectMapper objectMapper = new ObjectMapper(); JsonNode actualJsonTree = objectMapper.readTree(serializedValue); JsonNode expectedJsonTree = objectMapper.readTree(expectedSerializedValue); // JsonNode#equals makes a deep comparison Assert.assertEquals(expectedJsonTree, actualJsonTree); }
public static void assertObjectValueSerializedJava(ObjectValue typedValue, Object value) { assertEquals(Variables.SerializationDataFormats.JAVA.getName(), typedValue.getSerializationDataFormat()); try { // validate this is the base 64 encoded string representation of the serialized value of the java object String valueSerialized = typedValue.getValueSerialized(); byte[] decodedObject = Base64.decodeBase64(valueSerialized.getBytes(Charset.forName("UTF-8"))); ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(decodedObject)); assertEquals(value, objectInputStream.readObject()); } catch(IOException e) { throw new RuntimeException(e); } catch(ClassNotFoundException e) { throw new RuntimeException(e); } }
@Test public void testCanMigrateWithObjectVariableThatFailsOnDeserialization() { // given ProcessDefinition sourceProcessDefinition = testHelper.deployAndGetDefinition(ProcessModels.ONE_TASK_PROCESS); ProcessDefinition targetProcessDefinition = testHelper.deployAndGetDefinition(ProcessModels.ONE_TASK_PROCESS); MigrationPlan migrationPlan = rule.getRuntimeService() .createMigrationPlan(sourceProcessDefinition.getId(), targetProcessDefinition.getId()) .mapActivities("userTask", "userTask") .build(); ProcessInstance processInstance = rule.getRuntimeService().startProcessInstanceById(sourceProcessDefinition.getId()); ObjectValue objectValue = Variables .serializedObjectValue("does/not/deserialize") .serializationDataFormat(SerializationDataFormats.JAVA) .objectTypeName("and.this.is.a.nonexisting.Class") .create(); runtimeService.setVariable( processInstance.getId(), "var", objectValue); // when testHelper.migrateProcessInstance(migrationPlan, processInstance); // then ObjectValue migratedValue = runtimeService.getVariableTyped(processInstance.getId(), "var", false); Assert.assertEquals(objectValue.getValueSerialized(), migratedValue.getValueSerialized()); Assert.assertEquals(objectValue.getObjectTypeName(), migratedValue.getObjectTypeName()); }
@Test public void getHistoricVariableByteArrayUpdates() { // given BpmnModelInstance simpleDefinition = Bpmn.createExecutableProcess("process") .startEvent() .endEvent() .done(); testHelper.deploy(simpleDefinition); List<String> serializable = new ArrayList<String>(); serializable.add("one"); serializable.add("two"); serializable.add("three"); Map<String, Object> variables = new HashMap<String, Object>(); variables.put("var", serializable); runtimeService.startProcessInstanceByKey("process", variables); runtimeService.startProcessInstanceByKey("process", variables); runtimeService.startProcessInstanceByKey("process", variables); runtimeService.startProcessInstanceByKey("process", variables); // when List<HistoricVariableUpdate> historicVariableUpdates = optimizeService.getHistoricVariableUpdates(new Date(1L), null, 10); // then assertThat(historicVariableUpdates.size(), is(4)); for (HistoricVariableUpdate variableUpdate : historicVariableUpdates) { ObjectValue typedValue = (ObjectValue) variableUpdate.getTypedValue(); assertThat(typedValue.isDeserialized(), is(false)); assertThat(typedValue.getValueSerialized(), notNullValue()); } }
@Test public void testJacksonBug146AsVariable() { InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("org/camunda/bpm/integrationtest/functional/spin/jackson146.json"); String jackson146 = SpinIoUtil.inputStreamAsString(resourceAsStream); ProcessInstance pi = runtimeService.startProcessInstanceByKey("testProcess", Variables.createVariables() .putValue("jackson146", serializedObjectValue(jackson146).serializationDataFormat("application/json").objectTypeName(HashMap.class.getName()))); // file has 4000 characters in length a // 20 characters per repeated JSON object ObjectValue objectValue = runtimeService.getVariableTyped(pi.getId(), "jackson146", true); HashMap<String, List<Object>> map = (HashMap<String, List<Object>>) objectValue.getValue(); assertEquals(200, map.get("abcdef").size()); }
.and() .body("[0].value", equalTo("a serialized value")) .body("[0].variableType", equalTo(VariableTypeHelper.toExpectedValueTypeName(serializedValue.getType()))) .body("[0].errorMessage", nullValue()) .when().get(HISTORIC_DETAIL_RESOURCE_URL); .and() .body("[0].value", equalTo("a serialized value")) .body("[0].variableType", equalTo(VariableTypeHelper.toExpectedValueTypeName(serializedValue.getType()))) .body("[0].errorMessage", nullValue()) .when()
assertFalse(typedValue.isDeserialized()); typedValue.getValue(); assertNotNull(typedValue.getValueSerialized());
public static void assertObjectValueDeserialized(ObjectValue typedValue, Object value) { Class<? extends Object> expectedObjectType = value.getClass(); assertTrue(typedValue.isDeserialized()); assertEquals(ValueType.OBJECT, typedValue.getType()); assertEquals(value, typedValue.getValue()); assertEquals(value, typedValue.getValue(expectedObjectType)); assertEquals(expectedObjectType, typedValue.getObjectType()); assertEquals(expectedObjectType.getName(), typedValue.getObjectTypeName()); }
@Test public void testFallbackSerializer() { // given // that the process engine is configured with a fallback serializer factory ProcessEngineConfigurationImpl engineConfiguration = new StandaloneInMemProcessEngineConfiguration() .setJdbcUrl("jdbc:h2:mem:camunda-forceclose") .setProcessEngineName("engine-forceclose"); engineConfiguration.setFallbackSerializerFactory(new ExampleSerializerFactory()); processEngine = engineConfiguration.buildProcessEngine(); deployOneTaskProcess(processEngine); // when setting a variable that no regular serializer can handle ObjectValue objectValue = Variables.objectValue("foo").serializationDataFormat(ExampleSerializer.FORMAT).create(); ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceByKey("oneTaskProcess", Variables.createVariables().putValueTyped("var", objectValue)); ObjectValue fetchedValue = processEngine.getRuntimeService().getVariableTyped(pi.getId(), "var", true); // then the fallback serializer is used Assert.assertNotNull(fetchedValue); Assert.assertEquals(ExampleSerializer.FORMAT, fetchedValue.getSerializationDataFormat()); Assert.assertEquals("foo", fetchedValue.getValue()); }
assertEquals(serializableValue, typedValue.getValue()); assertFalse(serializedValue.isDeserialized()); assertEquals(serializableValueLocal, typedValueLocal.getValue()); assertFalse(serializedValueLocal.isDeserialized());
public boolean isMutableValue(ObjectValue typedValue) { return typedValue.isDeserialized(); }