From e2ddc9f96d4acd38434d5ba3544fc5e205dd5c29 Mon Sep 17 00:00:00 2001
From: Pruthvidhar R Dhodda <60198385+pruthvidhodda@users.noreply.github.com>
Date: Mon, 14 Sep 2020 16:32:50 -0700
Subject: [PATCH] Add metadata support for state API's (#336)
* Add metadata support for state API's
* Remove .vscode files
---
pom.xml | 2 +-
.../java/io/dapr/client/DaprClientGrpc.java | 6 ++-
.../java/io/dapr/client/DaprClientHttp.java | 4 ++
.../client/domain/DeleteStateRequest.java | 13 +++++
.../domain/DeleteStateRequestBuilder.java | 10 ++++
.../dapr/client/domain/GetStateRequest.java | 14 +++++
.../client/domain/GetStateRequestBuilder.java | 10 ++++
.../io/dapr/client/DaprClientGrpcTest.java | 53 +++++++++++++++++++
.../io/dapr/client/DaprClientHttpTest.java | 36 +++++++++++++
9 files changed, 145 insertions(+), 3 deletions(-)
diff --git a/pom.xml b/pom.xml
index bb08e284c..94bbd65e1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,7 @@
1.25.0
3.11.0
3.10.0
- https://raw.githubusercontent.com/dapr/dapr/13ee06cb55f1da9b7f823c42672e689a3cbb9df3/dapr/proto
+ https://raw.githubusercontent.com/dapr/dapr/2f32759fb9798d79b6d3fa92b1d972b07a62b6e8/dapr/proto
1.6.2
3.1.1
1.8
diff --git a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java
index d78bc4528..39ecd46ad 100644
--- a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java
+++ b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java
@@ -231,7 +231,8 @@ public class DaprClientGrpc extends AbstractDaprClient {
}
DaprProtos.GetStateRequest.Builder builder = DaprProtos.GetStateRequest.newBuilder()
.setStoreName(stateStoreName)
- .setKey(key);
+ .setKey(key)
+ .putAllMetadata(request.getMetadata());
if (options != null && options.getConsistency() != null) {
builder.setConsistency(getGrpcStateConsistency(options));
}
@@ -358,7 +359,8 @@ public class DaprClientGrpc extends AbstractDaprClient {
}
DaprProtos.DeleteStateRequest.Builder builder = DaprProtos.DeleteStateRequest.newBuilder()
.setStoreName(stateStoreName)
- .setKey(key);
+ .setKey(key)
+ .putAllMetadata(request.getMetadata());
if (etag != null) {
builder.setEtag(etag);
}
diff --git a/sdk/src/main/java/io/dapr/client/DaprClientHttp.java b/sdk/src/main/java/io/dapr/client/DaprClientHttp.java
index 7fe56bc3d..2c0cbc5a0 100644
--- a/sdk/src/main/java/io/dapr/client/DaprClientHttp.java
+++ b/sdk/src/main/java/io/dapr/client/DaprClientHttp.java
@@ -289,6 +289,8 @@ public class DaprClientHttp extends AbstractDaprClient {
.map(o -> o.getStateOptionsAsMap())
.orElse(new HashMap<>());
+ request.getMetadata().forEach(urlParameters::put);
+
return this.client
.invokeApi(DaprHttp.HttpMethods.GET.name(), url.toString(), urlParameters, headers, context)
.flatMap(s -> {
@@ -380,6 +382,8 @@ public class DaprClientHttp extends AbstractDaprClient {
.map(stateOptions -> stateOptions.getStateOptionsAsMap())
.orElse(new HashMap<>());
+ request.getMetadata().forEach(urlParameters::put);
+
return this.client.invokeApi(
DaprHttp.HttpMethods.DELETE.name(), url, urlParameters, headers, context)
.thenReturn(new Response<>(context, null));
diff --git a/sdk/src/main/java/io/dapr/client/domain/DeleteStateRequest.java b/sdk/src/main/java/io/dapr/client/domain/DeleteStateRequest.java
index b08aed65f..002694943 100644
--- a/sdk/src/main/java/io/dapr/client/domain/DeleteStateRequest.java
+++ b/sdk/src/main/java/io/dapr/client/domain/DeleteStateRequest.java
@@ -7,6 +7,9 @@ package io.dapr.client.domain;
import io.grpc.Context;
+import java.util.Collections;
+import java.util.Map;
+
/**
* A request to delete a state by key.
*/
@@ -16,6 +19,8 @@ public class DeleteStateRequest {
private String key;
+ private Map metadata;
+
private String etag;
private StateOptions stateOptions;
@@ -61,4 +66,12 @@ public class DeleteStateRequest {
void setContext(Context context) {
this.context = context;
}
+
+ public Map getMetadata() {
+ return metadata;
+ }
+
+ void setMetadata(Map metadata) {
+ this.metadata = metadata == null ? Collections.emptyMap() : metadata;
+ }
}
diff --git a/sdk/src/main/java/io/dapr/client/domain/DeleteStateRequestBuilder.java b/sdk/src/main/java/io/dapr/client/domain/DeleteStateRequestBuilder.java
index a964462f5..606befdd2 100644
--- a/sdk/src/main/java/io/dapr/client/domain/DeleteStateRequestBuilder.java
+++ b/sdk/src/main/java/io/dapr/client/domain/DeleteStateRequestBuilder.java
@@ -6,6 +6,8 @@
package io.dapr.client.domain;
import io.grpc.Context;
+import java.util.Collections;
+import java.util.Map;
/**
* Builds a request to delete a state by key.
@@ -16,6 +18,8 @@ public class DeleteStateRequestBuilder {
private final String key;
+ private Map metadata;
+
private String etag;
private StateOptions stateOptions;
@@ -27,6 +31,11 @@ public class DeleteStateRequestBuilder {
this.key = key;
}
+ public DeleteStateRequestBuilder withMetadata(Map metadata) {
+ this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata);
+ return this;
+ }
+
public DeleteStateRequestBuilder withEtag(String etag) {
this.etag = etag;
return this;
@@ -50,6 +59,7 @@ public class DeleteStateRequestBuilder {
DeleteStateRequest request = new DeleteStateRequest();
request.setStateStoreName(this.stateStoreName);
request.setKey(this.key);
+ request.setMetadata(metadata);
request.setEtag(this.etag);
request.setStateOptions(this.stateOptions);
request.setContext(this.context);
diff --git a/sdk/src/main/java/io/dapr/client/domain/GetStateRequest.java b/sdk/src/main/java/io/dapr/client/domain/GetStateRequest.java
index 59303e82c..996d6eb58 100644
--- a/sdk/src/main/java/io/dapr/client/domain/GetStateRequest.java
+++ b/sdk/src/main/java/io/dapr/client/domain/GetStateRequest.java
@@ -7,6 +7,10 @@ package io.dapr.client.domain;
import io.grpc.Context;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
/**
* A request to get a state by key.
*/
@@ -16,6 +20,8 @@ public class GetStateRequest {
private String key;
+ private Map metadata;
+
private String etag;
private StateOptions stateOptions;
@@ -61,4 +67,12 @@ public class GetStateRequest {
void setContext(Context context) {
this.context = context;
}
+
+ public Map getMetadata() {
+ return metadata;
+ }
+
+ void setMetadata(Map metadata) {
+ this.metadata = metadata == null ? Collections.emptyMap() : metadata;
+ }
}
diff --git a/sdk/src/main/java/io/dapr/client/domain/GetStateRequestBuilder.java b/sdk/src/main/java/io/dapr/client/domain/GetStateRequestBuilder.java
index 0db8e6275..efe5e4bb3 100644
--- a/sdk/src/main/java/io/dapr/client/domain/GetStateRequestBuilder.java
+++ b/sdk/src/main/java/io/dapr/client/domain/GetStateRequestBuilder.java
@@ -6,6 +6,8 @@
package io.dapr.client.domain;
import io.grpc.Context;
+import java.util.Collections;
+import java.util.Map;
/**
* Builds a request to publish an event.
@@ -16,6 +18,8 @@ public class GetStateRequestBuilder {
private final String key;
+ private Map metadata;
+
private String etag;
private StateOptions stateOptions;
@@ -27,6 +31,11 @@ public class GetStateRequestBuilder {
this.key = key;
}
+ public GetStateRequestBuilder withMetadata(Map metadata) {
+ this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata);
+ return this;
+ }
+
public GetStateRequestBuilder withEtag(String etag) {
this.etag = etag;
return this;
@@ -50,6 +59,7 @@ public class GetStateRequestBuilder {
GetStateRequest request = new GetStateRequest();
request.setStateStoreName(this.stateStoreName);
request.setKey(this.key);
+ request.setMetadata(this.metadata);
request.setEtag(this.etag);
request.setStateOptions(this.stateOptions);
request.setContext(this.context);
diff --git a/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java b/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java
index 4415f20dc..b23b27fe1 100644
--- a/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java
+++ b/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java
@@ -10,7 +10,13 @@ import com.google.common.util.concurrent.SettableFuture;
import com.google.protobuf.Any;
import com.google.protobuf.ByteString;
import com.google.protobuf.Empty;
+
+import io.dapr.client.domain.DeleteStateRequest;
+import io.dapr.client.domain.DeleteStateRequestBuilder;
+import io.dapr.client.domain.GetStateRequest;
+import io.dapr.client.domain.GetStateRequestBuilder;
import io.dapr.client.domain.HttpExtension;
+import io.dapr.client.domain.Response;
import io.dapr.client.domain.State;
import io.dapr.client.domain.StateOptions;
import io.dapr.serializer.DefaultObjectSerializer;
@@ -699,6 +705,32 @@ public class DaprClientGrpcTest {
assertEquals(expectedState, result.block());
}
+ @Test
+ public void getStateObjectValueWithMetadataTest() throws IOException {
+ String etag = "ETag1";
+ String key = "key1";
+ MyObject expectedValue = new MyObject(1, "The Value");
+ StateOptions options = buildStateOptions(StateOptions.Consistency.STRONG, StateOptions.Concurrency.FIRST_WRITE);
+ Map metadata = new HashMap();
+ metadata.put("key_1", "val_1");
+ State expectedState = buildStateKey(expectedValue, key, etag, options);
+ DaprProtos.GetStateResponse responseEnvelope = DaprProtos.GetStateResponse.newBuilder()
+ .setData(serialize(expectedValue))
+ .setEtag(etag)
+ .build();
+ GetStateRequestBuilder builder = new GetStateRequestBuilder(STATE_STORE_NAME, key);
+ builder.withMetadata(metadata).withEtag(etag).withStateOptions(options);
+ GetStateRequest request = builder.build();
+ SettableFuture settableFuture = SettableFuture.create();
+ MockCallback callback = new MockCallback<>(responseEnvelope);
+ addCallback(settableFuture, callback, directExecutor());
+ when(client.getState(any(io.dapr.v1.DaprProtos.GetStateRequest.class)))
+ .thenReturn(settableFuture);
+ Mono>> result = adapter.getState(request, TypeRef.get(MyObject.class));
+ settableFuture.set(responseEnvelope);
+ assertEquals(expectedState, result.block().getObject());
+ }
+
@Test
public void getStateObjectValueWithOptionsNoConcurrencyTest() throws IOException {
String etag = "ETag1";
@@ -779,6 +811,27 @@ public class DaprClientGrpcTest {
assertTrue(callback.wasCalled);
}
+ @Test
+ public void deleteStateWithMetadata() {
+ String etag = "ETag1";
+ String key = "key1";
+ StateOptions options = buildStateOptions(StateOptions.Consistency.STRONG, StateOptions.Concurrency.FIRST_WRITE);
+ Map metadata = new HashMap();
+ metadata.put("key_1", "val_1");
+ SettableFuture settableFuture = SettableFuture.create();
+ MockCallback callback = new MockCallback<>(Empty.newBuilder().build());
+ addCallback(settableFuture, callback, directExecutor());
+ when(client.deleteState(any(io.dapr.v1.DaprProtos.DeleteStateRequest.class)))
+ .thenReturn(settableFuture);
+ DeleteStateRequestBuilder builder = new DeleteStateRequestBuilder(STATE_STORE_NAME, key);
+ builder.withEtag(etag).withStateOptions(options).withMetadata(metadata);
+ DeleteStateRequest request = builder.build();
+ Mono> result = adapter.deleteState(request);
+ settableFuture.set(Empty.newBuilder().build());
+ result.block();
+ assertTrue(callback.wasCalled);
+ }
+
@Test
public void deleteStateTestNoHotMono() {
String etag = "ETag1";
diff --git a/sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java b/sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java
index 47b47281a..019fb7ef9 100644
--- a/sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java
+++ b/sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java
@@ -4,10 +4,14 @@
*/
package io.dapr.client;
+import io.dapr.client.domain.DeleteStateRequestBuilder;
+import io.dapr.client.domain.GetStateRequestBuilder;
import io.dapr.client.domain.HttpExtension;
+import io.dapr.client.domain.Response;
import io.dapr.client.domain.State;
import io.dapr.client.domain.StateOptions;
import io.dapr.config.Properties;
+import io.dapr.utils.TypeRef;
import okhttp3.OkHttpClient;
import okhttp3.mock.Behavior;
import okhttp3.mock.MockInterceptor;
@@ -406,6 +410,21 @@ public class DaprClientHttpTest {
assertEquals(monoEmptyEtag.block().getKey(), "key");
}
+ @Test
+ public void getStateWithMetadata() {
+ Map metadata = new HashMap();
+ metadata.put("key_1", "val_1");
+ mockInterceptor.addRule()
+ .get("http://127.0.0.1:3000/v1.0/state/MyStateStore/key?key_1=val_1")
+ .respond("\"" + EXPECTED_RESULT + "\"");
+ daprHttp = new DaprHttp(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
+ daprClientHttp = new DaprClientHttp(daprHttp);
+ GetStateRequestBuilder builder = new GetStateRequestBuilder(STATE_STORE_NAME, "key");
+ builder.withMetadata(metadata).withEtag("");
+ Mono>> monoMetadata = daprClientHttp.getState(builder.build(), TypeRef.get(String.class));
+ assertEquals(monoMetadata.block().getObject().getKey(), "key");
+ }
+
@Test
public void getStatesNullEtag() {
State stateNullEtag = new State("value", "key", null, null);
@@ -529,6 +548,23 @@ public class DaprClientHttpTest {
assertNull(mono.block());
}
+ @Test
+ public void deleteStateWithMetadata() {
+ Map metadata = new HashMap();
+ metadata.put("key_1", "val_1");
+ StateOptions stateOptions = mock(StateOptions.class);
+ State stateKeyValue = new State("value", "key", "etag", stateOptions);
+ mockInterceptor.addRule()
+ .delete("http://127.0.0.1:3000/v1.0/state/MyStateStore/key?key_1=val_1")
+ .respond(EXPECTED_RESULT);
+ daprHttp = new DaprHttp(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
+ daprClientHttp = new DaprClientHttp(daprHttp);
+ DeleteStateRequestBuilder builder = new DeleteStateRequestBuilder(STATE_STORE_NAME, stateKeyValue.getKey());
+ builder.withMetadata(metadata).withEtag(stateKeyValue.getEtag()).withStateOptions(stateOptions);
+ Mono> monoMetadata = daprClientHttp.deleteState(builder.build());
+ assertNull(monoMetadata.block().getObject());
+ }
+
@Test
public void deleteStateNoHotMono() {
StateOptions stateOptions = mock(StateOptions.class);