Add metadata support for state API's (#336)

* Add metadata support for state API's

* Remove .vscode files
This commit is contained in:
Pruthvidhar R Dhodda 2020-09-14 16:32:50 -07:00 committed by GitHub
parent 361a0e48a3
commit e2ddc9f96d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 145 additions and 3 deletions

View File

@ -17,7 +17,7 @@
<grpc.version>1.25.0</grpc.version>
<protobuf.version>3.11.0</protobuf.version>
<protoc.version>3.10.0</protoc.version>
<dapr.proto.baseurl>https://raw.githubusercontent.com/dapr/dapr/13ee06cb55f1da9b7f823c42672e689a3cbb9df3/dapr/proto</dapr.proto.baseurl>
<dapr.proto.baseurl>https://raw.githubusercontent.com/dapr/dapr/2f32759fb9798d79b6d3fa92b1d972b07a62b6e8/dapr/proto</dapr.proto.baseurl>
<os-maven-plugin.version>1.6.2</os-maven-plugin.version>
<maven-dependency-plugin.version>3.1.1</maven-dependency-plugin.version>
<maven-antrun-plugin.version>1.8</maven-antrun-plugin.version>

View File

@ -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);
}

View File

@ -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));

View File

@ -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<String, String> metadata;
private String etag;
private StateOptions stateOptions;
@ -61,4 +66,12 @@ public class DeleteStateRequest {
void setContext(Context context) {
this.context = context;
}
public Map<String, String> getMetadata() {
return metadata;
}
void setMetadata(Map<String, String> metadata) {
this.metadata = metadata == null ? Collections.emptyMap() : metadata;
}
}

View File

@ -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<String, String> metadata;
private String etag;
private StateOptions stateOptions;
@ -27,6 +31,11 @@ public class DeleteStateRequestBuilder {
this.key = key;
}
public DeleteStateRequestBuilder withMetadata(Map<String, String> 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);

View File

@ -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<String, String> metadata;
private String etag;
private StateOptions stateOptions;
@ -61,4 +67,12 @@ public class GetStateRequest {
void setContext(Context context) {
this.context = context;
}
public Map<String, String> getMetadata() {
return metadata;
}
void setMetadata(Map<String, String> metadata) {
this.metadata = metadata == null ? Collections.emptyMap() : metadata;
}
}

View File

@ -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<String, String> metadata;
private String etag;
private StateOptions stateOptions;
@ -27,6 +31,11 @@ public class GetStateRequestBuilder {
this.key = key;
}
public GetStateRequestBuilder withMetadata(Map<String, String> 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);

View File

@ -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<String, String> metadata = new HashMap<String, String>();
metadata.put("key_1", "val_1");
State<MyObject> 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<DaprProtos.GetStateResponse> settableFuture = SettableFuture.create();
MockCallback<DaprProtos.GetStateResponse> callback = new MockCallback<>(responseEnvelope);
addCallback(settableFuture, callback, directExecutor());
when(client.getState(any(io.dapr.v1.DaprProtos.GetStateRequest.class)))
.thenReturn(settableFuture);
Mono<Response<State<MyObject>>> 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<String, String> metadata = new HashMap<String, String>();
metadata.put("key_1", "val_1");
SettableFuture<Empty> settableFuture = SettableFuture.create();
MockCallback<Empty> 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<Response<Void>> result = adapter.deleteState(request);
settableFuture.set(Empty.newBuilder().build());
result.block();
assertTrue(callback.wasCalled);
}
@Test
public void deleteStateTestNoHotMono() {
String etag = "ETag1";

View File

@ -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<String, String> metadata = new HashMap<String, String>();
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<Response<State<String>>> monoMetadata = daprClientHttp.getState(builder.build(), TypeRef.get(String.class));
assertEquals(monoMetadata.block().getObject().getKey(), "key");
}
@Test
public void getStatesNullEtag() {
State<String> stateNullEtag = new State("value", "key", null, null);
@ -529,6 +548,23 @@ public class DaprClientHttpTest {
assertNull(mono.block());
}
@Test
public void deleteStateWithMetadata() {
Map<String, String> metadata = new HashMap<String, String>();
metadata.put("key_1", "val_1");
StateOptions stateOptions = mock(StateOptions.class);
State<String> 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<Response<Void>> monoMetadata = daprClientHttp.deleteState(builder.build());
assertNull(monoMetadata.block().getObject());
}
@Test
public void deleteStateNoHotMono() {
StateOptions stateOptions = mock(StateOptions.class);