Skip to content

Commit 69606d0

Browse files
authored
Merge pull request #513 from artursouza/hotfix_101
Merge pull request #504 from abogdanov37/feature_fix-statestore-seria…
2 parents 048d934 + 59e3198 commit 69606d0

2 files changed

Lines changed: 74 additions & 6 deletions

File tree

sdk-actors/src/main/java/io/dapr/actors/runtime/DaprStateAsyncProvider.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import io.dapr.actors.ActorId;
1010
import io.dapr.config.Properties;
1111
import io.dapr.serializer.DaprObjectSerializer;
12-
import io.dapr.serializer.DefaultObjectSerializer;
1312
import io.dapr.utils.TypeRef;
1413
import reactor.core.publisher.Mono;
1514

@@ -27,6 +26,11 @@ class DaprStateAsyncProvider {
2726
*/
2827
private static final Charset CHARSET = Properties.STRING_CHARSET.get();
2928

29+
/**
30+
* Marker to identify Json serializers.
31+
*/
32+
public static final String JSON_CONTENT_TYPE = "application/json";
33+
3034
/**
3135
* Handles special serialization cases.
3236
*/
@@ -45,7 +49,7 @@ class DaprStateAsyncProvider {
4549
/**
4650
* Flag determining if state serializer is the default serializer instead of user provided.
4751
*/
48-
private final boolean isStateSerializerDefault;
52+
private final boolean isStateSerializerJson;
4953

5054
/**
5155
* Instantiates a new Actor's state provider.
@@ -56,7 +60,7 @@ class DaprStateAsyncProvider {
5660
DaprStateAsyncProvider(DaprClient daprClient, DaprObjectSerializer stateSerializer) {
5761
this.daprClient = daprClient;
5862
this.stateSerializer = stateSerializer;
59-
this.isStateSerializerDefault = stateSerializer.getClass() == DefaultObjectSerializer.class;
63+
this.isStateSerializerJson = JSON_CONTENT_TYPE.equals(stateSerializer.getContentType());
6064
}
6165

6266
<T> Mono<T> load(String actorType, ActorId actorId, String stateName, TypeRef<T> type) {
@@ -69,7 +73,7 @@ <T> Mono<T> load(String actorType, ActorId actorId, String stateName, TypeRef<T>
6973
}
7074

7175
T response = this.stateSerializer.deserialize(s, type);
72-
if (this.isStateSerializerDefault && (response instanceof byte[])) {
76+
if (this.isStateSerializerJson && (response instanceof byte[])) {
7377
if (s.length == 0) {
7478
return Mono.empty();
7579
}
@@ -138,7 +142,7 @@ Mono<Void> apply(String actorType, ActorId actorId, ActorStateChange... stateCha
138142
try {
139143
byte[] data = this.stateSerializer.serialize(stateChange.getValue());
140144
if (data != null) {
141-
if (this.isStateSerializerDefault && !(stateChange.getValue() instanceof byte[])) {
145+
if (this.isStateSerializerJson && !(stateChange.getValue() instanceof byte[])) {
142146
// DefaultObjectSerializer is a JSON serializer, so we just pass it on.
143147
value = new String(data, CHARSET);
144148
} else {

sdk-actors/src/test/java/io/dapr/actors/runtime/DaprStateAsyncProviderTest.java

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77

88
import com.fasterxml.jackson.databind.ObjectMapper;
99
import io.dapr.actors.ActorId;
10+
import io.dapr.client.ObjectSerializer;
1011
import io.dapr.serializer.DaprObjectSerializer;
1112
import io.dapr.serializer.DefaultObjectSerializer;
1213
import io.dapr.utils.TypeRef;
1314
import org.junit.Assert;
1415
import org.junit.Test;
1516
import reactor.core.publisher.Mono;
1617

18+
import java.io.IOException;
1719
import java.util.Arrays;
1820
import java.util.Objects;
1921

@@ -27,10 +29,29 @@ public class DaprStateAsyncProviderTest {
2729

2830
private static final DaprObjectSerializer SERIALIZER = new DefaultObjectSerializer();
2931

30-
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
32+
3133

3234
private static final double EPSILON = 1e-10;
3335

36+
class CustomJsonSerializer implements DaprObjectSerializer{
37+
private final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
38+
39+
@Override
40+
public byte[] serialize(Object o) throws IOException {
41+
return OBJECT_MAPPER.writeValueAsBytes(o);
42+
}
43+
44+
@Override
45+
public <T> T deserialize(byte[] data, TypeRef<T> type) throws IOException {
46+
return OBJECT_MAPPER.readValue(data, OBJECT_MAPPER.constructType(type.getType()));
47+
}
48+
49+
@Override
50+
public String getContentType() {
51+
return "application/json";
52+
}
53+
}
54+
3455
/**
3556
* Class used to test JSON serialization.
3657
*/
@@ -136,6 +157,49 @@ public void happyCaseApply() {
136157
verify(daprClient).saveStateTransactionally(eq("MyActor"), eq("123"), any());
137158
}
138159

160+
@Test
161+
public void happyCaseApplyWithCustomJsonSerializer() {
162+
DaprClient daprClient = mock(DaprClient.class);
163+
when(daprClient
164+
.saveStateTransactionally(
165+
eq("MyActor"),
166+
eq("123"),
167+
argThat(operations -> {
168+
if (operations == null) {
169+
return false;
170+
}
171+
172+
if (operations.size() != 1) {
173+
return false;
174+
}
175+
ActorStateOperation operation = operations.get(0);
176+
if (operation.getOperationType() == null) {
177+
return false;
178+
}
179+
if (operation.getKey() == null) {
180+
return false;
181+
}
182+
183+
String opName = operation.getOperationType();
184+
String key = operation.getKey();
185+
Object value = operation.getValue();
186+
187+
return "upsert".equals(opName) &&
188+
"object".equals(key) &&
189+
"{\"id\":1000,\"name\":\"Roxane\"}".equals(value);
190+
})))
191+
.thenReturn(Mono.empty());
192+
193+
DaprStateAsyncProvider provider = new DaprStateAsyncProvider(daprClient, new CustomJsonSerializer());
194+
provider.apply("MyActor",
195+
new ActorId("123"),
196+
createInsertChange("object", new Customer().setId(1000).setName("Roxane")))
197+
.block();
198+
199+
verify(daprClient).saveStateTransactionally(eq("MyActor"), eq("123"), any());
200+
}
201+
202+
139203
@Test
140204
public void happyCaseLoad() throws Exception {
141205
DaprClient daprClient = mock(DaprClient.class);

0 commit comments

Comments
 (0)