Skip to content
22 changes: 22 additions & 0 deletions sdk/src/main/java/io/dapr/client/AbstractDaprClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -509,6 +510,27 @@ public Mono<Void> saveState(String storeName, String key, String etag, Object va
return this.saveBulkState(storeName, Collections.singletonList(state));
}

/**
* {@inheritDoc}
*/
@Override
public Mono<Void> saveState(String storeName, String key, String etag, Object value, Map<String, String> meta,
StateOptions options) {
Map<String, String> metaCopy = null;
if (meta == null) {
metaCopy = new HashMap<>();
} else {
metaCopy = new HashMap<>(meta);
}

if (value != null) {
metaCopy.putIfAbsent("contentType", stateSerializer.getContentType());
}

State<?> state = new State<>(key, value, etag, metaCopy, options);
return this.saveBulkState(storeName, Collections.singletonList(state));
}

/**
* {@inheritDoc}
*/
Expand Down
15 changes: 15 additions & 0 deletions sdk/src/main/java/io/dapr/client/DaprClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,21 @@ Mono<Void> executeStateTransaction(String storeName,
*/
Mono<Void> saveState(String storeName, String key, String etag, Object value, StateOptions options);


/**
* Save/Update a state.
*
* @param storeName The name of the state store.
* @param key The key of the state.
* @param etag The etag to be used.
* @param value The value of the state.
* @param meta The metadata to be set to the state.
* @param options The Options to use for each state.
* @return a Mono plan of type Void.
*/
Mono<Void> saveState(String storeName, String key, String etag, Object value, Map<String, String> meta,
StateOptions options);

/**
* Delete a state.
*
Expand Down
58 changes: 58 additions & 0 deletions sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,64 @@ public void saveStateNoOptionsTest() {
result.block();
}

@Test
public void saveStateWithMetaTest() {
String key = "key1";
String etag = "ETag1";
String value = "State value";
Map<String, String> metadata = new HashMap<>();
metadata.put("custom", "customValue");
ArgumentCaptor<DaprProtos.SaveStateRequest> argument = ArgumentCaptor.forClass(DaprProtos.SaveStateRequest.class);
doAnswer((Answer<Void>) invocation -> {
StreamObserver<Empty> observer = (StreamObserver<Empty>) invocation.getArguments()[1];
observer.onNext(Empty.getDefaultInstance());
observer.onCompleted();
return null;
}).when(daprStub).saveState(argument.capture(), any());


Mono<Void> result = client.saveState(STATE_STORE_NAME, key, etag, value, metadata,null);
result.block();
assertEquals("customValue", argument.getValue().getStates(0).getMetadata().get("custom"));
}

@Test
public void saveStateWithMetaContentTypeTest() {
String key = "key1";
String etag = "ETag1";
String value = "State value";
Map<String, String> metadata = new HashMap<>();
ArgumentCaptor<DaprProtos.SaveStateRequest> argument = ArgumentCaptor.forClass(DaprProtos.SaveStateRequest.class);
doAnswer((Answer<Void>) invocation -> {
StreamObserver<Empty> observer = (StreamObserver<Empty>) invocation.getArguments()[1];
observer.onNext(Empty.getDefaultInstance());
observer.onCompleted();
return null;
}).when(daprStub).saveState(argument.capture(), any());


Mono<Void> result = client.saveState(STATE_STORE_NAME, key, etag, value, metadata,null);
result.block();
assertEquals("application/json", argument.getValue().getStates(0).getMetadata().get("contentType"));
}

@Test
public void saveStateWithMetaEmptyTest() {
String key = "key1";
String etag = "ETag1";
ArgumentCaptor<DaprProtos.SaveStateRequest> argument = ArgumentCaptor.forClass(DaprProtos.SaveStateRequest.class);
doAnswer((Answer<Void>) invocation -> {
StreamObserver<Empty> observer = (StreamObserver<Empty>) invocation.getArguments()[1];
observer.onNext(Empty.getDefaultInstance());
observer.onCompleted();
return null;
}).when(daprStub).saveState(argument.capture(), any());

Mono<Void> result = client.saveState(STATE_STORE_NAME, key, etag, null, null,null);
result.block();
assertTrue(argument.getValue().getStates(0).getMetadata().keySet().isEmpty());
}

@Test
public void saveStateTest() {
String key = "key1";
Expand Down
Loading