From 7c2ebc8908b6a031350f1eb2c5e7db8c164b94ba Mon Sep 17 00:00:00 2001 From: salaboy Date: Wed, 1 Oct 2025 13:04:05 +0200 Subject: [PATCH 1/4] adding new method signature plus test Signed-off-by: salaboy --- .../io/dapr/client/AbstractDaprClient.java | 24 +++++++++++++++---- .../main/java/io/dapr/client/DaprClient.java | 15 ++++++++++++ .../io/dapr/client/DaprClientGrpcTest.java | 21 ++++++++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java index 203f3f00a2..26bf83881c 100644 --- a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java +++ b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java @@ -48,11 +48,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -509,6 +505,24 @@ public Mono saveState(String storeName, String key, String etag, Object va return this.saveBulkState(storeName, Collections.singletonList(state)); } + /** + * {@inheritDoc} + */ + @Override + public Mono saveState(String storeName, String key, String etag, Object value, Map meta, + StateOptions options) { + if (meta == null) { + meta = new HashMap<>(); + } + + if( value != null){ + meta.put("contentType", stateSerializer.getContentType()); + } + + State state = new State<>(key, value, etag, meta, options); + return this.saveBulkState(storeName, Collections.singletonList(state)); + } + /** * {@inheritDoc} */ diff --git a/sdk/src/main/java/io/dapr/client/DaprClient.java b/sdk/src/main/java/io/dapr/client/DaprClient.java index f51a6d0ffb..6ac6086e76 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClient.java +++ b/sdk/src/main/java/io/dapr/client/DaprClient.java @@ -498,6 +498,21 @@ Mono executeStateTransaction(String storeName, */ Mono 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 saveState(String storeName, String key, String etag, Object value, Map meta, + StateOptions options); + /** * Delete a state. * diff --git a/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java b/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java index 54240d70ca..818ff2257c 100644 --- a/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java @@ -1241,6 +1241,27 @@ public void saveStateNoOptionsTest() { result.block(); } + @Test + public void saveStateWithMetaTest() { + String key = "key1"; + String etag = "ETag1"; + String value = "State value"; + Map metadata = new HashMap<>(); + metadata.put("custom", "customValue"); + ArgumentCaptor argument = ArgumentCaptor.forClass(DaprProtos.SaveStateRequest.class); + doAnswer((Answer) invocation -> { + StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; + observer.onNext(Empty.getDefaultInstance()); + observer.onCompleted(); + return null; + }).when(daprStub).saveState(argument.capture(), any()); + + + Mono 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 saveStateTest() { String key = "key1"; From 5d97c2302fc1859410e1bb946fddd75068954207 Mon Sep 17 00:00:00 2001 From: salaboy Date: Wed, 1 Oct 2025 16:57:06 +0200 Subject: [PATCH 2/4] re adding imports Signed-off-by: salaboy --- sdk/src/main/java/io/dapr/client/AbstractDaprClient.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java index 26bf83881c..7a8859c40f 100644 --- a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java +++ b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java @@ -48,7 +48,12 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.HashMap; import java.util.stream.Collectors; /** From a27a6c8192c8e3799cfb010e943c8be5eb43c271 Mon Sep 17 00:00:00 2001 From: salaboy Date: Wed, 1 Oct 2025 17:34:06 +0200 Subject: [PATCH 3/4] fixing style Signed-off-by: salaboy --- sdk/src/main/java/io/dapr/client/AbstractDaprClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java index 7a8859c40f..d13c463cb6 100644 --- a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java +++ b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java @@ -51,9 +51,9 @@ 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.HashMap; import java.util.stream.Collectors; /** @@ -520,7 +520,7 @@ public Mono saveState(String storeName, String key, String etag, Object va meta = new HashMap<>(); } - if( value != null){ + if (value != null) { meta.put("contentType", stateSerializer.getContentType()); } From d6fe7d5f0272c17d92d0da5031d188e3f0274ba6 Mon Sep 17 00:00:00 2001 From: salaboy Date: Thu, 2 Oct 2025 09:24:40 +0200 Subject: [PATCH 4/4] checking empty metadata Signed-off-by: salaboy --- .../io/dapr/client/DaprClientGrpcTest.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java b/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java index 818ff2257c..7ac6ab3cf5 100644 --- a/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java @@ -1262,6 +1262,43 @@ public void saveStateWithMetaTest() { assertEquals("customValue", argument.getValue().getStates(0).getMetadata().get("custom")); } + @Test + public void saveStateWithMetaContentTypeTest() { + String key = "key1"; + String etag = "ETag1"; + String value = "State value"; + Map metadata = new HashMap<>(); + ArgumentCaptor argument = ArgumentCaptor.forClass(DaprProtos.SaveStateRequest.class); + doAnswer((Answer) invocation -> { + StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; + observer.onNext(Empty.getDefaultInstance()); + observer.onCompleted(); + return null; + }).when(daprStub).saveState(argument.capture(), any()); + + + Mono 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 argument = ArgumentCaptor.forClass(DaprProtos.SaveStateRequest.class); + doAnswer((Answer) invocation -> { + StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; + observer.onNext(Empty.getDefaultInstance()); + observer.onCompleted(); + return null; + }).when(daprStub).saveState(argument.capture(), any()); + + Mono 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";