Skip to content

Commit 4118d16

Browse files
committed
Allow customize ObjectSerializer using a custom ObjectMapper
Signed-off-by: Matheus Cruz <[email protected]>
1 parent a03f220 commit 4118d16

File tree

5 files changed

+131
-5
lines changed

5 files changed

+131
-5
lines changed

sdk/pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@
127127
<artifactId>grpc-inprocess</artifactId>
128128
<scope>test</scope>
129129
</dependency>
130+
<dependency>
131+
<groupId>com.fasterxml.jackson.datatype</groupId>
132+
<artifactId>jackson-datatype-jsr310</artifactId>
133+
<version>2.18.2</version>
134+
<scope>test</scope>
135+
</dependency>
130136
</dependencies>
131137

132138
<build>

sdk/src/main/java/io/dapr/client/ObjectSerializer.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public class ObjectSerializer {
4343
protected ObjectSerializer() {
4444
}
4545

46+
protected ObjectMapper getObjectMapper() {
47+
return OBJECT_MAPPER;
48+
}
49+
4650
/**
4751
* Serializes a given state object into byte array.
4852
*
@@ -70,7 +74,7 @@ public byte[] serialize(Object state) throws IOException {
7074
}
7175

7276
// Not string, not primitive, so it is a complex type: we use JSON for that.
73-
return OBJECT_MAPPER.writeValueAsBytes(state);
77+
return getObjectMapper().writeValueAsBytes(state);
7478
}
7579

7680
/**
@@ -83,7 +87,7 @@ public byte[] serialize(Object state) throws IOException {
8387
* @throws IOException In case content cannot be deserialized.
8488
*/
8589
public <T> T deserialize(byte[] content, TypeRef<T> type) throws IOException {
86-
return deserialize(content, OBJECT_MAPPER.constructType(type.getType()));
90+
return deserialize(content, getObjectMapper().constructType(type.getType()));
8791
}
8892

8993
/**
@@ -96,7 +100,7 @@ public <T> T deserialize(byte[] content, TypeRef<T> type) throws IOException {
96100
* @throws IOException In case content cannot be deserialized.
97101
*/
98102
public <T> T deserialize(byte[] content, Class<T> clazz) throws IOException {
99-
return deserialize(content, OBJECT_MAPPER.constructType(clazz));
103+
return deserialize(content, getObjectMapper().constructType(clazz));
100104
}
101105

102106
private <T> T deserialize(byte[] content, JavaType javaType) throws IOException {
@@ -138,7 +142,7 @@ private <T> T deserialize(byte[] content, JavaType javaType) throws IOException
138142
}
139143
}
140144

141-
return OBJECT_MAPPER.readValue(content, javaType);
145+
return getObjectMapper().readValue(content, javaType);
142146
}
143147

144148
/**
@@ -149,7 +153,7 @@ private <T> T deserialize(byte[] content, JavaType javaType) throws IOException
149153
* @throws IOException In case content cannot be parsed.
150154
*/
151155
public JsonNode parseNode(byte[] content) throws IOException {
152-
return OBJECT_MAPPER.readTree(content);
156+
return getObjectMapper().readTree(content);
153157
}
154158

155159
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.dapr.serializer;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import io.dapr.client.ObjectSerializer;
5+
6+
public class CustomizableObjectSerializer extends ObjectSerializer implements DaprObjectSerializer {
7+
8+
private final ObjectMapper objectMapper;
9+
10+
public CustomizableObjectSerializer(ObjectMapper objectMapper) {
11+
this.objectMapper = objectMapper;
12+
}
13+
14+
@Override
15+
public ObjectMapper getObjectMapper() {
16+
return objectMapper;
17+
}
18+
19+
@Override
20+
public String getContentType() {
21+
return "application/json";
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.dapr.serializer;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
5+
public interface ObjectSerializerFactory {
6+
7+
static DaprObjectSerializer createJacksonSerializer(final ObjectMapper objectMapper) {
8+
return new CustomizableObjectSerializer(objectMapper);
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2021 The Dapr Authors
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package io.dapr.serializer;
15+
16+
import com.fasterxml.jackson.annotation.JsonInclude;
17+
import com.fasterxml.jackson.databind.DeserializationFeature;
18+
import com.fasterxml.jackson.databind.ObjectMapper;
19+
import com.fasterxml.jackson.databind.SerializationFeature;
20+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
21+
import com.google.common.base.Objects;
22+
import org.junit.jupiter.api.Test;
23+
24+
import java.io.IOException;
25+
import java.io.Serializable;
26+
import java.time.ZoneId;
27+
import java.time.ZonedDateTime;
28+
29+
import static org.junit.jupiter.api.Assertions.assertEquals;
30+
import static org.junit.jupiter.api.Assertions.fail;
31+
32+
public class CustomObjectSerializerTest {
33+
34+
private static final DaprObjectSerializer SERIALIZER =
35+
ObjectSerializerFactory.createJacksonSerializer(new ObjectMapper()
36+
.registerModule(new JavaTimeModule())
37+
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
38+
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
39+
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS));
40+
41+
public static class ObjectForTesting implements Serializable {
42+
private ZonedDateTime time;
43+
44+
public ZonedDateTime getTime() {
45+
return time;
46+
}
47+
48+
public void setTime(ZonedDateTime time) {
49+
this.time = time;
50+
}
51+
52+
@Override
53+
public boolean equals(Object o) {
54+
if (o == null || getClass() != o.getClass()) {
55+
return false;
56+
}
57+
ObjectForTesting that = (ObjectForTesting) o;
58+
return Objects.equal(time, that.time);
59+
}
60+
61+
@Override
62+
public int hashCode() {
63+
return Objects.hashCode(time);
64+
}
65+
}
66+
67+
@Test
68+
public void serializeObjectForTesting() {
69+
ObjectForTesting obj = new ObjectForTesting();
70+
obj.setTime(ZonedDateTime.of(1900, 1, 1, 1, 1, 0, 0, ZoneId.of("UTC")));
71+
String expectedResult =
72+
"{\"time\":\"1900-01-01T01:01:00Z\"}";
73+
74+
String serializedValue;
75+
try {
76+
serializedValue = new String(SERIALIZER.serialize(obj));
77+
assertEquals(expectedResult, serializedValue,
78+
"FOUND:[[" + serializedValue + "]] \n but was EXPECTING: [[" + expectedResult + "]]");
79+
} catch (IOException exception) {
80+
fail(exception.getMessage());
81+
}
82+
}
83+
}

0 commit comments

Comments
 (0)