mirror of https://github.com/dapr/java-sdk.git
Refactor ObjectSerializer class to add ability set custom object mapper. Refactor DaprStateAsyncprovider class to use custom serializers based on ObjectSerializer class as Json serializer. Add unit tests.
This commit is contained in:
parent
9296a83323
commit
c58b9b3bca
|
@ -174,7 +174,7 @@ public class ActorObjectSerializer extends ObjectSerializer {
|
|||
return null;
|
||||
}
|
||||
|
||||
JsonNode node = OBJECT_MAPPER.readTree(value);
|
||||
JsonNode node = getObjectMapper().readTree(value);
|
||||
String callback = node.get("callback").asText();
|
||||
Duration dueTime = extractDurationOrNull(node, "dueTime");
|
||||
Duration period = extractDurationOrNull(node, "period");
|
||||
|
@ -195,7 +195,7 @@ public class ActorObjectSerializer extends ObjectSerializer {
|
|||
return null;
|
||||
}
|
||||
|
||||
JsonNode node = OBJECT_MAPPER.readTree(value);
|
||||
JsonNode node = getObjectMapper().readTree(value);
|
||||
Duration dueTime = extractDurationOrNull(node, "dueTime");
|
||||
Duration period = extractDurationOrNull(node, "period");
|
||||
byte[] data = node.get("data") != null ? node.get("data").binaryValue() : null;
|
||||
|
|
|
@ -7,6 +7,7 @@ package io.dapr.actors.runtime;
|
|||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.dapr.actors.ActorId;
|
||||
import io.dapr.client.ObjectSerializer;
|
||||
import io.dapr.config.Properties;
|
||||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
|
@ -56,7 +57,7 @@ class DaprStateAsyncProvider {
|
|||
DaprStateAsyncProvider(DaprClient daprClient, DaprObjectSerializer stateSerializer) {
|
||||
this.daprClient = daprClient;
|
||||
this.stateSerializer = stateSerializer;
|
||||
this.isStateSerializerDefault = stateSerializer.getClass() == DefaultObjectSerializer.class;
|
||||
this.isStateSerializerDefault = ObjectSerializer.class.isAssignableFrom(stateSerializer.getClass());
|
||||
}
|
||||
|
||||
<T> Mono<T> load(String actorType, ActorId actorId, String stateName, TypeRef<T> type) {
|
||||
|
|
|
@ -7,6 +7,7 @@ package io.dapr.actors.runtime;
|
|||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.dapr.actors.ActorId;
|
||||
import io.dapr.client.ObjectSerializer;
|
||||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
import io.dapr.utils.TypeRef;
|
||||
|
@ -31,6 +32,17 @@ public class DaprStateAsyncProviderTest {
|
|||
|
||||
private static final double EPSILON = 1e-10;
|
||||
|
||||
class CustomJsonSerializer extends ObjectSerializer implements DaprObjectSerializer{
|
||||
CustomJsonSerializer() {
|
||||
super(DaprStateAsyncProviderTest.OBJECT_MAPPER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return "application/json";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class used to test JSON serialization.
|
||||
*/
|
||||
|
@ -124,7 +136,7 @@ public class DaprStateAsyncProviderTest {
|
|||
})))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
DaprStateAsyncProvider provider = new DaprStateAsyncProvider(daprClient, SERIALIZER);
|
||||
DaprStateAsyncProvider provider = new DaprStateAsyncProvider(daprClient, new CustomJsonSerializer());
|
||||
provider.apply("MyActor",
|
||||
new ActorId("123"),
|
||||
createInsertChange("name", "Jon Doe"),
|
||||
|
@ -136,6 +148,49 @@ public class DaprStateAsyncProviderTest {
|
|||
verify(daprClient).saveStateTransactionally(eq("MyActor"), eq("123"), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void happyCaseApplyWithCustomJsonSerializer() {
|
||||
DaprClient daprClient = mock(DaprClient.class);
|
||||
when(daprClient
|
||||
.saveStateTransactionally(
|
||||
eq("MyActor"),
|
||||
eq("123"),
|
||||
argThat(operations -> {
|
||||
if (operations == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (operations.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
ActorStateOperation operation = operations.get(0);
|
||||
if (operation.getOperationType() == null) {
|
||||
return false;
|
||||
}
|
||||
if (operation.getKey() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String opName = operation.getOperationType();
|
||||
String key = operation.getKey();
|
||||
Object value = operation.getValue();
|
||||
|
||||
return "upsert".equals(opName) &&
|
||||
"object".equals(key) &&
|
||||
"{\"id\":1000,\"name\":\"Roxane\"}".equals(value);
|
||||
})))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
DaprStateAsyncProvider provider = new DaprStateAsyncProvider(daprClient, SERIALIZER);
|
||||
provider.apply("MyActor",
|
||||
new ActorId("123"),
|
||||
createInsertChange("object", new Customer().setId(1000).setName("Roxane")))
|
||||
.block();
|
||||
|
||||
verify(daprClient).saveStateTransactionally(eq("MyActor"), eq("123"), any());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void happyCaseLoad() throws Exception {
|
||||
DaprClient daprClient = mock(DaprClient.class);
|
||||
|
|
|
@ -22,17 +22,22 @@ import java.lang.reflect.Method;
|
|||
*/
|
||||
public class ObjectSerializer {
|
||||
|
||||
/**
|
||||
* Shared Json serializer/deserializer as per Jackson's documentation.
|
||||
*/
|
||||
protected static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
/**
|
||||
* Default constructor to avoid class from being instantiated outside package but still inherited.
|
||||
*/
|
||||
protected ObjectSerializer() {
|
||||
objectMapper = new ObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor to avoid class from being instantiated outside package but still inherited.
|
||||
*/
|
||||
protected ObjectSerializer(ObjectMapper mapper) {
|
||||
objectMapper = mapper;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,7 +67,7 @@ public class ObjectSerializer {
|
|||
}
|
||||
|
||||
// Not string, not primitive, so it is a complex type: we use JSON for that.
|
||||
return OBJECT_MAPPER.writeValueAsBytes(state);
|
||||
return getObjectMapper().writeValueAsBytes(state);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,7 +80,7 @@ public class ObjectSerializer {
|
|||
* @throws IOException In case content cannot be deserialized.
|
||||
*/
|
||||
public <T> T deserialize(byte[] content, TypeRef<T> type) throws IOException {
|
||||
return deserialize(content, OBJECT_MAPPER.constructType(type.getType()));
|
||||
return deserialize(content, getObjectMapper().constructType(type.getType()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,7 +93,7 @@ public class ObjectSerializer {
|
|||
* @throws IOException In case content cannot be deserialized.
|
||||
*/
|
||||
public <T> T deserialize(byte[] content, Class<T> clazz) throws IOException {
|
||||
return deserialize(content, OBJECT_MAPPER.constructType(clazz));
|
||||
return deserialize(content, getObjectMapper().constructType(clazz));
|
||||
}
|
||||
|
||||
private <T> T deserialize(byte[] content, JavaType javaType) throws IOException {
|
||||
|
@ -130,7 +135,7 @@ public class ObjectSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
return OBJECT_MAPPER.readValue(content, javaType);
|
||||
return getObjectMapper().readValue(content, javaType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,7 +146,7 @@ public class ObjectSerializer {
|
|||
* @throws IOException In case content cannot be parsed.
|
||||
*/
|
||||
public JsonNode parseNode(byte[] content) throws IOException {
|
||||
return OBJECT_MAPPER.readTree(content);
|
||||
return getObjectMapper().readTree(content);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,7 +158,7 @@ public class ObjectSerializer {
|
|||
* @return Result as corresponding type.
|
||||
* @throws IOException if cannot deserialize primitive time.
|
||||
*/
|
||||
private static <T> T deserializePrimitives(byte[] content, JavaType javaType) throws IOException {
|
||||
private <T> T deserializePrimitives(byte[] content, JavaType javaType) throws IOException {
|
||||
if ((content == null) || (content.length == 0)) {
|
||||
if (javaType.hasRawClass(boolean.class)) {
|
||||
return (T) Boolean.FALSE;
|
||||
|
@ -190,6 +195,13 @@ public class ObjectSerializer {
|
|||
return null;
|
||||
}
|
||||
|
||||
return OBJECT_MAPPER.readValue(content, javaType);
|
||||
return getObjectMapper().readValue(content, javaType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared Json serializer/deserializer as per Jackson's documentation.
|
||||
*/
|
||||
protected ObjectMapper getObjectMapper() {
|
||||
return objectMapper;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue