Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 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,24 @@ 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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is dangerous to modify the incoming method parameter. I would rather make a copy and add the content type if value is not null.

if (meta == null) {
meta = new HashMap<>();
}

if (value != null) {
meta.put("contentType", stateSerializer.getContentType());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the key already exists? Is it ok to overwrite it?

}

State<?> state = new State<>(key, value, etag, meta, 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