From 8f5288b4867314f8f3460b09387e2951c3c08e33 Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Fri, 24 Dec 2021 19:27:28 +0530 Subject: [PATCH 01/13] inital draft for config api Signed-off-by: Pravin Pushkar --- .../grpc/ConfigurationClientSDK.java | 110 ++++++++++++ .../grpc/SubscribeConfigurationClient.java | 47 +++++ .../io/dapr/client/AbstractDaprClient.java | 32 ++++ .../main/java/io/dapr/client/DaprClient.java | 56 ++++++ .../java/io/dapr/client/DaprClientGrpc.java | 166 ++++++++++++++++++ .../java/io/dapr/client/DaprClientHttp.java | 29 +++ .../java/io/dapr/client/DaprClientProxy.java | 53 ++++++ .../io/dapr/client/DaprPreviewClient.java | 39 ++++ .../dapr/client/domain/ConfigurationItem.java | 34 ++++ .../domain/GetBulkConfigurationRequest.java | 34 ++++ .../domain/GetConfigurationRequest.java | 33 ++++ .../domain/SubscribeConfigurationRequest.java | 34 ++++ .../io/dapr/exceptions/DaprException.java | 18 ++ 13 files changed, 685 insertions(+) create mode 100644 examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClientSDK.java create mode 100644 examples/src/main/java/io/dapr/examples/configuration/grpc/SubscribeConfigurationClient.java create mode 100644 sdk/src/main/java/io/dapr/client/DaprPreviewClient.java create mode 100644 sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java create mode 100644 sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java create mode 100644 sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java create mode 100644 sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClientSDK.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClientSDK.java new file mode 100644 index 0000000000..7eaf69dc96 --- /dev/null +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClientSDK.java @@ -0,0 +1,110 @@ +package io.dapr.examples.configuration.grpc; + +import io.dapr.client.DaprClient; +import io.dapr.client.DaprClientBuilder; +import io.dapr.client.domain.ConfigurationItem; +import io.dapr.client.domain.GetBulkConfigurationRequest; +import io.dapr.client.domain.GetConfigurationRequest; +import reactor.core.publisher.Mono; + +import java.util.ArrayList; +import java.util.List; + +public class ConfigurationClientSDK { + private static final String configurationStoreName = "redisconfigstore"; + private static String key = "configgrpc||myconfig"; + + public static void main(String[] args) throws Exception { + try (DaprClient client = (new DaprClientBuilder()).build()) { + usingConfigurationrequest(client); + usingParameters(client); + usingVarargs(client); + usingBulkCofigreq(client); + getAllUsingCofigreq(client); + getAllUsingVarargs(client); + errorUsingParameters(client); + } + } + + public static void usingConfigurationrequest(DaprClient client) { + System.out.println("trying to fetch using Configuration request..."); + GetConfigurationRequest request = new GetConfigurationRequest(configurationStoreName, key); + try { + Mono item = client.getConfiguration(request); + System.out.println("Retrieved value from configurationstore, Value -> "+ item.block().getValue() + " : key ->" + item.block().getKey()); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + } + + public static void usingParameters(DaprClient client) { + System.out.println("trying to fetch using Configuration parameters..."); + key = "myconfig2"; + try { + Mono item = client.getConfiguration(configurationStoreName, key); + System.out.println("Retrieved value from configurationstore, Value -> "+ item.block().getValue() + " : key ->" + item.block().getKey()); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + } + + public static void usingVarargs(DaprClient client) { + System.out.println("trying to fetch using Varargs..."); + try { + Mono> items = client.getConfigurations(configurationStoreName, "configgrpc||myconfig", "myconfig2", "myconfig3"); + items.block().forEach(ConfigurationClientSDK::print); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + } + + public static void usingBulkCofigreq(DaprClient client) { + System.out.println("trying to fetch using usingBulkCofigreq..."); + List keys = new ArrayList<>(); + keys.add("myconfig2"); + keys.add("myconfig3"); + keys.add("myconfig4"); + keys.add("myconfig5"); + GetBulkConfigurationRequest req = new GetBulkConfigurationRequest(configurationStoreName, keys); + try { + Mono> items = client.getConfigurations(req); + items.block().forEach(ConfigurationClientSDK::print); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + } + + public static void getAllUsingCofigreq(DaprClient client) { + System.out.println("trying to fetch using getAllUsingCofigreq..."); + GetBulkConfigurationRequest req = new GetBulkConfigurationRequest(configurationStoreName, null); + try { + Mono> items = client.getConfigurations(req); + items.block().forEach(ConfigurationClientSDK::print); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + } + + public static void getAllUsingVarargs(DaprClient client) { + System.out.println("trying to fetch using getAllUsingVarargs..."); + try { + Mono> items = client.getConfigurations(configurationStoreName); + items.block().forEach(ConfigurationClientSDK::print); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + } + + public static void errorUsingParameters(DaprClient client) { + try { + Mono item = client.getConfiguration(configurationStoreName, ""); + System.out.println("Retrieved value from configurationstore, Value -> "+ item.block().getValue() + " : key ->" + item.block().getKey()); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + } + + private static void print(ConfigurationItem item) { + System.out.println(item.getValue() + " : key ->" + item.getKey()); + } +} diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/SubscribeConfigurationClient.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/SubscribeConfigurationClient.java new file mode 100644 index 0000000000..9032596d71 --- /dev/null +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/SubscribeConfigurationClient.java @@ -0,0 +1,47 @@ +package io.dapr.examples.configuration.grpc; + +import io.dapr.client.DaprClient; +import io.dapr.client.DaprClientBuilder; +import io.dapr.client.domain.ConfigurationItem; +import io.dapr.client.domain.SubscribeConfigurationRequest; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +public class SubscribeConfigurationClient { + private static final String configurationStoreName = "redisconfigstore"; + private static List k = new ArrayList<>(Arrays.asList("myconfig2","myconfig3", "myconfig4")); + + public static void main(String[] args) throws Exception { + try (DaprClient client = (new DaprClientBuilder()).build()) { + subscribeConfigurationRequestWithIterator(client); + subscribeConfigurationRequestDemoWithSubscribe(client); + } + } + + public static void subscribeConfigurationRequestWithIterator(DaprClient client) { + System.out.println("Subscribing to keys: " + k.toString()); + SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(configurationStoreName, k); + Iterator> itr = client.subscribeToConfigurations(req).toIterable().iterator(); + while(itr.hasNext()) { + List cis = itr.next(); + cis.forEach(SubscribeConfigurationClient::print); + } + } + + public static void subscribeConfigurationRequestDemoWithSubscribe(DaprClient client) { + System.out.println("Subscribing to keys using subscribe method: " + k.toString()); + SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(configurationStoreName, k); + client.subscribeToConfigurations(req) + .subscribe( + cis -> cis.forEach(SubscribeConfigurationClient::print) + ); + while (true) {} + } + + private static void print(ConfigurationItem item) { + System.out.println(item.getValue() + " : key ->" + item.getKey()); + } +} diff --git a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java index b8cf2af42d..6b9efba095 100644 --- a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java +++ b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java @@ -37,8 +37,13 @@ import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; import io.dapr.client.domain.TransactionalStateOperation; +import io.dapr.client.domain.ConfigurationItem; +import io.dapr.client.domain.GetConfigurationRequest; +import io.dapr.client.domain.GetBulkConfigurationRequest; +import io.dapr.client.domain.SubscribeConfigurationRequest; import io.dapr.serializer.DaprObjectSerializer; import io.dapr.utils.TypeRef; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.Collections; @@ -416,4 +421,31 @@ public Mono>> getBulkSecret(String storeName, Ma return this.getBulkSecret(request).defaultIfEmpty(Collections.emptyMap()); } + /** + * {@inheritDoc} + */ + @Override + public Mono getConfiguration(String storeName, String key) { + GetConfigurationRequest request = new GetConfigurationRequest(storeName, key); + return this.getConfiguration(request); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getConfigurations(String storeName, String... keys) { + List listOfKeys = Flux.just(keys).collectList().block(); + GetBulkConfigurationRequest request = new GetBulkConfigurationRequest(storeName, listOfKeys); + return this.getConfigurations(request); + } + + /** + * {@inheritDoc} + */ + public Flux> subscribeToConfigurations(String storeName, String... keys) { + List listOfKeys = Flux.just(keys).collectList().block(); + SubscribeConfigurationRequest request = new SubscribeConfigurationRequest(storeName, listOfKeys); + return this.subscribeToConfigurations(request); + } } diff --git a/sdk/src/main/java/io/dapr/client/DaprClient.java b/sdk/src/main/java/io/dapr/client/DaprClient.java index 49a9988966..cd4cbabad9 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClient.java +++ b/sdk/src/main/java/io/dapr/client/DaprClient.java @@ -27,7 +27,12 @@ import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; import io.dapr.client.domain.TransactionalStateOperation; +import io.dapr.client.domain.ConfigurationItem; +import io.dapr.client.domain.GetConfigurationRequest; +import io.dapr.client.domain.GetBulkConfigurationRequest; +import io.dapr.client.domain.SubscribeConfigurationRequest; import io.dapr.utils.TypeRef; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.List; @@ -565,4 +570,55 @@ Mono executeStateTransaction(String storeName, * @return a Mono plan of type Void. */ Mono shutdown(); + + /** + * Retrieve a configuration based on a provided key + * + * @param storeName Name of the configuration store + * @param key key of the configuration item which is to be retrieved + * @return Mono of the Configuration Item + */ + Mono getConfiguration(String storeName, String key); + + /** + * Retrieve a configuration based on a provided request object + * + * @param request request for retrieving Configuration for a single key + * @return Mono of the Configuration Item + */ + Mono getConfiguration(GetConfigurationRequest request); + + /** + * Retrieve List of configurations based on a provided variable number of keys + * + * @param storeName Name of the configuration store + * @param keys keys of the configurations which are to be retrieved + * @return Mono of List of ConfigurationItems + */ + Mono> getConfigurations(String storeName, String... keys); + + /** + * Retrieve List of configurations based on a provided configuration request object + * @param request request for retrieving Configurations for a list keys + * @return Mono of List of ConfigurationItems + */ + Mono> getConfigurations(GetBulkConfigurationRequest request); + + /** + * Subscribe to the keys for any change + * + * @param storeName Name of the configuration store + * @param keys keys of the configurations which are to be subscribed + * @return Flux of List of configuration items + */ + Flux> subscribeToConfigurations(String storeName, String... keys); + + /** + * Subscribe to the keys for any change + * + * @param request request for subscribing to any change for the given keys in request + * @return Flux of List of configuration items + */ + Flux> subscribeToConfigurations(SubscribeConfigurationRequest request); + } diff --git a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java index d829cce4c0..1b908f632d 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java @@ -31,6 +31,10 @@ import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; import io.dapr.client.domain.TransactionalStateOperation; +import io.dapr.client.domain.ConfigurationItem; +import io.dapr.client.domain.GetConfigurationRequest; +import io.dapr.client.domain.GetBulkConfigurationRequest; +import io.dapr.client.domain.SubscribeConfigurationRequest; import io.dapr.config.Properties; import io.dapr.exceptions.DaprException; import io.dapr.internal.opencensus.GrpcWrapper; @@ -48,6 +52,8 @@ import io.grpc.Metadata; import io.grpc.MethodDescriptor; import io.grpc.stub.StreamObserver; +import reactor.core.publisher.Flux; +import reactor.core.publisher.FluxSink; import reactor.core.publisher.Mono; import reactor.core.publisher.MonoSink; import reactor.util.context.Context; @@ -677,6 +683,143 @@ public Mono shutdown() { ).then(); } + /** + *{@inheritDoc} + */ + @Override + public Mono getConfiguration(GetConfigurationRequest request) { + try { + final String configurationStoreName = request.getStoreName(); + final String key = request.getKey(); + + if((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { + throw new IllegalArgumentException("Configuration Store Name cannot be null or empty."); + } + if((key == null) || (key.trim().isEmpty())) { + throw new IllegalArgumentException("Key cannot be null or empty."); + } + DaprProtos.GetConfigurationRequest.Builder builder = DaprProtos.GetConfigurationRequest.newBuilder() + .setStoreName(configurationStoreName) + .addKeys(key); + + DaprProtos.GetConfigurationRequest envelop = builder.build(); + + return Mono.subscriberContext().flatMap( + context -> + this.createMono( + it -> intercept(context, asyncStub).getConfigurationAlpha1(envelop, it) + ) + ).map( + it -> { + try { + return buildConfigurationItem(it.getItems(0)); + } catch (IOException ex) { + throw DaprException.propagate(ex); + } + } + ); + } catch (Exception ex) { + return DaprException.wrapMono(ex); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getConfigurations(GetBulkConfigurationRequest request) { + try { + final String configurationStoreName = request.getStoreName(); + final List keys = request.getKeys(); + if((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { + throw new IllegalArgumentException("Configuration Store Name cannot be null or empty."); + } + DaprProtos.GetConfigurationRequest.Builder builder = DaprProtos.GetConfigurationRequest.newBuilder() + .setStoreName(configurationStoreName); + + DaprProtos.GetConfigurationRequest tempEnvelop = null; + if(keys.isEmpty() || keys == null) { + tempEnvelop = builder.build(); + } + else { + tempEnvelop = builder.addAllKeys(keys).build(); + } + DaprProtos.GetConfigurationRequest envelop = tempEnvelop; + return Mono.subscriberContext().flatMap( + context -> + this.createMono( + it -> intercept(context, asyncStub).getConfigurationAlpha1(envelop, it) + ) + ).map( + it -> + it.getItemsList().stream() + .map(b -> { + try { + return buildConfigurationItem(b); + } catch (Exception e) { + throw DaprException.propagate(e); + } + }).collect(Collectors.toList()) + ); + + } catch (Exception ex) { + return DaprException.wrapMono(ex); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Flux> subscribeToConfigurations(SubscribeConfigurationRequest request) { + try { + final String configurationStoreName = request.getStoreName(); + final List keys = request.getKeys(); + if (configurationStoreName == null || (configurationStoreName.trim().isEmpty())) { + throw new IllegalArgumentException("Configuration Store Name can not be null or empty."); + } + if (keys == null || keys.isEmpty()) { + throw new IllegalArgumentException("Keys can not be null or empty."); + } + DaprProtos.SubscribeConfigurationRequest.Builder builder = DaprProtos.SubscribeConfigurationRequest.newBuilder() + .setStoreName(configurationStoreName) + .addAllKeys(keys); + DaprProtos.SubscribeConfigurationRequest envelop = builder.build(); + return this.createFlux( + it -> intercept(asyncStub).subscribeConfigurationAlpha1(envelop, it) + ).map( + it -> + it.getItemsList().stream() + .map(item -> { + try { + return buildConfigurationItem(item); + } catch (Exception ex) { + throw DaprException.propagate(ex); + } + }).collect(Collectors.toList()) + ); + } catch (Exception ex) { + return DaprException.wrapFlux(ex); + } + } + + /** + * Build a new Configuration Item from provided parameter + * + * @param configurationItem CommonProtos.ConfigurationItem + * @return io.dapr.client.domain.ConfigurationItem + * @throws IOException + */ + private ConfigurationItem buildConfigurationItem( + CommonProtos.ConfigurationItem configurationItem) throws IOException { + return new ConfigurationItem( + configurationItem.getKey(), + configurationItem.getValue(), + configurationItem.getVersion(), + configurationItem.getMetadataMap() + ); + } + /** * Populates GRPC client with interceptors. * @@ -722,6 +865,29 @@ private Mono createMono(Consumer> consumer) { return Mono.create(sink -> DaprException.wrap(() -> consumer.accept(createStreamObserver(sink))).run()); } + private Flux createFlux(Consumer> consumer) { + return Flux.create(sink -> DaprException.wrap(() -> consumer.accept(createStreamObserver(sink))).run()); + } + + private StreamObserver createStreamObserver(FluxSink sink) { + return new StreamObserver() { + @Override + public void onNext(T value) { + sink.next(value); + } + + @Override + public void onError(Throwable t) { + sink.error(DaprException.propagate(new ExecutionException(t))); + } + + @Override + public void onCompleted() { + sink.complete(); + } + }; + } + private StreamObserver createStreamObserver(MonoSink sink) { return new StreamObserver() { @Override diff --git a/sdk/src/main/java/io/dapr/client/DaprClientHttp.java b/sdk/src/main/java/io/dapr/client/DaprClientHttp.java index df672e2014..10c6096332 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientHttp.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientHttp.java @@ -30,12 +30,17 @@ import io.dapr.client.domain.StateOptions; import io.dapr.client.domain.TransactionalStateOperation; import io.dapr.client.domain.TransactionalStateRequest; +import io.dapr.client.domain.ConfigurationItem; +import io.dapr.client.domain.GetConfigurationRequest; +import io.dapr.client.domain.GetBulkConfigurationRequest; +import io.dapr.client.domain.SubscribeConfigurationRequest; import io.dapr.config.Properties; import io.dapr.exceptions.DaprException; import io.dapr.serializer.DaprObjectSerializer; import io.dapr.serializer.DefaultObjectSerializer; import io.dapr.utils.NetworkUtils; import io.dapr.utils.TypeRef; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.io.IOException; @@ -665,6 +670,30 @@ public Mono shutdown() { .then(); } + /** + * {@inheritDoc} + */ + @Override + public Mono getConfiguration(GetConfigurationRequest request) { + throw new DaprException("501", "Implementation not supported"); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getConfigurations(GetBulkConfigurationRequest request) { + throw new DaprException("501", "Implementation not supported"); + } + + /** + * {@inheritDoc} + */ + @Override + public Flux> subscribeToConfigurations(SubscribeConfigurationRequest request) { + throw new DaprException("501", "Implementation not supported"); + } + /** * Converts metadata map into Query params. * @param metadata metadata map diff --git a/sdk/src/main/java/io/dapr/client/DaprClientProxy.java b/sdk/src/main/java/io/dapr/client/DaprClientProxy.java index 53f619a9ca..0d99d9fbe8 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientProxy.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientProxy.java @@ -27,7 +27,12 @@ import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; import io.dapr.client.domain.TransactionalStateOperation; +import io.dapr.client.domain.ConfigurationItem; +import io.dapr.client.domain.GetConfigurationRequest; +import io.dapr.client.domain.GetBulkConfigurationRequest; +import io.dapr.client.domain.SubscribeConfigurationRequest; import io.dapr.utils.TypeRef; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.List; @@ -515,4 +520,52 @@ public void close() throws Exception { public Mono shutdown() { return client.shutdown(); } + + /** + * {@inheritDoc} + */ + @Override + public Mono getConfiguration(String storeName, String key) { + return client.getConfiguration(storeName, key); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono getConfiguration(GetConfigurationRequest request) { + return client.getConfiguration(request); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getConfigurations(String storeName, String... keys) { + return client.getConfigurations(storeName, keys); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getConfigurations(GetBulkConfigurationRequest request) { + return client.getConfigurations(request); + } + + /** + * {@inheritDoc} + */ + @Override + public Flux> subscribeToConfigurations(String storeName, String... keys) { + return client.subscribeToConfigurations(storeName, keys); + } + + /** + * {@inheritDoc} + */ + @Override + public Flux> subscribeToConfigurations(SubscribeConfigurationRequest request) { + return client.subscribeToConfigurations(request); + } } diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java new file mode 100644 index 0000000000..166a9ec668 --- /dev/null +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + +package io.dapr.client; + +import io.dapr.client.domain.ConfigurationItem; +import reactor.core.publisher.Mono; + +import java.util.List; + +/** + * A Client to be used for all Preview APIs + */ +public interface DaprPreviewClient extends AutoCloseable { + /** + * + * @param storeName + * @param key + * @return + */ + Mono getConfigurationItem(String storeName, String key); + + /** + * + * @param storeName + * @param keys + * @return + */ + Mono> getConfigurationItems(String storeName, List keys); + + /** + * + * @param storeName + * @return + */ + Mono> getAllConfigurationItems(String storeName); +} diff --git a/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java b/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java new file mode 100644 index 0000000000..214775e07e --- /dev/null +++ b/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java @@ -0,0 +1,34 @@ +package io.dapr.client.domain; + +import java.util.HashMap; +import java.util.Map; + +public class ConfigurationItem { + private final String key; + private final String value; + private final String version; + private final Map metadata; + + public ConfigurationItem(String key, String value, String version, Map metadata) { + this.key = key; + this.value = value; + this.version = version; + this.metadata = metadata; + } + + public String getKey() { + return key; + } + + public String getValue() { + return value; + } + + public String getVersion() { + return version; + } + + public Map getMetadata() { + return metadata; + } +} diff --git a/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java new file mode 100644 index 0000000000..bf1bfd79e4 --- /dev/null +++ b/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java @@ -0,0 +1,34 @@ +package io.dapr.client.domain; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class GetBulkConfigurationRequest { + private final String storeName; + private final List keys; + private Map metadata; + + public GetBulkConfigurationRequest(String storeName, List keys) { + this.storeName = storeName; + this.keys = keys == null ? Collections.unmodifiableList(new ArrayList<>()) : Collections.unmodifiableList(keys); + } + + public GetBulkConfigurationRequest setMetadata(Map metadata) { + this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata); + return this; + } + + public String getStoreName() { + return storeName; + } + + public List getKeys() { + return keys; + } + + public Map getMetadata() { + return metadata; + } +} diff --git a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java new file mode 100644 index 0000000000..a9473ed543 --- /dev/null +++ b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java @@ -0,0 +1,33 @@ +package io.dapr.client.domain; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class GetConfigurationRequest { + private final String storeName; + private final String key; + private Map metadata; + + public GetConfigurationRequest(String storeName, String key) { + this.storeName = storeName; + this.key = key; + } + + public GetConfigurationRequest setMetadata(Map metadata) { + this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata); + return this; + } + + public String getStoreName() { + return storeName; + } + + public String getKey() { + return key; + } + + public Map getMetadata() { + return metadata; + } +} diff --git a/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java new file mode 100644 index 0000000000..37a0340ee7 --- /dev/null +++ b/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java @@ -0,0 +1,34 @@ +package io.dapr.client.domain; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class SubscribeConfigurationRequest { + private final String storeName; + private final List keys; + private Map metadata; + + public SubscribeConfigurationRequest(String storeName, List keys) { + this.storeName = storeName; + this.keys = Collections.unmodifiableList(keys); + } + + public SubscribeConfigurationRequest setMetadata(Map metadata) { + this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata); + return this; + } + + public String getStoreName() { + return storeName; + } + + public List getKeys() { + return keys; + } + + public Map getMetadata() { + return metadata; + } +} diff --git a/sdk/src/main/java/io/dapr/exceptions/DaprException.java b/sdk/src/main/java/io/dapr/exceptions/DaprException.java index f8fdae376f..0771e1fac7 100644 --- a/sdk/src/main/java/io/dapr/exceptions/DaprException.java +++ b/sdk/src/main/java/io/dapr/exceptions/DaprException.java @@ -15,6 +15,7 @@ import io.grpc.StatusRuntimeException; import reactor.core.Exceptions; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.concurrent.Callable; @@ -154,6 +155,23 @@ public static Mono wrapMono(Exception exception) { return Mono.empty(); } + /** + * Wraps an exception into DaprException (if not already DaprException). + * + * @param exception Exception to be wrapped. + * @param Flux's response type. + * @return Flux containing DaprException. + */ + public static Flux wrapFlux(Exception exception) { + try { + wrap(exception); + } catch (Exception e) { + return Flux.error(e); + } + + return Flux.empty(); + } + /** * Wraps an exception into DaprException (if not already DaprException). * From d9ac5c061c574b96b9340e223a4d0ee12136559b Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Mon, 27 Dec 2021 13:10:46 +0530 Subject: [PATCH 02/13] Introducing new client for preview apis and code refactoring Signed-off-by: Pravin Pushkar --- .../grpc/ConfigurationClientSDK.java | 21 +-- .../grpc/SubscribeConfigurationClient.java | 11 +- .../io/dapr/client/AbstractDaprClient.java | 3 +- .../main/java/io/dapr/client/DaprClient.java | 56 ------- .../java/io/dapr/client/DaprClientProxy.java | 53 ------ .../io/dapr/client/DaprPreviewClient.java | 69 ++++++-- .../dapr/client/DaprPreviewClientBuilder.java | 152 ++++++++++++++++++ .../dapr/client/DaprPreviewClientProxy.java | 122 ++++++++++++++ 8 files changed, 351 insertions(+), 136 deletions(-) create mode 100644 sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java create mode 100644 sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClientSDK.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClientSDK.java index 7eaf69dc96..0c1e8ff4c7 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClientSDK.java +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClientSDK.java @@ -1,7 +1,7 @@ package io.dapr.examples.configuration.grpc; -import io.dapr.client.DaprClient; -import io.dapr.client.DaprClientBuilder; +import io.dapr.client.DaprPreviewClient; +import io.dapr.client.DaprPreviewClientBuilder; import io.dapr.client.domain.ConfigurationItem; import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.GetConfigurationRequest; @@ -15,7 +15,8 @@ public class ConfigurationClientSDK { private static String key = "configgrpc||myconfig"; public static void main(String[] args) throws Exception { - try (DaprClient client = (new DaprClientBuilder()).build()) { + try (DaprPreviewClient client = (new DaprPreviewClientBuilder()).build()) { + System.out.println("Using preview client..."); usingConfigurationrequest(client); usingParameters(client); usingVarargs(client); @@ -26,7 +27,7 @@ public static void main(String[] args) throws Exception { } } - public static void usingConfigurationrequest(DaprClient client) { + public static void usingConfigurationrequest(DaprPreviewClient client) { System.out.println("trying to fetch using Configuration request..."); GetConfigurationRequest request = new GetConfigurationRequest(configurationStoreName, key); try { @@ -37,7 +38,7 @@ public static void usingConfigurationrequest(DaprClient client) { } } - public static void usingParameters(DaprClient client) { + public static void usingParameters(DaprPreviewClient client) { System.out.println("trying to fetch using Configuration parameters..."); key = "myconfig2"; try { @@ -48,7 +49,7 @@ public static void usingParameters(DaprClient client) { } } - public static void usingVarargs(DaprClient client) { + public static void usingVarargs(DaprPreviewClient client) { System.out.println("trying to fetch using Varargs..."); try { Mono> items = client.getConfigurations(configurationStoreName, "configgrpc||myconfig", "myconfig2", "myconfig3"); @@ -58,7 +59,7 @@ public static void usingVarargs(DaprClient client) { } } - public static void usingBulkCofigreq(DaprClient client) { + public static void usingBulkCofigreq(DaprPreviewClient client) { System.out.println("trying to fetch using usingBulkCofigreq..."); List keys = new ArrayList<>(); keys.add("myconfig2"); @@ -74,7 +75,7 @@ public static void usingBulkCofigreq(DaprClient client) { } } - public static void getAllUsingCofigreq(DaprClient client) { + public static void getAllUsingCofigreq(DaprPreviewClient client) { System.out.println("trying to fetch using getAllUsingCofigreq..."); GetBulkConfigurationRequest req = new GetBulkConfigurationRequest(configurationStoreName, null); try { @@ -85,7 +86,7 @@ public static void getAllUsingCofigreq(DaprClient client) { } } - public static void getAllUsingVarargs(DaprClient client) { + public static void getAllUsingVarargs(DaprPreviewClient client) { System.out.println("trying to fetch using getAllUsingVarargs..."); try { Mono> items = client.getConfigurations(configurationStoreName); @@ -95,7 +96,7 @@ public static void getAllUsingVarargs(DaprClient client) { } } - public static void errorUsingParameters(DaprClient client) { + public static void errorUsingParameters(DaprPreviewClient client) { try { Mono item = client.getConfiguration(configurationStoreName, ""); System.out.println("Retrieved value from configurationstore, Value -> "+ item.block().getValue() + " : key ->" + item.block().getKey()); diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/SubscribeConfigurationClient.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/SubscribeConfigurationClient.java index 9032596d71..dd44ba19d9 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/SubscribeConfigurationClient.java +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/SubscribeConfigurationClient.java @@ -1,7 +1,7 @@ package io.dapr.examples.configuration.grpc; -import io.dapr.client.DaprClient; -import io.dapr.client.DaprClientBuilder; +import io.dapr.client.DaprPreviewClient; +import io.dapr.client.DaprPreviewClientBuilder; import io.dapr.client.domain.ConfigurationItem; import io.dapr.client.domain.SubscribeConfigurationRequest; @@ -15,13 +15,14 @@ public class SubscribeConfigurationClient { private static List k = new ArrayList<>(Arrays.asList("myconfig2","myconfig3", "myconfig4")); public static void main(String[] args) throws Exception { - try (DaprClient client = (new DaprClientBuilder()).build()) { + try (DaprPreviewClient client = (new DaprPreviewClientBuilder()).build()) { + System.out.println("Using preview client..."); subscribeConfigurationRequestWithIterator(client); subscribeConfigurationRequestDemoWithSubscribe(client); } } - public static void subscribeConfigurationRequestWithIterator(DaprClient client) { + public static void subscribeConfigurationRequestWithIterator(DaprPreviewClient client) { System.out.println("Subscribing to keys: " + k.toString()); SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(configurationStoreName, k); Iterator> itr = client.subscribeToConfigurations(req).toIterable().iterator(); @@ -31,7 +32,7 @@ public static void subscribeConfigurationRequestWithIterator(DaprClient client) } } - public static void subscribeConfigurationRequestDemoWithSubscribe(DaprClient client) { + public static void subscribeConfigurationRequestDemoWithSubscribe(DaprPreviewClient client) { System.out.println("Subscribing to keys using subscribe method: " + k.toString()); SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(configurationStoreName, k); client.subscribeToConfigurations(req) diff --git a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java index 6b9efba095..5bb1512bac 100644 --- a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java +++ b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java @@ -41,6 +41,7 @@ import io.dapr.client.domain.GetConfigurationRequest; import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.SubscribeConfigurationRequest; +import io.dapr.client.DaprPreviewClient; import io.dapr.serializer.DaprObjectSerializer; import io.dapr.utils.TypeRef; import reactor.core.publisher.Flux; @@ -57,7 +58,7 @@ * @see io.dapr.client.DaprClientGrpc * @see io.dapr.client.DaprClientHttp */ -abstract class AbstractDaprClient implements DaprClient { +abstract class AbstractDaprClient implements DaprClient, DaprPreviewClient { /** * A utility class for serialize and deserialize the transient objects. diff --git a/sdk/src/main/java/io/dapr/client/DaprClient.java b/sdk/src/main/java/io/dapr/client/DaprClient.java index cd4cbabad9..49a9988966 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClient.java +++ b/sdk/src/main/java/io/dapr/client/DaprClient.java @@ -27,12 +27,7 @@ import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; import io.dapr.client.domain.TransactionalStateOperation; -import io.dapr.client.domain.ConfigurationItem; -import io.dapr.client.domain.GetConfigurationRequest; -import io.dapr.client.domain.GetBulkConfigurationRequest; -import io.dapr.client.domain.SubscribeConfigurationRequest; import io.dapr.utils.TypeRef; -import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.List; @@ -570,55 +565,4 @@ Mono executeStateTransaction(String storeName, * @return a Mono plan of type Void. */ Mono shutdown(); - - /** - * Retrieve a configuration based on a provided key - * - * @param storeName Name of the configuration store - * @param key key of the configuration item which is to be retrieved - * @return Mono of the Configuration Item - */ - Mono getConfiguration(String storeName, String key); - - /** - * Retrieve a configuration based on a provided request object - * - * @param request request for retrieving Configuration for a single key - * @return Mono of the Configuration Item - */ - Mono getConfiguration(GetConfigurationRequest request); - - /** - * Retrieve List of configurations based on a provided variable number of keys - * - * @param storeName Name of the configuration store - * @param keys keys of the configurations which are to be retrieved - * @return Mono of List of ConfigurationItems - */ - Mono> getConfigurations(String storeName, String... keys); - - /** - * Retrieve List of configurations based on a provided configuration request object - * @param request request for retrieving Configurations for a list keys - * @return Mono of List of ConfigurationItems - */ - Mono> getConfigurations(GetBulkConfigurationRequest request); - - /** - * Subscribe to the keys for any change - * - * @param storeName Name of the configuration store - * @param keys keys of the configurations which are to be subscribed - * @return Flux of List of configuration items - */ - Flux> subscribeToConfigurations(String storeName, String... keys); - - /** - * Subscribe to the keys for any change - * - * @param request request for subscribing to any change for the given keys in request - * @return Flux of List of configuration items - */ - Flux> subscribeToConfigurations(SubscribeConfigurationRequest request); - } diff --git a/sdk/src/main/java/io/dapr/client/DaprClientProxy.java b/sdk/src/main/java/io/dapr/client/DaprClientProxy.java index 0d99d9fbe8..53f619a9ca 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientProxy.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientProxy.java @@ -27,12 +27,7 @@ import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; import io.dapr.client.domain.TransactionalStateOperation; -import io.dapr.client.domain.ConfigurationItem; -import io.dapr.client.domain.GetConfigurationRequest; -import io.dapr.client.domain.GetBulkConfigurationRequest; -import io.dapr.client.domain.SubscribeConfigurationRequest; import io.dapr.utils.TypeRef; -import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.List; @@ -520,52 +515,4 @@ public void close() throws Exception { public Mono shutdown() { return client.shutdown(); } - - /** - * {@inheritDoc} - */ - @Override - public Mono getConfiguration(String storeName, String key) { - return client.getConfiguration(storeName, key); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono getConfiguration(GetConfigurationRequest request) { - return client.getConfiguration(request); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono> getConfigurations(String storeName, String... keys) { - return client.getConfigurations(storeName, keys); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono> getConfigurations(GetBulkConfigurationRequest request) { - return client.getConfigurations(request); - } - - /** - * {@inheritDoc} - */ - @Override - public Flux> subscribeToConfigurations(String storeName, String... keys) { - return client.subscribeToConfigurations(storeName, keys); - } - - /** - * {@inheritDoc} - */ - @Override - public Flux> subscribeToConfigurations(SubscribeConfigurationRequest request) { - return client.subscribeToConfigurations(request); - } } diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java index 166a9ec668..af1e32db39 100644 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java @@ -6,6 +6,10 @@ package io.dapr.client; import io.dapr.client.domain.ConfigurationItem; +import io.dapr.client.domain.GetBulkConfigurationRequest; +import io.dapr.client.domain.GetConfigurationRequest; +import io.dapr.client.domain.SubscribeConfigurationRequest; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.List; @@ -14,26 +18,69 @@ * A Client to be used for all Preview APIs */ public interface DaprPreviewClient extends AutoCloseable { + + + /** + * Waits for the sidecar, giving up after timeout. + * @param timeoutInMilliseconds Timeout in milliseconds to wait for sidecar. + * @return a Mono plan of type Void. + */ + Mono waitForSidecar(int timeoutInMilliseconds); + + /** + * Gracefully shutdown the dapr runtime. + * + * @return a Mono plan of type Void. + */ + Mono shutdown(); + + /** + * Retrieve a configuration based on a provided key + * + * @param storeName Name of the configuration store + * @param key key of the configuration item which is to be retrieved + * @return Mono of the Configuration Item + */ + Mono getConfiguration(String storeName, String key); + + /** + * Retrieve a configuration based on a provided request object + * + * @param request request for retrieving Configuration for a single key + * @return Mono of the Configuration Item + */ + Mono getConfiguration(GetConfigurationRequest request); + /** + * Retrieve List of configurations based on a provided variable number of keys * - * @param storeName - * @param key - * @return + * @param storeName Name of the configuration store + * @param keys keys of the configurations which are to be retrieved + * @return Mono of List of ConfigurationItems + */ + Mono> getConfigurations(String storeName, String... keys); + + /** + * Retrieve List of configurations based on a provided configuration request object + * @param request request for retrieving Configurations for a list keys + * @return Mono of List of ConfigurationItems */ - Mono getConfigurationItem(String storeName, String key); + Mono> getConfigurations(GetBulkConfigurationRequest request); /** + * Subscribe to the keys for any change * - * @param storeName - * @param keys - * @return + * @param storeName Name of the configuration store + * @param keys keys of the configurations which are to be subscribed + * @return Flux of List of configuration items */ - Mono> getConfigurationItems(String storeName, List keys); + Flux> subscribeToConfigurations(String storeName, String... keys); /** + * Subscribe to the keys for any change * - * @param storeName - * @return + * @param request request for subscribing to any change for the given keys in request + * @return Flux of List of configuration items */ - Mono> getAllConfigurationItems(String storeName); + Flux> subscribeToConfigurations(SubscribeConfigurationRequest request); } diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java new file mode 100644 index 0000000000..e87145757f --- /dev/null +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java @@ -0,0 +1,152 @@ +package io.dapr.client; + +import io.dapr.config.Properties; +import io.dapr.serializer.DaprObjectSerializer; +import io.dapr.serializer.DefaultObjectSerializer; +import io.dapr.v1.DaprGrpc; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; + +import java.io.Closeable; + +public class DaprPreviewClientBuilder { + + /** + * Determine if this builder will create GRPC clients instead of HTTP clients. + */ + private final DaprApiProtocol apiProtocol; + + /** + * Determine if this builder will use HTTP client for service method invocation APIs. + */ + private final DaprApiProtocol methodInvocationApiProtocol; + + /** + * Builder for Dapr's HTTP Client. + */ + private final DaprHttpBuilder daprHttpBuilder; + + /** + * Serializer used for request and response objects in DaprClient. + */ + private DaprObjectSerializer objectSerializer; + + /** + * Serializer used for state objects in DaprClient. + */ + private DaprObjectSerializer stateSerializer; + + /** + * Creates a constructor for DaprClient. + * + * {@link DefaultObjectSerializer} is used for object and state serializers by defaul but is not recommended + * for production scenarios. + */ + public DaprPreviewClientBuilder() { + this.objectSerializer = new DefaultObjectSerializer(); + this.stateSerializer = new DefaultObjectSerializer(); + this.apiProtocol = Properties.API_PROTOCOL.get(); + this.methodInvocationApiProtocol = Properties.API_METHOD_INVOCATION_PROTOCOL.get(); + this.daprHttpBuilder = new DaprHttpBuilder(); + } + + /** + * Sets the serializer for objects to be sent and received from Dapr. + * See {@link DefaultObjectSerializer} as possible serializer for non-production scenarios. + * + * @param objectSerializer Serializer for objects to be sent and received from Dapr. + * @return This instance. + */ + public DaprPreviewClientBuilder withObjectSerializer(DaprObjectSerializer objectSerializer) { + if (objectSerializer == null) { + throw new IllegalArgumentException("Object serializer is required"); + } + + if (objectSerializer.getContentType() == null || objectSerializer.getContentType().isEmpty()) { + throw new IllegalArgumentException("Content Type should not be null or empty"); + } + + this.objectSerializer = objectSerializer; + return this; + } + + /** + * Sets the serializer for objects to be persisted. + * See {@link DefaultObjectSerializer} as possible serializer for non-production scenarios. + * + * @param stateSerializer Serializer for objects to be persisted. + * @return This instance. + */ + public DaprPreviewClientBuilder withStateSerializer(DaprObjectSerializer stateSerializer) { + if (stateSerializer == null) { + throw new IllegalArgumentException("State serializer is required"); + } + + this.stateSerializer = stateSerializer; + return this; + } + + /** + * Build an instance of the Client based on the provided setup. + * + * @return an instance of the setup Client + * @throws IllegalStateException if any required field is missing + */ + public DaprPreviewClient build() { + if (this.apiProtocol != this.methodInvocationApiProtocol) { + return new DaprPreviewClientProxy(buildDaprPreviewClient(this.apiProtocol), buildDaprPreviewClient(this.methodInvocationApiProtocol)); + } + + return buildDaprPreviewClient(this.apiProtocol); + } + + /** + * Creates an instance of a Dapr Client based on the chosen protocol. + * + * @param protocol Dapr API's protocol. + * @return the GRPC Client. + * @throws IllegalStateException if either host is missing or if port is missing or a negative number. + */ + private DaprPreviewClient buildDaprPreviewClient(DaprApiProtocol protocol) { + if (protocol == null) { + throw new IllegalStateException("Protocol is required."); + } + + switch (protocol) { + case GRPC: return buildDaprClientGrpc(); + case HTTP: return buildDaprClientHttp(); + default: throw new IllegalStateException("Unsupported protocol: " + protocol.name()); + } + } + + /** + * Creates an instance of the GPRC Client. + * + * @return the GRPC Client. + * @throws IllegalStateException if either host is missing or if port is missing or a negative number. + */ + private DaprPreviewClient buildDaprClientGrpc() { + int port = Properties.GRPC_PORT.get(); + if (port <= 0) { + throw new IllegalArgumentException("Invalid port."); + } + ManagedChannel channel = ManagedChannelBuilder.forAddress( + Properties.SIDECAR_IP.get(), port).usePlaintext().build(); + Closeable closeableChannel = () -> { + if (channel != null && !channel.isShutdown()) { + channel.shutdown(); + } + }; + DaprGrpc.DaprStub asyncStub = DaprGrpc.newStub(channel); + return new DaprClientGrpc(closeableChannel, asyncStub, this.objectSerializer, this.stateSerializer); + } + + /** + * Creates and instance of DaprClient over HTTP. + * + * @return DaprClient over HTTP. + */ + private DaprPreviewClient buildDaprClientHttp() { + return new DaprClientHttp(this.daprHttpBuilder.build(), this.objectSerializer, this.stateSerializer); + } +} diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java new file mode 100644 index 0000000000..e69e09dd8e --- /dev/null +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java @@ -0,0 +1,122 @@ +package io.dapr.client; + +import io.dapr.client.domain.ConfigurationItem; +import io.dapr.client.domain.GetConfigurationRequest; +import io.dapr.client.domain.GetBulkConfigurationRequest; +import io.dapr.client.domain.SubscribeConfigurationRequest; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.List; + +public class DaprPreviewClientProxy implements DaprPreviewClient { + + /** + * Client for all API invocations. + */ + private final DaprPreviewClient client; + + /** + * Client to override Dapr's service invocation APIs. + */ + private final DaprPreviewClient methodInvocationOverrideClient; + + /** + * Constructor with delegate client. + * + * @param client Client for all API invocations. + * @see DaprPreviewClientBuilder + */ + DaprPreviewClientProxy(DaprPreviewClient client) { + this(client, client); + } + + /** + * Constructor with delegate client and override client for Dapr's method invocation APIs. + * + * @param client Client for all API invocations, except override below. + * @param methodInvocationOverrideClient Client to override Dapr's service invocation APIs. + * @see DaprClientBuilder + */ + DaprPreviewClientProxy( + DaprPreviewClient client, + DaprPreviewClient methodInvocationOverrideClient) { + this.client = client; + this.methodInvocationOverrideClient = methodInvocationOverrideClient; + } + + /** + * {@inheritDoc} + */ + @Override + public Mono waitForSidecar(int timeoutInMilliseconds) { + return client.waitForSidecar(timeoutInMilliseconds); + } + + /** + * {@inheritDoc} + */ + @Override + public void close() throws Exception { + client.close(); + if (client != methodInvocationOverrideClient) { + methodInvocationOverrideClient.close(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Mono shutdown() { + return client.shutdown(); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono getConfiguration(String storeName, String key) { + return client.getConfiguration(storeName, key); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono getConfiguration(GetConfigurationRequest request) { + return client.getConfiguration(request); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getConfigurations(String storeName, String... keys) { + return client.getConfigurations(storeName, keys); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getConfigurations(GetBulkConfigurationRequest request) { + return client.getConfigurations(request); + } + + /** + * {@inheritDoc} + */ + @Override + public Flux> subscribeToConfigurations(String storeName, String... keys) { + return client.subscribeToConfigurations(storeName, keys); + } + + /** + * {@inheritDoc} + */ + @Override + public Flux> subscribeToConfigurations(SubscribeConfigurationRequest request) { + return client.subscribeToConfigurations(request); + } +} From 8d52bcb630723e60774ffb7b8a04606bb28153b5 Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Mon, 27 Dec 2021 16:57:53 +0530 Subject: [PATCH 03/13] Unit tests and code refactoring Signed-off-by: Pravin Pushkar --- .../grpc/ConfigurationClient.java | 146 +++++++++ .../grpc/ConfigurationClientSDK.java | 111 ------- .../examples/configuration/grpc/README.md | 92 ++++++ .../grpc/SubscribeConfigurationClient.java | 48 --- pom.xml | 2 +- .../io/dapr/client/AbstractDaprClient.java | 65 +++- .../java/io/dapr/client/DaprClientGrpc.java | 115 +++---- .../java/io/dapr/client/DaprClientHttp.java | 16 +- .../io/dapr/client/DaprPreviewClient.java | 189 ++++++++---- .../dapr/client/DaprPreviewClientBuilder.java | 285 +++++++++--------- .../dapr/client/DaprPreviewClientProxy.java | 274 ++++++++++------- .../dapr/client/domain/ConfigurationItem.java | 68 +++-- .../domain/GetBulkConfigurationRequest.java | 55 ++-- .../domain/GetConfigurationRequest.java | 55 ++-- .../domain/SubscribeConfigurationRequest.java | 56 ++-- .../client/DaprPreviewClientBuilderTest.java | 43 +++ .../client/DaprPreviewClientGrpcTest.java | 231 ++++++++++++++ .../client/DaprPreviewClientHttpTest.java | 160 ++++++++++ .../client/DaprPreviewClientProxyTest.java | 56 ++++ 19 files changed, 1427 insertions(+), 640 deletions(-) create mode 100644 examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java delete mode 100644 examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClientSDK.java create mode 100644 examples/src/main/java/io/dapr/examples/configuration/grpc/README.md delete mode 100644 examples/src/main/java/io/dapr/examples/configuration/grpc/SubscribeConfigurationClient.java create mode 100644 sdk/src/test/java/io/dapr/client/DaprPreviewClientBuilderTest.java create mode 100644 sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java create mode 100644 sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java create mode 100644 sdk/src/test/java/io/dapr/client/DaprPreviewClientProxyTest.java diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java new file mode 100644 index 0000000000..9abcfb072b --- /dev/null +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + +package io.dapr.examples.configuration.grpc; + +import io.dapr.client.DaprPreviewClient; +import io.dapr.client.DaprPreviewClientBuilder; +import io.dapr.client.domain.ConfigurationItem; +import io.dapr.client.domain.GetBulkConfigurationRequest; +import io.dapr.client.domain.GetConfigurationRequest; +import io.dapr.client.domain.SubscribeConfigurationRequest; +import reactor.core.publisher.Mono; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +public class ConfigurationClient { + + private static final String CONFIG_STORE_NAME = "redisconfigstore"; + + private static final List keys = new ArrayList<>(Arrays.asList("myconfig2", "myconfig3", "myconfig4")); + + /** + * Executes various methods to check the different apis. + * @param args arguments + * @throws Exception throws Exception + */ + public static void main(String[] args) throws Exception { + try (DaprPreviewClient client = (new DaprPreviewClientBuilder()).build()) { + System.out.println("Using preview client..."); + getConfigurationForaSingleKey(client); + getConfigurationsUsingVarargs(client); + getConfigurations(client); + getAllConfigurations(client); + subscribeConfigurationRequestWithIterator(client); + subscribeConfigurationRequestWithSubscribe(client); + } + } + + /** + * Gets configuration for a single key. + * + * @param client DaprPreviewClient object + */ + public static void getConfigurationForaSingleKey(DaprPreviewClient client) { + System.out.println("*******trying to retrieve configuration a key********"); + GetConfigurationRequest request = new GetConfigurationRequest(CONFIG_STORE_NAME, keys.get(0)); + try { + Mono item = client.getConfiguration(request); + System.out.println("Value ->" + item.block().getValue() + " key ->" + item.block().getKey()); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + } + + /** + * Gets configurations for varibale no. of arguments. + * + * @param client DaprPreviewClient object + */ + public static void getConfigurationsUsingVarargs(DaprPreviewClient client) { + System.out.println("*******trying to retrieve configurations for a variable no. of keys********"); + try { + Mono> items = + client.getConfigurations(CONFIG_STORE_NAME, "configgrpc||myconfig", "myconfig2", "myconfig3"); + items.block().forEach(ConfigurationClient::print); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + } + + /** + * Gets configurations for a list of keys. + * + * @param client DaprPreviewClient object + */ + public static void getConfigurations(DaprPreviewClient client) { + System.out.println("*******trying to retrieve configurations for a list of keys********"); + List keys = new ArrayList<>(); + keys.add("myconfig2"); + keys.add("myconfig3"); + keys.add("myconfig4"); + keys.add("myconfig5"); + GetBulkConfigurationRequest req = new GetBulkConfigurationRequest(CONFIG_STORE_NAME, keys); + try { + Mono> items = client.getConfigurations(req); + items.block().forEach(ConfigurationClient::print); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + } + + /** + * Gets all configurations. + * + * @param client DaprPreviewClient object + */ + public static void getAllConfigurations(DaprPreviewClient client) { + System.out.println("*****Retrieving all configurations*******"); + try { + Mono> items = client.getAllConfigurations(CONFIG_STORE_NAME); + items.block().forEach(ConfigurationClient::print); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + } + + /** + * Subscribe to a list of keys. + * + * @param client DaprPreviewClient object + */ + public static void subscribeConfigurationRequestWithIterator(DaprPreviewClient client) { + System.out.println("*****Subscribing to keys: " + keys.toString() + " *****"); + SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(CONFIG_STORE_NAME, keys); + Iterator> itr = client.subscribeToConfigurations(req).toIterable().iterator(); + while (itr.hasNext()) { + List cis = itr.next(); + cis.forEach(ConfigurationClient::print); + } + } + + /** + * Subscribe to a list of keys.Optional to above iterator way of retrieving the changes + * + * @param client DaprPreviewClient object + */ + public static void subscribeConfigurationRequestWithSubscribe(DaprPreviewClient client) { + System.out.println("*****Subscribing to keys using subscribe method: " + keys.toString() + " *****"); + SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(CONFIG_STORE_NAME, keys); + client.subscribeToConfigurations(req) + .subscribe( + cis -> cis.forEach(ConfigurationClient::print) + ); + // Below lines need to be uncommented to stop client from getting killed. + /*while (true) {}*/ + } + + private static void print(ConfigurationItem item) { + System.out.println(item.getValue() + " : key ->" + item.getKey()); + } +} diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClientSDK.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClientSDK.java deleted file mode 100644 index 0c1e8ff4c7..0000000000 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClientSDK.java +++ /dev/null @@ -1,111 +0,0 @@ -package io.dapr.examples.configuration.grpc; - -import io.dapr.client.DaprPreviewClient; -import io.dapr.client.DaprPreviewClientBuilder; -import io.dapr.client.domain.ConfigurationItem; -import io.dapr.client.domain.GetBulkConfigurationRequest; -import io.dapr.client.domain.GetConfigurationRequest; -import reactor.core.publisher.Mono; - -import java.util.ArrayList; -import java.util.List; - -public class ConfigurationClientSDK { - private static final String configurationStoreName = "redisconfigstore"; - private static String key = "configgrpc||myconfig"; - - public static void main(String[] args) throws Exception { - try (DaprPreviewClient client = (new DaprPreviewClientBuilder()).build()) { - System.out.println("Using preview client..."); - usingConfigurationrequest(client); - usingParameters(client); - usingVarargs(client); - usingBulkCofigreq(client); - getAllUsingCofigreq(client); - getAllUsingVarargs(client); - errorUsingParameters(client); - } - } - - public static void usingConfigurationrequest(DaprPreviewClient client) { - System.out.println("trying to fetch using Configuration request..."); - GetConfigurationRequest request = new GetConfigurationRequest(configurationStoreName, key); - try { - Mono item = client.getConfiguration(request); - System.out.println("Retrieved value from configurationstore, Value -> "+ item.block().getValue() + " : key ->" + item.block().getKey()); - } catch (Exception ex) { - System.out.println(ex.getMessage()); - } - } - - public static void usingParameters(DaprPreviewClient client) { - System.out.println("trying to fetch using Configuration parameters..."); - key = "myconfig2"; - try { - Mono item = client.getConfiguration(configurationStoreName, key); - System.out.println("Retrieved value from configurationstore, Value -> "+ item.block().getValue() + " : key ->" + item.block().getKey()); - } catch (Exception ex) { - System.out.println(ex.getMessage()); - } - } - - public static void usingVarargs(DaprPreviewClient client) { - System.out.println("trying to fetch using Varargs..."); - try { - Mono> items = client.getConfigurations(configurationStoreName, "configgrpc||myconfig", "myconfig2", "myconfig3"); - items.block().forEach(ConfigurationClientSDK::print); - } catch (Exception ex) { - System.out.println(ex.getMessage()); - } - } - - public static void usingBulkCofigreq(DaprPreviewClient client) { - System.out.println("trying to fetch using usingBulkCofigreq..."); - List keys = new ArrayList<>(); - keys.add("myconfig2"); - keys.add("myconfig3"); - keys.add("myconfig4"); - keys.add("myconfig5"); - GetBulkConfigurationRequest req = new GetBulkConfigurationRequest(configurationStoreName, keys); - try { - Mono> items = client.getConfigurations(req); - items.block().forEach(ConfigurationClientSDK::print); - } catch (Exception ex) { - System.out.println(ex.getMessage()); - } - } - - public static void getAllUsingCofigreq(DaprPreviewClient client) { - System.out.println("trying to fetch using getAllUsingCofigreq..."); - GetBulkConfigurationRequest req = new GetBulkConfigurationRequest(configurationStoreName, null); - try { - Mono> items = client.getConfigurations(req); - items.block().forEach(ConfigurationClientSDK::print); - } catch (Exception ex) { - System.out.println(ex.getMessage()); - } - } - - public static void getAllUsingVarargs(DaprPreviewClient client) { - System.out.println("trying to fetch using getAllUsingVarargs..."); - try { - Mono> items = client.getConfigurations(configurationStoreName); - items.block().forEach(ConfigurationClientSDK::print); - } catch (Exception ex) { - System.out.println(ex.getMessage()); - } - } - - public static void errorUsingParameters(DaprPreviewClient client) { - try { - Mono item = client.getConfiguration(configurationStoreName, ""); - System.out.println("Retrieved value from configurationstore, Value -> "+ item.block().getValue() + " : key ->" + item.block().getKey()); - } catch (Exception ex) { - System.out.println(ex.getMessage()); - } - } - - private static void print(ConfigurationItem item) { - System.out.println(item.getValue() + " : key ->" + item.getKey()); - } -} diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md b/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md new file mode 100644 index 0000000000..1fdec9302a --- /dev/null +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md @@ -0,0 +1,92 @@ +## Retrieve Configurations via Configuration API + +This example provides the different capabilities provided by Dapr Java SDK for Configuration. For further information about Configuration APIs please refer to [this link](https://docs.dapr.io/developing-applications/building-blocks/configuration/) +**This API is available in Preview Mode**. + +## Pre-requisites + +* [Dapr and Dapr Cli](https://docs.dapr.io/getting-started/install-dapr/). +* Java JDK 11 (or greater): [Oracle JDK](https://www.oracle.com/technetwork/java/javase/downloads/index.html#JDK11) or [OpenJDK](https://jdk.java.net/13/). +* [Apache Maven](https://maven.apache.org/install.html) version 3.x. + +### Checking out the code + +Clone this repository: + +```sh +git clone https://github.com/dapr/java-sdk.git +cd java-sdk +``` + +Then build the Maven project: + +```sh +# make sure you are in the `java-sdk` directory. +mvn install +``` + +Get into the examples' directory: +```sh +cd examples +``` + +### Using the ConfigurationAPI + +The java SDK exposes several methods for this - +* `client.getConfiguration(...)` for getting a configuration for a single key. +* `client.getConfigurations(...)` for getting a configurations by passing a variable no. of arguments or list of argumets. +* `client.getAllConfigurations(...)` for getting all configurations. +* `client.subscribeToConfigurations(...)` for subscribing to a list of keys for any change. + +### Running the example +The code uses the `DaprPreviewClient` created by the `DaprPreviewClientBuilder`. + +```bash +dapr run --app-id configgrpc --log-level debug -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.configuration.grpc.ConfigurationClient +``` + +### Sample output +``` +== APP == Using preview client... +== APP == *******trying to retrieve configuration a key******** +== APP == Value ->"value2" key ->myconfig2 +== APP == *******trying to retrieve configurations for a variable no. of keys******** +== APP == "wookie-pravin" : key ->configgrpc||myconfig +== APP == "value2" : key ->myconfig2 +== APP == "value3" : key ->myconfig3 +== APP == *******trying to retrieve configurations for a list of keys******** +== APP == "value2" : key ->myconfig2 +== APP == "value3" : key ->myconfig3 +== APP == "value4" : key ->myconfig4 +== APP == "value5" : key ->myconfig5 +== APP == *****Retrieving all configurations******* +== APP == "value4" : key ->myconfig4 +== APP == "wookie-pravin" : key ->configgrpc||myconfig +== APP == "value2" : key ->myconfig2 +== APP == "value6" : key ->"myconfig6" +== APP == "value5" : key ->myconfig5 +== APP == "value3" : key ->myconfig3 +== APP == *****Subscribing to keys: [myconfig2, myconfig3, myconfig4] ***** +DEBU[0030] Refreshing all mDNS addresses. app_id=configgrpc instance=LAPTOP-OS4MBC7R scope=dapr.contrib type=log ver=1.5.1 +DEBU[0030] no mDNS apps to refresh. app_id=configgrpc instance=LAPTOP-OS4MBC7R scope=dapr.contrib type=log ver=1.5.1 +DEBU[0060] Refreshing all mDNS addresses. app_id=configgrpc instance=LAPTOP-OS4MBC7R scope=dapr.contrib type=log ver=1.5.1 +DEBU[0060] no mDNS apps to refresh. app_id=configgrpc instance=LAPTOP-OS4MBC7R scope=dapr.contrib type=log ver=1.5.1 +== APP == "new-value" : key ->myconfig2 + +``` +### Cleanup + +To stop the apps run (or press CTRL+C): + + + +```bash +dapr stop --app-id configgrpc +``` + + + +Thanks for playing. + diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/SubscribeConfigurationClient.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/SubscribeConfigurationClient.java deleted file mode 100644 index dd44ba19d9..0000000000 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/SubscribeConfigurationClient.java +++ /dev/null @@ -1,48 +0,0 @@ -package io.dapr.examples.configuration.grpc; - -import io.dapr.client.DaprPreviewClient; -import io.dapr.client.DaprPreviewClientBuilder; -import io.dapr.client.domain.ConfigurationItem; -import io.dapr.client.domain.SubscribeConfigurationRequest; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -public class SubscribeConfigurationClient { - private static final String configurationStoreName = "redisconfigstore"; - private static List k = new ArrayList<>(Arrays.asList("myconfig2","myconfig3", "myconfig4")); - - public static void main(String[] args) throws Exception { - try (DaprPreviewClient client = (new DaprPreviewClientBuilder()).build()) { - System.out.println("Using preview client..."); - subscribeConfigurationRequestWithIterator(client); - subscribeConfigurationRequestDemoWithSubscribe(client); - } - } - - public static void subscribeConfigurationRequestWithIterator(DaprPreviewClient client) { - System.out.println("Subscribing to keys: " + k.toString()); - SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(configurationStoreName, k); - Iterator> itr = client.subscribeToConfigurations(req).toIterable().iterator(); - while(itr.hasNext()) { - List cis = itr.next(); - cis.forEach(SubscribeConfigurationClient::print); - } - } - - public static void subscribeConfigurationRequestDemoWithSubscribe(DaprPreviewClient client) { - System.out.println("Subscribing to keys using subscribe method: " + k.toString()); - SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(configurationStoreName, k); - client.subscribeToConfigurations(req) - .subscribe( - cis -> cis.forEach(SubscribeConfigurationClient::print) - ); - while (true) {} - } - - private static void print(ConfigurationItem item) { - System.out.println(item.getValue() + " : key ->" + item.getKey()); - } -} diff --git a/pom.xml b/pom.xml index 7911a520e7..f48c596346 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ UTF-8 1.39.0 3.13.0 - https://raw.githubusercontent.com/dapr/dapr/v1.4.0-rc.6/dapr/proto + https://raw.githubusercontent.com/dapr/dapr/v1.5.1/dapr/proto 1.6.2 3.1.1 1.8 diff --git a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java index 5bb1512bac..8b50fef248 100644 --- a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java +++ b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java @@ -13,14 +13,17 @@ package io.dapr.client; +import io.dapr.client.domain.ConfigurationItem; import io.dapr.client.domain.DeleteStateRequest; import io.dapr.client.domain.DeleteStateRequestBuilder; import io.dapr.client.domain.ExecuteStateTransactionRequest; import io.dapr.client.domain.ExecuteStateTransactionRequestBuilder; +import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.GetBulkSecretRequest; import io.dapr.client.domain.GetBulkSecretRequestBuilder; import io.dapr.client.domain.GetBulkStateRequest; import io.dapr.client.domain.GetBulkStateRequestBuilder; +import io.dapr.client.domain.GetConfigurationRequest; import io.dapr.client.domain.GetSecretRequest; import io.dapr.client.domain.GetSecretRequestBuilder; import io.dapr.client.domain.GetStateRequest; @@ -36,12 +39,8 @@ import io.dapr.client.domain.SaveStateRequestBuilder; import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; -import io.dapr.client.domain.TransactionalStateOperation; -import io.dapr.client.domain.ConfigurationItem; -import io.dapr.client.domain.GetConfigurationRequest; -import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.SubscribeConfigurationRequest; -import io.dapr.client.DaprPreviewClient; +import io.dapr.client.domain.TransactionalStateOperation; import io.dapr.serializer.DaprObjectSerializer; import io.dapr.utils.TypeRef; import reactor.core.publisher.Flux; @@ -431,16 +430,58 @@ public Mono getConfiguration(String storeName, String key) { return this.getConfiguration(request); } + /** + * {@inheritDoc} + */ + @Override + public Mono getConfiguration(String storeName, String key, Map metadata) { + GetConfigurationRequest request = new GetConfigurationRequest(storeName, key); + request.setMetadata(metadata); + return this.getConfiguration(request); + } + /** * {@inheritDoc} */ @Override public Mono> getConfigurations(String storeName, String... keys) { - List listOfKeys = Flux.just(keys).collectList().block(); + List listOfKeys = Flux.just(keys).filter(key -> !key.trim().isEmpty()).collectList().block(); GetBulkConfigurationRequest request = new GetBulkConfigurationRequest(storeName, listOfKeys); return this.getConfigurations(request); } + /** + * {@inheritDoc} + */ + @Override + public Mono> getConfigurations( + String storeName, + List keys, + Map metadata) { + GetBulkConfigurationRequest request = new GetBulkConfigurationRequest(storeName, keys); + request.setMetadata(metadata); + return this.getConfigurations(request); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getAllConfigurations(String storeName) { + GetBulkConfigurationRequest request = new GetBulkConfigurationRequest(storeName, null); + return this.getAllConfigurations(request); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getAllConfigurations(String storeName, Map metadata) { + GetBulkConfigurationRequest request = new GetBulkConfigurationRequest(storeName, null); + request.setMetadata(metadata); + return this.getAllConfigurations(request); + } + /** * {@inheritDoc} */ @@ -449,4 +490,16 @@ public Flux> subscribeToConfigurations(String storeName, SubscribeConfigurationRequest request = new SubscribeConfigurationRequest(storeName, listOfKeys); return this.subscribeToConfigurations(request); } + + /** + * {@inheritDoc} + */ + public Flux> subscribeToConfigurations( + String storeName, + List keys, + Map metadata) { + SubscribeConfigurationRequest request = new SubscribeConfigurationRequest(storeName, keys); + request.setMetadata(metadata); + return this.subscribeToConfigurations(request); + } } diff --git a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java index 1b908f632d..4d9df33f49 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java @@ -17,10 +17,13 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import com.google.protobuf.Empty; +import io.dapr.client.domain.ConfigurationItem; import io.dapr.client.domain.DeleteStateRequest; import io.dapr.client.domain.ExecuteStateTransactionRequest; +import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.GetBulkSecretRequest; import io.dapr.client.domain.GetBulkStateRequest; +import io.dapr.client.domain.GetConfigurationRequest; import io.dapr.client.domain.GetSecretRequest; import io.dapr.client.domain.GetStateRequest; import io.dapr.client.domain.HttpExtension; @@ -30,11 +33,8 @@ import io.dapr.client.domain.SaveStateRequest; import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; -import io.dapr.client.domain.TransactionalStateOperation; -import io.dapr.client.domain.ConfigurationItem; -import io.dapr.client.domain.GetConfigurationRequest; -import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.SubscribeConfigurationRequest; +import io.dapr.client.domain.TransactionalStateOperation; import io.dapr.config.Properties; import io.dapr.exceptions.DaprException; import io.dapr.internal.opencensus.GrpcWrapper; @@ -692,10 +692,10 @@ public Mono getConfiguration(GetConfigurationRequest request) final String configurationStoreName = request.getStoreName(); final String key = request.getKey(); - if((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { + if ((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { throw new IllegalArgumentException("Configuration Store Name cannot be null or empty."); } - if((key == null) || (key.trim().isEmpty())) { + if ((key == null) || (key.trim().isEmpty())) { throw new IllegalArgumentException("Key cannot be null or empty."); } DaprProtos.GetConfigurationRequest.Builder builder = DaprProtos.GetConfigurationRequest.newBuilder() @@ -703,20 +703,8 @@ public Mono getConfiguration(GetConfigurationRequest request) .addKeys(key); DaprProtos.GetConfigurationRequest envelop = builder.build(); - - return Mono.subscriberContext().flatMap( - context -> - this.createMono( - it -> intercept(context, asyncStub).getConfigurationAlpha1(envelop, it) - ) - ).map( - it -> { - try { - return buildConfigurationItem(it.getItems(0)); - } catch (IOException ex) { - throw DaprException.propagate(ex); - } - } + return this.getConfigurationAlpha1(envelop).map( + it -> it.get(0) ); } catch (Exception ex) { return DaprException.wrapMono(ex); @@ -731,42 +719,63 @@ public Mono> getConfigurations(GetBulkConfigurationReque try { final String configurationStoreName = request.getStoreName(); final List keys = request.getKeys(); - if((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { + if ((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { throw new IllegalArgumentException("Configuration Store Name cannot be null or empty."); } + if (keys.isEmpty() || keys == null) { + throw new IllegalArgumentException("Keys can not be empty or null"); + } DaprProtos.GetConfigurationRequest.Builder builder = DaprProtos.GetConfigurationRequest.newBuilder() - .setStoreName(configurationStoreName); + .setStoreName(configurationStoreName).addAllKeys(keys); - DaprProtos.GetConfigurationRequest tempEnvelop = null; - if(keys.isEmpty() || keys == null) { - tempEnvelop = builder.build(); - } - else { - tempEnvelop = builder.addAllKeys(keys).build(); + DaprProtos.GetConfigurationRequest envelop = builder.build(); + return this.getConfigurationAlpha1(envelop); + + } catch (Exception ex) { + return DaprException.wrapMono(ex); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getAllConfigurations(GetBulkConfigurationRequest request) { + try { + final String configurationStoreName = request.getStoreName(); + if ((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { + throw new IllegalArgumentException("Configuration Store Name cannot be null or empty."); } - DaprProtos.GetConfigurationRequest envelop = tempEnvelop; - return Mono.subscriberContext().flatMap( - context -> - this.createMono( - it -> intercept(context, asyncStub).getConfigurationAlpha1(envelop, it) - ) - ).map( - it -> - it.getItemsList().stream() - .map(b -> { - try { - return buildConfigurationItem(b); - } catch (Exception e) { - throw DaprException.propagate(e); - } - }).collect(Collectors.toList()) - ); + DaprProtos.GetConfigurationRequest.Builder builder = DaprProtos.GetConfigurationRequest.newBuilder() + .setStoreName(configurationStoreName); + + DaprProtos.GetConfigurationRequest envelop = builder.build(); + return this.getConfigurationAlpha1(envelop); } catch (Exception ex) { return DaprException.wrapMono(ex); } } + private Mono> getConfigurationAlpha1(DaprProtos.GetConfigurationRequest envelop) { + return Mono.subscriberContext().flatMap( + context -> + this.createMono( + it -> intercept(context, asyncStub).getConfigurationAlpha1(envelop, it) + ) + ).map( + it -> + it.getItemsList().stream() + .map(b -> { + try { + return buildConfigurationItem(b); + } catch (Exception e) { + throw DaprException.propagate(e); + } + }).collect(Collectors.toList()) + ); + } + /** * {@inheritDoc} */ @@ -804,11 +813,11 @@ public Flux> subscribeToConfigurations(SubscribeConfigur } /** - * Build a new Configuration Item from provided parameter + * Build a new Configuration Item from provided parameter. * * @param configurationItem CommonProtos.ConfigurationItem * @return io.dapr.client.domain.ConfigurationItem - * @throws IOException + * @throws IOException throws IOException */ private ConfigurationItem buildConfigurationItem( CommonProtos.ConfigurationItem configurationItem) throws IOException { @@ -869,11 +878,11 @@ private Flux createFlux(Consumer> consumer) { return Flux.create(sink -> DaprException.wrap(() -> consumer.accept(createStreamObserver(sink))).run()); } - private StreamObserver createStreamObserver(FluxSink sink) { + private StreamObserver createStreamObserver(MonoSink sink) { return new StreamObserver() { @Override public void onNext(T value) { - sink.next(value); + sink.success(value); } @Override @@ -883,16 +892,16 @@ public void onError(Throwable t) { @Override public void onCompleted() { - sink.complete(); + sink.success(); } }; } - private StreamObserver createStreamObserver(MonoSink sink) { + private StreamObserver createStreamObserver(FluxSink sink) { return new StreamObserver() { @Override public void onNext(T value) { - sink.success(value); + sink.next(value); } @Override @@ -902,7 +911,7 @@ public void onError(Throwable t) { @Override public void onCompleted() { - sink.success(); + sink.complete(); } }; } diff --git a/sdk/src/main/java/io/dapr/client/DaprClientHttp.java b/sdk/src/main/java/io/dapr/client/DaprClientHttp.java index 10c6096332..de01836e5e 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientHttp.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientHttp.java @@ -15,10 +15,13 @@ import com.fasterxml.jackson.databind.JsonNode; import com.google.common.base.Strings; +import io.dapr.client.domain.ConfigurationItem; import io.dapr.client.domain.DeleteStateRequest; import io.dapr.client.domain.ExecuteStateTransactionRequest; +import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.GetBulkSecretRequest; import io.dapr.client.domain.GetBulkStateRequest; +import io.dapr.client.domain.GetConfigurationRequest; import io.dapr.client.domain.GetSecretRequest; import io.dapr.client.domain.GetStateRequest; import io.dapr.client.domain.HttpExtension; @@ -28,12 +31,9 @@ import io.dapr.client.domain.SaveStateRequest; import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; +import io.dapr.client.domain.SubscribeConfigurationRequest; import io.dapr.client.domain.TransactionalStateOperation; import io.dapr.client.domain.TransactionalStateRequest; -import io.dapr.client.domain.ConfigurationItem; -import io.dapr.client.domain.GetConfigurationRequest; -import io.dapr.client.domain.GetBulkConfigurationRequest; -import io.dapr.client.domain.SubscribeConfigurationRequest; import io.dapr.config.Properties; import io.dapr.exceptions.DaprException; import io.dapr.serializer.DaprObjectSerializer; @@ -686,6 +686,14 @@ public Mono> getConfigurations(GetBulkConfigurationReque throw new DaprException("501", "Implementation not supported"); } + /** + * {@inheritDoc} + */ + @Override + public Mono> getAllConfigurations(GetBulkConfigurationRequest request) { + throw new DaprException("501", "Implementation not supported"); + } + /** * {@inheritDoc} */ diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java index af1e32db39..5bbeb4ee2a 100644 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java @@ -13,74 +13,131 @@ import reactor.core.publisher.Mono; import java.util.List; +import java.util.Map; -/** - * A Client to be used for all Preview APIs - */ public interface DaprPreviewClient extends AutoCloseable { - /** - * Waits for the sidecar, giving up after timeout. - * @param timeoutInMilliseconds Timeout in milliseconds to wait for sidecar. - * @return a Mono plan of type Void. - */ - Mono waitForSidecar(int timeoutInMilliseconds); - - /** - * Gracefully shutdown the dapr runtime. - * - * @return a Mono plan of type Void. - */ - Mono shutdown(); - - /** - * Retrieve a configuration based on a provided key - * - * @param storeName Name of the configuration store - * @param key key of the configuration item which is to be retrieved - * @return Mono of the Configuration Item - */ - Mono getConfiguration(String storeName, String key); - - /** - * Retrieve a configuration based on a provided request object - * - * @param request request for retrieving Configuration for a single key - * @return Mono of the Configuration Item - */ - Mono getConfiguration(GetConfigurationRequest request); - - /** - * Retrieve List of configurations based on a provided variable number of keys - * - * @param storeName Name of the configuration store - * @param keys keys of the configurations which are to be retrieved - * @return Mono of List of ConfigurationItems - */ - Mono> getConfigurations(String storeName, String... keys); - - /** - * Retrieve List of configurations based on a provided configuration request object - * @param request request for retrieving Configurations for a list keys - * @return Mono of List of ConfigurationItems - */ - Mono> getConfigurations(GetBulkConfigurationRequest request); - - /** - * Subscribe to the keys for any change - * - * @param storeName Name of the configuration store - * @param keys keys of the configurations which are to be subscribed - * @return Flux of List of configuration items - */ - Flux> subscribeToConfigurations(String storeName, String... keys); - - /** - * Subscribe to the keys for any change - * - * @param request request for subscribing to any change for the given keys in request - * @return Flux of List of configuration items - */ - Flux> subscribeToConfigurations(SubscribeConfigurationRequest request); + /** + * Waits for the sidecar, giving up after timeout. + * + * @param timeoutInMilliseconds Timeout in milliseconds to wait for sidecar. + * @return a Mono plan of type Void. + */ + Mono waitForSidecar(int timeoutInMilliseconds); + + /** + * Gracefully shutdown the dapr runtime. + * + * @return a Mono plan of type Void. + */ + Mono shutdown(); + + /** + * Retrieve a configuration based on a provided key. + * + * @param storeName Name of the configuration store + * @param key key of the configuration item which is to be retrieved + * @return Mono of the Configuration Item + */ + Mono getConfiguration(String storeName, String key); + + /** + * Retrieve a configuration based on a provided key. + * + * @param storeName Name of the configuration store + * @param key key of the configuration item which is to be retrieved + * @param metadata optional metadata + * @return Mono of the Configuration Item + */ + Mono getConfiguration(String storeName, String key, Map metadata); + + /** + * Retrieve a configuration based on a provided request object. + * + * @param request request for retrieving Configuration for a single key + * @return Mono of the Configuration Item + */ + Mono getConfiguration(GetConfigurationRequest request); + + /** + * Retrieve List of configurations based on a provided variable number of keys. + * + * @param storeName Name of the configuration store + * @param keys keys of the configurations which are to be retrieved + * @return Mono of List of ConfigurationItems + */ + Mono> getConfigurations(String storeName, String... keys); + + /** + * Retrieve List of configurations based on a provided variable number of keys. + * + * @param storeName Name of the configuration store + * @param keys keys of the configurations which are to be retrieved + * @param metadata optional metadata + * @return Mono of List of ConfigurationItems + */ + Mono> getConfigurations(String storeName, List keys, Map metadata); + + /** + * Retrieve List of configurations based on a provided configuration request object. + * + * @param request request for retrieving Configurations for a list keys + * @return Mono of List of ConfigurationItems + */ + + Mono> getConfigurations(GetBulkConfigurationRequest request); + + /** + * Retrieve List of configurations based on a provided configuration request object. + * + * @param storeName Name of the configuration store + * @return Mono of List of ConfigurationItems + */ + Mono> getAllConfigurations(String storeName); + + /** + * Retrieve List of configurations based on a provided configuration request object. + * + * @param storeName Name of the configuration store + * @param metadata optional metadata + * @return Mono of List of ConfigurationItems + */ + Mono> getAllConfigurations(String storeName, Map metadata); + + /** + * Retrieve List of configurations based on a provided configuration request object. + * + * @param request request for retrieving Configurations for a list keys + * @return Mono of List of ConfigurationItems + */ + Mono> getAllConfigurations(GetBulkConfigurationRequest request); + + /** + * Subscribe to the keys for any change. + * + * @param storeName Name of the configuration store + * @param keys keys of the configurations which are to be subscribed + * @return Flux of List of configuration items + */ + Flux> subscribeToConfigurations(String storeName, String... keys); + + /** + * Subscribe to the keys for any change. + * + * @param storeName Name of the configuration store + * @param keys keys of the configurations which are to be subscribed + * @param metadata optional metadata + * @return Flux of List of configuration items + */ + Flux> subscribeToConfigurations(String storeName, List keys, + Map metadata); + + /** + * Subscribe to the keys for any change. + * + * @param request request for subscribing to any change for the given keys in request + * @return Flux of List of configuration items + */ + Flux> subscribeToConfigurations(SubscribeConfigurationRequest request); } diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java index e87145757f..21eb90dbbe 100644 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + package io.dapr.client; import io.dapr.config.Properties; @@ -11,142 +16,146 @@ public class DaprPreviewClientBuilder { - /** - * Determine if this builder will create GRPC clients instead of HTTP clients. - */ - private final DaprApiProtocol apiProtocol; - - /** - * Determine if this builder will use HTTP client for service method invocation APIs. - */ - private final DaprApiProtocol methodInvocationApiProtocol; - - /** - * Builder for Dapr's HTTP Client. - */ - private final DaprHttpBuilder daprHttpBuilder; - - /** - * Serializer used for request and response objects in DaprClient. - */ - private DaprObjectSerializer objectSerializer; - - /** - * Serializer used for state objects in DaprClient. - */ - private DaprObjectSerializer stateSerializer; - - /** - * Creates a constructor for DaprClient. - * - * {@link DefaultObjectSerializer} is used for object and state serializers by defaul but is not recommended - * for production scenarios. - */ - public DaprPreviewClientBuilder() { - this.objectSerializer = new DefaultObjectSerializer(); - this.stateSerializer = new DefaultObjectSerializer(); - this.apiProtocol = Properties.API_PROTOCOL.get(); - this.methodInvocationApiProtocol = Properties.API_METHOD_INVOCATION_PROTOCOL.get(); - this.daprHttpBuilder = new DaprHttpBuilder(); - } - - /** - * Sets the serializer for objects to be sent and received from Dapr. - * See {@link DefaultObjectSerializer} as possible serializer for non-production scenarios. - * - * @param objectSerializer Serializer for objects to be sent and received from Dapr. - * @return This instance. - */ - public DaprPreviewClientBuilder withObjectSerializer(DaprObjectSerializer objectSerializer) { - if (objectSerializer == null) { - throw new IllegalArgumentException("Object serializer is required"); - } - - if (objectSerializer.getContentType() == null || objectSerializer.getContentType().isEmpty()) { - throw new IllegalArgumentException("Content Type should not be null or empty"); - } - - this.objectSerializer = objectSerializer; - return this; - } - - /** - * Sets the serializer for objects to be persisted. - * See {@link DefaultObjectSerializer} as possible serializer for non-production scenarios. - * - * @param stateSerializer Serializer for objects to be persisted. - * @return This instance. - */ - public DaprPreviewClientBuilder withStateSerializer(DaprObjectSerializer stateSerializer) { - if (stateSerializer == null) { - throw new IllegalArgumentException("State serializer is required"); - } - - this.stateSerializer = stateSerializer; - return this; - } - - /** - * Build an instance of the Client based on the provided setup. - * - * @return an instance of the setup Client - * @throws IllegalStateException if any required field is missing - */ - public DaprPreviewClient build() { - if (this.apiProtocol != this.methodInvocationApiProtocol) { - return new DaprPreviewClientProxy(buildDaprPreviewClient(this.apiProtocol), buildDaprPreviewClient(this.methodInvocationApiProtocol)); - } - - return buildDaprPreviewClient(this.apiProtocol); - } - - /** - * Creates an instance of a Dapr Client based on the chosen protocol. - * - * @param protocol Dapr API's protocol. - * @return the GRPC Client. - * @throws IllegalStateException if either host is missing or if port is missing or a negative number. - */ - private DaprPreviewClient buildDaprPreviewClient(DaprApiProtocol protocol) { - if (protocol == null) { - throw new IllegalStateException("Protocol is required."); - } - - switch (protocol) { - case GRPC: return buildDaprClientGrpc(); - case HTTP: return buildDaprClientHttp(); - default: throw new IllegalStateException("Unsupported protocol: " + protocol.name()); - } - } - - /** - * Creates an instance of the GPRC Client. - * - * @return the GRPC Client. - * @throws IllegalStateException if either host is missing or if port is missing or a negative number. - */ - private DaprPreviewClient buildDaprClientGrpc() { - int port = Properties.GRPC_PORT.get(); - if (port <= 0) { - throw new IllegalArgumentException("Invalid port."); - } - ManagedChannel channel = ManagedChannelBuilder.forAddress( - Properties.SIDECAR_IP.get(), port).usePlaintext().build(); - Closeable closeableChannel = () -> { - if (channel != null && !channel.isShutdown()) { - channel.shutdown(); - } - }; - DaprGrpc.DaprStub asyncStub = DaprGrpc.newStub(channel); - return new DaprClientGrpc(closeableChannel, asyncStub, this.objectSerializer, this.stateSerializer); - } - - /** - * Creates and instance of DaprClient over HTTP. - * - * @return DaprClient over HTTP. - */ - private DaprPreviewClient buildDaprClientHttp() { - return new DaprClientHttp(this.daprHttpBuilder.build(), this.objectSerializer, this.stateSerializer); - } + /** + * Determine if this builder will create GRPC clients instead of HTTP clients. + */ + private final DaprApiProtocol apiProtocol; + + /** + * Determine if this builder will use HTTP client for service method invocation APIs. + */ + private final DaprApiProtocol methodInvocationApiProtocol; + + /** + * Builder for Dapr's HTTP Client. + */ + private final DaprHttpBuilder daprHttpBuilder; + + /** + * Serializer used for request and response objects in DaprClient. + */ + private DaprObjectSerializer objectSerializer; + + /** + * Serializer used for state objects in DaprClient. + */ + private DaprObjectSerializer stateSerializer; + + /** + * Creates a constructor for DaprClient. + * + * {@link DefaultObjectSerializer} is used for object and state serializers by defaul but is not recommended + * for production scenarios. + */ + public DaprPreviewClientBuilder() { + this.objectSerializer = new DefaultObjectSerializer(); + this.stateSerializer = new DefaultObjectSerializer(); + this.apiProtocol = Properties.API_PROTOCOL.get(); + this.methodInvocationApiProtocol = Properties.API_METHOD_INVOCATION_PROTOCOL.get(); + this.daprHttpBuilder = new DaprHttpBuilder(); + } + + /** + * Sets the serializer for objects to be sent and received from Dapr. + * See {@link DefaultObjectSerializer} as possible serializer for non-production scenarios. + * + * @param objectSerializer Serializer for objects to be sent and received from Dapr. + * @return This instance. + */ + public DaprPreviewClientBuilder withObjectSerializer(DaprObjectSerializer objectSerializer) { + if (objectSerializer == null) { + throw new IllegalArgumentException("Object serializer is required"); + } + + if (objectSerializer.getContentType() == null || objectSerializer.getContentType().isEmpty()) { + throw new IllegalArgumentException("Content Type should not be null or empty"); + } + + this.objectSerializer = objectSerializer; + return this; + } + + /** + * Sets the serializer for objects to be persisted. + * See {@link DefaultObjectSerializer} as possible serializer for non-production scenarios. + * + * @param stateSerializer Serializer for objects to be persisted. + * @return This instance. + */ + public DaprPreviewClientBuilder withStateSerializer(DaprObjectSerializer stateSerializer) { + if (stateSerializer == null) { + throw new IllegalArgumentException("State serializer is required"); + } + + this.stateSerializer = stateSerializer; + return this; + } + + /** + * Build an instance of the Client based on the provided setup. + * + * @return an instance of the setup Client + * @throws IllegalStateException if any required field is missing + */ + public DaprPreviewClient build() { + if (this.apiProtocol != this.methodInvocationApiProtocol) { + return new DaprPreviewClientProxy(buildDaprPreviewClient(this.apiProtocol), + buildDaprPreviewClient(this.methodInvocationApiProtocol)); + } + + return buildDaprPreviewClient(this.apiProtocol); + } + + /** + * Creates an instance of a Dapr Client based on the chosen protocol. + * + * @param protocol Dapr API's protocol. + * @return the GRPC Client. + * @throws IllegalStateException if either host is missing or if port is missing or a negative number. + */ + private DaprPreviewClient buildDaprPreviewClient(DaprApiProtocol protocol) { + if (protocol == null) { + throw new IllegalStateException("Protocol is required."); + } + + switch (protocol) { + case GRPC: + return buildDaprClientGrpc(); + case HTTP: + return buildDaprClientHttp(); + default: + throw new IllegalStateException("Unsupported protocol: " + protocol.name()); + } + } + + /** + * Creates an instance of the GPRC Client. + * + * @return the GRPC Client. + * @throws IllegalStateException if either host is missing or if port is missing or a negative number. + */ + private DaprPreviewClient buildDaprClientGrpc() { + int port = Properties.GRPC_PORT.get(); + if (port <= 0) { + throw new IllegalArgumentException("Invalid port."); + } + ManagedChannel channel = ManagedChannelBuilder.forAddress( + Properties.SIDECAR_IP.get(), port).usePlaintext().build(); + Closeable closeableChannel = () -> { + if (channel != null && !channel.isShutdown()) { + channel.shutdown(); + } + }; + DaprGrpc.DaprStub asyncStub = DaprGrpc.newStub(channel); + return new DaprClientGrpc(closeableChannel, asyncStub, this.objectSerializer, this.stateSerializer); + } + + /** + * Creates and instance of DaprClient over HTTP. + * + * @return DaprClient over HTTP. + */ + private DaprPreviewClient buildDaprClientHttp() { + return new DaprClientHttp(this.daprHttpBuilder.build(), this.objectSerializer, this.stateSerializer); + } } diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java index e69e09dd8e..169e645a26 100644 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java @@ -1,122 +1,178 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + package io.dapr.client; import io.dapr.client.domain.ConfigurationItem; -import io.dapr.client.domain.GetConfigurationRequest; import io.dapr.client.domain.GetBulkConfigurationRequest; +import io.dapr.client.domain.GetConfigurationRequest; import io.dapr.client.domain.SubscribeConfigurationRequest; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.List; +import java.util.Map; public class DaprPreviewClientProxy implements DaprPreviewClient { - /** - * Client for all API invocations. - */ - private final DaprPreviewClient client; - - /** - * Client to override Dapr's service invocation APIs. - */ - private final DaprPreviewClient methodInvocationOverrideClient; - - /** - * Constructor with delegate client. - * - * @param client Client for all API invocations. - * @see DaprPreviewClientBuilder - */ - DaprPreviewClientProxy(DaprPreviewClient client) { - this(client, client); - } - - /** - * Constructor with delegate client and override client for Dapr's method invocation APIs. - * - * @param client Client for all API invocations, except override below. - * @param methodInvocationOverrideClient Client to override Dapr's service invocation APIs. - * @see DaprClientBuilder - */ - DaprPreviewClientProxy( - DaprPreviewClient client, - DaprPreviewClient methodInvocationOverrideClient) { - this.client = client; - this.methodInvocationOverrideClient = methodInvocationOverrideClient; - } - - /** - * {@inheritDoc} - */ - @Override - public Mono waitForSidecar(int timeoutInMilliseconds) { - return client.waitForSidecar(timeoutInMilliseconds); - } - - /** - * {@inheritDoc} - */ - @Override - public void close() throws Exception { - client.close(); - if (client != methodInvocationOverrideClient) { - methodInvocationOverrideClient.close(); - } - } - - /** - * {@inheritDoc} - */ - @Override - public Mono shutdown() { - return client.shutdown(); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono getConfiguration(String storeName, String key) { - return client.getConfiguration(storeName, key); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono getConfiguration(GetConfigurationRequest request) { - return client.getConfiguration(request); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono> getConfigurations(String storeName, String... keys) { - return client.getConfigurations(storeName, keys); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono> getConfigurations(GetBulkConfigurationRequest request) { - return client.getConfigurations(request); - } - - /** - * {@inheritDoc} - */ - @Override - public Flux> subscribeToConfigurations(String storeName, String... keys) { - return client.subscribeToConfigurations(storeName, keys); - } - - /** - * {@inheritDoc} - */ - @Override - public Flux> subscribeToConfigurations(SubscribeConfigurationRequest request) { - return client.subscribeToConfigurations(request); - } + /** + * Client for all API invocations. + */ + private final DaprPreviewClient client; + + /** + * Client to override Dapr's service invocation APIs. + */ + private final DaprPreviewClient methodInvocationOverrideClient; + + /** + * Constructor with delegate client. + * + * @param client Client for all API invocations. + * @see DaprPreviewClientBuilder + */ + DaprPreviewClientProxy(DaprPreviewClient client) { + this(client, client); + } + + /** + * Constructor with delegate client and override client for Dapr's method invocation APIs. + * + * @param client Client for all API invocations, except override below. + * @param methodInvocationOverrideClient Client to override Dapr's service invocation APIs. + * @see DaprClientBuilder + */ + DaprPreviewClientProxy( + DaprPreviewClient client, + DaprPreviewClient methodInvocationOverrideClient) { + this.client = client; + this.methodInvocationOverrideClient = methodInvocationOverrideClient; + } + + /** + * {@inheritDoc} + */ + @Override + public Mono waitForSidecar(int timeoutInMilliseconds) { + return client.waitForSidecar(timeoutInMilliseconds); + } + + /** + * {@inheritDoc} + */ + @Override + public void close() throws Exception { + client.close(); + if (client != methodInvocationOverrideClient) { + methodInvocationOverrideClient.close(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Mono shutdown() { + return client.shutdown(); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono getConfiguration(String storeName, String key) { + return client.getConfiguration(storeName, key); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono getConfiguration(String storeName, String key, Map metadata) { + return client.getConfiguration(storeName, key, metadata); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono getConfiguration(GetConfigurationRequest request) { + return client.getConfiguration(request); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getConfigurations(String storeName, String... keys) { + return client.getConfigurations(storeName, keys); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getConfigurations(String storeName, List keys, + Map metadata) { + return client.getConfigurations(storeName, keys, metadata); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getConfigurations(GetBulkConfigurationRequest request) { + return client.getConfigurations(request); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getAllConfigurations(String storeName) { + return client.getAllConfigurations(storeName); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getAllConfigurations(String storeName, Map metadata) { + return client.getAllConfigurations(storeName, metadata); + } + + /** + * {@inheritDoc} + */ + @Override + public Mono> getAllConfigurations(GetBulkConfigurationRequest request) { + return client.getAllConfigurations(request); + } + + /** + * {@inheritDoc} + */ + @Override + public Flux> subscribeToConfigurations(String storeName, String... keys) { + return client.subscribeToConfigurations(storeName, keys); + } + + /** + * {@inheritDoc} + */ + @Override + public Flux> subscribeToConfigurations(String storeName, List keys, + Map metadata) { + return client.subscribeToConfigurations(storeName, keys, metadata); + } + + /** + * {@inheritDoc} + */ + @Override + public Flux> subscribeToConfigurations(SubscribeConfigurationRequest request) { + return client.subscribeToConfigurations(request); + } } diff --git a/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java b/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java index 214775e07e..aebb43de3e 100644 --- a/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java +++ b/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java @@ -1,34 +1,46 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + package io.dapr.client.domain; -import java.util.HashMap; import java.util.Map; public class ConfigurationItem { - private final String key; - private final String value; - private final String version; - private final Map metadata; - - public ConfigurationItem(String key, String value, String version, Map metadata) { - this.key = key; - this.value = value; - this.version = version; - this.metadata = metadata; - } - - public String getKey() { - return key; - } - - public String getValue() { - return value; - } - - public String getVersion() { - return version; - } - - public Map getMetadata() { - return metadata; - } + private final String key; + private final String value; + private final String version; + private final Map metadata; + + /** + * Constructor for a configuration Item. + * + * @param key key of the configuration item + * @param value value for the provided key + * @param version version of the configuration item + * @param metadata additional information + */ + public ConfigurationItem(String key, String value, String version, Map metadata) { + this.key = key; + this.value = value; + this.version = version; + this.metadata = metadata; + } + + public String getKey() { + return key; + } + + public String getValue() { + return value; + } + + public String getVersion() { + return version; + } + + public Map getMetadata() { + return metadata; + } } diff --git a/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java index bf1bfd79e4..cb4c890701 100644 --- a/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java +++ b/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + package io.dapr.client.domain; import java.util.ArrayList; @@ -6,29 +11,29 @@ import java.util.Map; public class GetBulkConfigurationRequest { - private final String storeName; - private final List keys; - private Map metadata; - - public GetBulkConfigurationRequest(String storeName, List keys) { - this.storeName = storeName; - this.keys = keys == null ? Collections.unmodifiableList(new ArrayList<>()) : Collections.unmodifiableList(keys); - } - - public GetBulkConfigurationRequest setMetadata(Map metadata) { - this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata); - return this; - } - - public String getStoreName() { - return storeName; - } - - public List getKeys() { - return keys; - } - - public Map getMetadata() { - return metadata; - } + private final String storeName; + private final List keys; + private Map metadata; + + public GetBulkConfigurationRequest(String storeName, List keys) { + this.storeName = storeName; + this.keys = keys == null ? Collections.unmodifiableList(new ArrayList<>()) : Collections.unmodifiableList(keys); + } + + public GetBulkConfigurationRequest setMetadata(Map metadata) { + this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata); + return this; + } + + public String getStoreName() { + return storeName; + } + + public List getKeys() { + return keys; + } + + public Map getMetadata() { + return metadata; + } } diff --git a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java index a9473ed543..1669f35010 100644 --- a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java +++ b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + package io.dapr.client.domain; import java.util.Collections; @@ -5,29 +10,29 @@ import java.util.Map; public class GetConfigurationRequest { - private final String storeName; - private final String key; - private Map metadata; - - public GetConfigurationRequest(String storeName, String key) { - this.storeName = storeName; - this.key = key; - } - - public GetConfigurationRequest setMetadata(Map metadata) { - this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata); - return this; - } - - public String getStoreName() { - return storeName; - } - - public String getKey() { - return key; - } - - public Map getMetadata() { - return metadata; - } + private final String storeName; + private final String key; + private Map metadata; + + public GetConfigurationRequest(String storeName, String key) { + this.storeName = storeName; + this.key = key; + } + + public GetConfigurationRequest setMetadata(Map metadata) { + this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata); + return this; + } + + public String getStoreName() { + return storeName; + } + + public String getKey() { + return key; + } + + public Map getMetadata() { + return metadata; + } } diff --git a/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java index 37a0340ee7..415a0343d4 100644 --- a/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java +++ b/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java @@ -1,34 +1,38 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + package io.dapr.client.domain; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; public class SubscribeConfigurationRequest { - private final String storeName; - private final List keys; - private Map metadata; - - public SubscribeConfigurationRequest(String storeName, List keys) { - this.storeName = storeName; - this.keys = Collections.unmodifiableList(keys); - } - - public SubscribeConfigurationRequest setMetadata(Map metadata) { - this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata); - return this; - } - - public String getStoreName() { - return storeName; - } - - public List getKeys() { - return keys; - } - - public Map getMetadata() { - return metadata; - } + private final String storeName; + private final List keys; + private Map metadata; + + public SubscribeConfigurationRequest(String storeName, List keys) { + this.storeName = storeName; + this.keys = Collections.unmodifiableList(keys); + } + + public SubscribeConfigurationRequest setMetadata(Map metadata) { + this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata); + return this; + } + + public String getStoreName() { + return storeName; + } + + public List getKeys() { + return keys; + } + + public Map getMetadata() { + return metadata; + } } diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientBuilderTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientBuilderTest.java new file mode 100644 index 0000000000..e1e1e289e9 --- /dev/null +++ b/sdk/src/test/java/io/dapr/client/DaprPreviewClientBuilderTest.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + +package io.dapr.client; + +import io.dapr.serializer.DaprObjectSerializer; +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DaprPreviewClientBuilderTest { + + @Test + public void build() { + DaprObjectSerializer objectSerializer = mock(DaprObjectSerializer.class); + when(objectSerializer.getContentType()).thenReturn("application/json"); + DaprObjectSerializer stateSerializer = mock(DaprObjectSerializer.class); + DaprPreviewClientBuilder daprPreviewClientBuilder = new DaprPreviewClientBuilder(); + daprPreviewClientBuilder.withObjectSerializer(objectSerializer); + daprPreviewClientBuilder.withStateSerializer(stateSerializer); + DaprPreviewClient daprPreviewClient = daprPreviewClientBuilder.build(); + assertNotNull(daprPreviewClient); + } + + @Test(expected = IllegalArgumentException.class) + public void noObjectSerializer() { + new DaprPreviewClientBuilder().withObjectSerializer(null); + } + + @Test(expected = IllegalArgumentException.class) + public void blankContentTypeInObjectSerializer() { + new DaprPreviewClientBuilder().withObjectSerializer(mock(DaprObjectSerializer.class)); + } + + @Test(expected = IllegalArgumentException.class) + public void noStateSerializer() { + new DaprPreviewClientBuilder().withStateSerializer(null); + } +} diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java new file mode 100644 index 0000000000..23a2c9f9e0 --- /dev/null +++ b/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + +package io.dapr.client; + + +import io.dapr.client.domain.ConfigurationItem; +import io.dapr.config.Properties; +import io.dapr.serializer.DefaultObjectSerializer; +import io.dapr.v1.CommonProtos; +import io.dapr.v1.DaprGrpc; +import io.dapr.v1.DaprProtos; +import io.grpc.stub.StreamObserver; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.stubbing.Answer; + +import java.io.Closeable; +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import static io.dapr.utils.TestUtils.findFreePort; +import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +public class DaprPreviewClientGrpcTest { + + private static final String CONFIG_STORE_NAME = "MyConfigStore"; + + private Closeable closeable; + private DaprGrpc.DaprStub daprStub; + private DaprPreviewClient previewClient; + private ObjectSerializer serializer; + + @Before + public void setup() throws IOException { + closeable = mock(Closeable.class); + daprStub = mock(DaprGrpc.DaprStub.class); + when(daprStub.withInterceptors(any())).thenReturn(daprStub); + previewClient = new DaprPreviewClientProxy(new DaprClientGrpc( + closeable, daprStub, new DefaultObjectSerializer(), new DefaultObjectSerializer())); + serializer = new ObjectSerializer(); + doNothing().when(closeable).close(); + } + + @After + public void tearDown() throws Exception { + previewClient.close(); + verify(closeable).close(); + verifyNoMoreInteractions(closeable); + } + + @Test + public void waitForSidecarTimeout() throws Exception { + int port = findFreePort(); + System.setProperty(Properties.GRPC_PORT.getName(), Integer.toString(port)); + assertThrows(RuntimeException.class, () -> previewClient.waitForSidecar(1).block()); + } + + @Test + public void waitForSidecarTimeoutOK() throws Exception { + try (ServerSocket serverSocket = new ServerSocket(0)) { + final int port = serverSocket.getLocalPort(); + System.setProperty(Properties.GRPC_PORT.getName(), Integer.toString(port)); + Thread t = new Thread(() -> { + try { + try (Socket socket = serverSocket.accept()) { + } + } catch (IOException e) { + } + }); + t.start(); + previewClient.waitForSidecar(10000).block(); + } + } + + @Test + public void getConfigurationIllegalArgumentExceptionTest() { + // Empty Store name + assertThrows(IllegalArgumentException.class, () -> { + previewClient.getConfiguration("", "key1").block(); + }); + //Empty store name + assertThrows(IllegalArgumentException.class, () -> { + previewClient.getConfigurations("", "key1").block(); + }); + //Empty store name + assertThrows(IllegalArgumentException.class, () -> { + previewClient.getAllConfigurations("").block(); + }); + // Empty key + assertThrows(IllegalArgumentException.class, () -> { + previewClient.getConfiguration(CONFIG_STORE_NAME, "").block(); + }); + // Empty key + assertThrows(IllegalArgumentException.class, () -> { + previewClient.getConfigurations(CONFIG_STORE_NAME, "").block(); + }); + } + + @Test + public void getSingleConfigurationTest() { + Map metadata = new HashMap<>(); + metadata.put("meta1", "value1"); + DaprProtos.GetConfigurationResponse responseEnvelope = DaprProtos.GetConfigurationResponse.newBuilder() + .addItems(CommonProtos.ConfigurationItem.newBuilder() + .setKey("configkey1") + .setValue("configvalue1") + .setVersion("1") + .putAllMetadata(metadata) + .build() + ).build(); + doAnswer((Answer) invocation -> { + StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; + observer.onNext(responseEnvelope); + observer.onCompleted(); + return null; + }).when(daprStub).getConfigurationAlpha1(any(DaprProtos.GetConfigurationRequest.class), any()); + + ConfigurationItem ci = previewClient.getConfiguration(CONFIG_STORE_NAME, "configkey1").block(); + assertEquals("configkey1", ci.getKey()); + assertEquals("configvalue1", ci.getValue()); + assertEquals(metadata, ci.getMetadata()); + assertEquals("1", ci.getVersion()); + } + + @Test + public void getMultipleConfigurationTest() { + Map metadata = new HashMap<>(); + metadata.put("meta1", "value1"); + DaprProtos.GetConfigurationResponse responseEnvelope = DaprProtos.GetConfigurationResponse.newBuilder() + .addItems(CommonProtos.ConfigurationItem.newBuilder() + .setKey("configkey1") + .setValue("configvalue1") + .setVersion("1") + .putAllMetadata(metadata) + .build()) + .addItems(CommonProtos.ConfigurationItem.newBuilder() + .setKey("configkey2") + .setValue("configvalue2") + .setVersion("1") + .putAllMetadata(metadata) + .build()) + .build(); + + doAnswer((Answer) invocation -> { + StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; + observer.onNext(responseEnvelope); + observer.onCompleted(); + return null; + }).when(daprStub).getConfigurationAlpha1(any(DaprProtos.GetConfigurationRequest.class), any()); + + List cis = previewClient.getConfigurations(CONFIG_STORE_NAME, "configkey1","configkey2").block(); + assertEquals(2, cis.size()); + assertEquals("configkey1", cis.stream().findFirst().get().getKey()); + assertEquals("configvalue1", cis.stream().findFirst().get().getValue()); + assertEquals(metadata, cis.stream().findFirst().get().getMetadata()); + assertEquals("1", cis.stream().findFirst().get().getVersion()); + + assertEquals("configkey2", cis.stream().skip(1).findFirst().get().getKey()); + assertEquals("configvalue2", cis.stream().skip(1).findFirst().get().getValue()); + assertEquals(metadata, cis.stream().skip(1).findFirst().get().getMetadata()); + assertEquals("1", cis.stream().skip(1).findFirst().get().getVersion()); + } + + @Test + public void getAllConfigurationTest() { + Map metadata = new HashMap<>(); + metadata.put("meta1", "value1"); + DaprProtos.GetConfigurationResponse responseEnvelope = DaprProtos.GetConfigurationResponse.newBuilder() + .addItems(CommonProtos.ConfigurationItem.newBuilder() + .setKey("configkey1") + .setValue("configvalue1") + .setVersion("1") + .putAllMetadata(metadata) + .build()) + .addItems(CommonProtos.ConfigurationItem.newBuilder() + .setKey("configkey2") + .setValue("configvalue2") + .setVersion("1") + .putAllMetadata(metadata) + .build()) + .build(); + + doAnswer((Answer) invocation -> { + StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; + observer.onNext(responseEnvelope); + observer.onCompleted(); + return null; + }).when(daprStub).getConfigurationAlpha1(any(DaprProtos.GetConfigurationRequest.class), any()); + + List cis = previewClient.getAllConfigurations(CONFIG_STORE_NAME).block(); + assertEquals(2, cis.size()); + } + + @Test + public void subscribeConfigurationTest() { + Map metadata = new HashMap<>(); + metadata.put("meta1", "value1"); + DaprProtos.SubscribeConfigurationResponse responseEnvelope = DaprProtos.SubscribeConfigurationResponse.newBuilder() + .addItems(CommonProtos.ConfigurationItem.newBuilder() + .setKey("configkey1") + .setValue("configvalue1") + .setVersion("1") + .putAllMetadata(metadata) + .build()) + .build(); + + doAnswer((Answer) invocation -> { + StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; + observer.onNext(responseEnvelope); + observer.onCompleted(); + return null; + }).when(daprStub).subscribeConfigurationAlpha1(any(DaprProtos.SubscribeConfigurationRequest.class), any()); + + Iterator> itr = previewClient.subscribeToConfigurations(CONFIG_STORE_NAME, "configkey1").toIterable().iterator(); + assertTrue(itr.hasNext()); + assertEquals("configkey1", itr.next().get(0).getKey()); + assertFalse(itr.hasNext()); + } +} diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java new file mode 100644 index 0000000000..a41ba026e5 --- /dev/null +++ b/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + +package io.dapr.client; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import io.dapr.config.Properties; +import io.dapr.exceptions.DaprException; +import io.dapr.serializer.DaprObjectSerializer; +import io.dapr.utils.TypeRef; +import okhttp3.OkHttpClient; +import okhttp3.mock.Behavior; +import okhttp3.mock.MockInterceptor; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import reactor.core.publisher.Mono; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; + +import static io.dapr.utils.TestUtils.findFreePort; +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class DaprPreviewClientHttpTest { + private static final String CONFIG_STORE_NAME = "MyConfigurationStore"; + + private DaprPreviewClient daprPreviewClientHttp; + + private DaprPreviewClient daprPreviewClientHttpXML; + + private DaprHttp daprHttp; + + private OkHttpClient okHttpClient; + + private MockInterceptor mockInterceptor; + + @Before + public void setUp() { + mockInterceptor = new MockInterceptor(Behavior.UNORDERED); + okHttpClient = new OkHttpClient.Builder().addInterceptor(mockInterceptor).build(); + daprHttp = new DaprHttp(Properties.SIDECAR_IP.get(), 3000, okHttpClient); + daprPreviewClientHttp = new DaprPreviewClientProxy(new DaprClientHttp(daprHttp)); + daprPreviewClientHttpXML = new DaprPreviewClientProxy( + new DaprClientHttp(daprHttp, new DaprPreviewClientHttpTest.XmlSerializer(), + new DaprPreviewClientHttpTest.XmlSerializer())); + } + + @Test + public void waitForSidecarTimeout() throws Exception { + int port = findFreePort(); + System.setProperty(Properties.HTTP_PORT.getName(), Integer.toString(port)); + daprHttp = new DaprHttp(Properties.SIDECAR_IP.get(), port, okHttpClient); + DaprClientHttp daprClientHttp = new DaprClientHttp(daprHttp); + assertThrows(RuntimeException.class, () -> daprClientHttp.waitForSidecar(1).block()); + } + + @Test + public void waitForSidecarTimeoutOK() throws Exception { + try (ServerSocket serverSocket = new ServerSocket(0)) { + final int port = serverSocket.getLocalPort(); + System.setProperty(Properties.HTTP_PORT.getName(), Integer.toString(port)); + Thread t = new Thread(() -> { + try { + try (Socket socket = serverSocket.accept()) { + } + } catch (IOException e) { + } + }); + t.start(); + daprHttp = new DaprHttp(Properties.SIDECAR_IP.get(), port, okHttpClient); + DaprClientHttp daprClientHttp = new DaprClientHttp(daprHttp); + daprClientHttp.waitForSidecar(10000).block(); + } + } + + @Test + public void getConfigurationWithSingleKey() { + assertThrows(DaprException.class, () -> { + daprPreviewClientHttp.getConfiguration(CONFIG_STORE_NAME, "key").block(); + }); + } + + @Test + public void getConfigurations() { + assertThrows(DaprException.class, () -> { + daprPreviewClientHttp.getConfigurations(CONFIG_STORE_NAME, "key1", "key2").block(); + }); + } + + @Test + public void getAllConfigurations() { + assertThrows(DaprException.class, () -> { + daprPreviewClientHttp.getAllConfigurations(CONFIG_STORE_NAME).block(); + }); + } + + @Test + public void subscribeConfigurations() { + assertThrows(DaprException.class, () -> { + daprPreviewClientHttp.subscribeToConfigurations(CONFIG_STORE_NAME, "key1", "key2"); + }); + } + + @Test + public void closeException() { + DaprHttp daprHttp = Mockito.mock(DaprHttp.class); + Mockito.doThrow(new RuntimeException()).when(daprHttp).close(); + + // This method does not throw DaprException because it already throws RuntimeException and does not call Dapr. + daprPreviewClientHttp = new DaprClientHttp(daprHttp); + assertThrows(RuntimeException.class, () -> daprPreviewClientHttp.close()); + } + + @Test + public void close() throws Exception { + DaprHttp daprHttp = Mockito.mock(DaprHttp.class); + Mockito.doNothing().when(daprHttp).close(); + + // This method does not throw DaprException because IOException is expected by the Closeable interface. + daprPreviewClientHttp = new DaprClientHttp(daprHttp); + daprPreviewClientHttp.close(); + } + + @Test + public void shutdown() throws Exception { + mockInterceptor.addRule() + .post("http://127.0.0.1:3000/v1.0/shutdown") + .respond(204); + + final Mono mono = daprPreviewClientHttp.shutdown(); + assertNull(mono.block()); + } + + private static class XmlSerializer implements DaprObjectSerializer { + + private static final XmlMapper XML_MAPPER = new XmlMapper(); + + @Override + public byte[] serialize(Object o) throws IOException { + return XML_MAPPER.writeValueAsBytes(o); + } + + @Override + public T deserialize(byte[] data, TypeRef type) throws IOException { + return XML_MAPPER.readValue(data, new TypeReference() { + }); + } + + @Override + public String getContentType() { + return "application/xml"; + } + } +} diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientProxyTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientProxyTest.java new file mode 100644 index 0000000000..0a8b9d93ad --- /dev/null +++ b/sdk/src/test/java/io/dapr/client/DaprPreviewClientProxyTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + +package io.dapr.client; + +import io.dapr.client.domain.SubscribeConfigurationRequest; +import org.junit.Test; +import org.mockito.Mockito; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.*; + +import static org.mockito.Mockito.times; + +public class DaprPreviewClientProxyTest { + + @Test + public void getconfigurationAPI() { + DaprPreviewClient client = Mockito.mock(DaprPreviewClient.class); + Mockito.when(client.getConfiguration("store", "key")).thenReturn(Mono.empty()); + Mockito.when(client.getConfigurations("store", "key")).thenReturn(Mono.empty()); + Mockito.when(client.getAllConfigurations("store")).thenReturn(Mono.empty()); + + DaprPreviewClient proxy = new DaprPreviewClientProxy(client); + + proxy.getConfiguration("store", "key").block(); + proxy.getConfigurations("store", "key").block(); + proxy.getAllConfigurations("store").block(); + + Mockito.verify(client, times(1)).getConfiguration("store", "key"); + Mockito.verify(client, times(1)).getConfigurations("store", "key"); + Mockito.verify(client, times(1)).getAllConfigurations("store"); + } + + @Test + public void subscribeConfigurationAPI() { + Map metadata = new HashMap<>(); + List keys = new ArrayList<>(Arrays.asList("key")); + SubscribeConfigurationRequest req = new SubscribeConfigurationRequest("store", keys); + DaprPreviewClient client = Mockito.mock(DaprPreviewClient.class); + Mockito.when(client.subscribeToConfigurations("store", "key")).thenReturn(Flux.empty()); + + DaprPreviewClient proxy = new DaprPreviewClientProxy(client); + + proxy.subscribeToConfigurations("store", "key"); + proxy.subscribeToConfigurations("store", keys, metadata); + proxy.subscribeToConfigurations(req); + + Mockito.verify(client, times(1)).subscribeToConfigurations("store", "key"); + Mockito.verify(client, times(1)).subscribeToConfigurations("store", keys, metadata); + Mockito.verify(client, times(1)).subscribeToConfigurations(req); + } +} From c28105f3746ed6c08de0161c6ed2b0acb32312d3 Mon Sep 17 00:00:00 2001 From: pravinpushkar Date: Fri, 31 Dec 2021 22:40:00 +0530 Subject: [PATCH 04/13] Adding integration test Signed-off-by: pravinpushkar --- sdk-tests/components/redisconfigstore.yaml | 14 +++ .../grpc/ConfigurationClientIT.java | 91 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 sdk-tests/components/redisconfigstore.yaml create mode 100644 sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java diff --git a/sdk-tests/components/redisconfigstore.yaml b/sdk-tests/components/redisconfigstore.yaml new file mode 100644 index 0000000000..5cf0ee23f3 --- /dev/null +++ b/sdk-tests/components/redisconfigstore.yaml @@ -0,0 +1,14 @@ +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: redisconfigstore +spec: + type: configuration.redis + version: v1 + metadata: + - name: redisHost + value: localhost:6379 + - name: redisPassword + value: "" + - name: actorStateStore + value: "true" diff --git a/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java b/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java new file mode 100644 index 0000000000..e82d70d49f --- /dev/null +++ b/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) Microsoft Corporation and Dapr Contributors. + * Licensed under the MIT License. + */ + +package io.dapr.it.configuration.grpc; + +import io.dapr.client.DaprPreviewClient; +import io.dapr.client.DaprPreviewClientBuilder; +import io.dapr.client.domain.ConfigurationItem; +import io.dapr.it.BaseIT; +import io.dapr.it.DaprRun; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import reactor.core.publisher.Flux; + +import java.util.*; + +import static org.junit.Assert.*; + +public class ConfigurationClientIT extends BaseIT { + + private static final String CONFIG_STORE_NAME = "redisconfigstore"; + + private static DaprRun daprRun; + + private static DaprPreviewClient daprPreviewClient; + + private static String key = "myconfig1"; + + private static List keys = new ArrayList<>(Arrays.asList("myconfig1", "myconfig2", "myconfig3")); + + @BeforeClass + public static void init() throws Exception { + /* setup redis configuration store to have below key-value pairs before running the tests. + this step is required as there is no save api for configuration data. + config store name -> redisconfigstore + below 3 key-value pairs - + myconfigkey1-myconfigvalue1 + myconfigkey2-myconfigvalue2 + myconfigkey3-myconfigvalue3 + */ + daprRun = startDaprApp(ConfigurationClientIT.class.getSimpleName(), 5000); + daprRun.switchToGRPC(); + daprPreviewClient = new DaprPreviewClientBuilder().build(); + } + + @AfterClass + public static void tearDown() throws Exception { + daprPreviewClient.close(); + } + + @Test + public void getConfiguration() { + ConfigurationItem ci = daprPreviewClient.getConfiguration(CONFIG_STORE_NAME, "myconfigkey1").block(); + assertEquals(ci.getKey(), "myconfigkey1"); + assertEquals(ci.getValue(), "myconfigvalue1"); + } + + @Test + public void getConfigurationWithEmptyKey() { + assertThrows(IllegalArgumentException.class, () -> { + daprPreviewClient.getConfiguration(CONFIG_STORE_NAME, "").block(); + }); + } + + @Test + public void getConfigurations() { + List cis = daprPreviewClient.getConfigurations(CONFIG_STORE_NAME, "myconfigkey1", "myconfigkey2").block(); + assertTrue(cis.size() == 2); + assertEquals(cis.get(0).getKey(), "myconfigkey1"); + assertEquals(cis.get(1).getValue(), "myconfigvalue2"); + } + + @Test + public void getConfigurationsWithEmptyList() { + List listOfKeys = new ArrayList<>(); + Map metadata = new HashMap<>(); + assertThrows(IllegalArgumentException.class, () -> { + daprPreviewClient.getConfigurations(CONFIG_STORE_NAME, listOfKeys, metadata).block(); + }); + } + + @Test + public void subscribeToConfiguration() { + Flux> outFlux = daprPreviewClient.subscribeToConfigurations(CONFIG_STORE_NAME, "myconfigkey1", "myconfigkey2"); + assertNotNull(outFlux); + } +} From 276debce9956bc82e0a1badb6829df4d1918fbd5 Mon Sep 17 00:00:00 2001 From: pravinpushkar Date: Fri, 31 Dec 2021 23:41:08 +0530 Subject: [PATCH 05/13] Copyright changes Signed-off-by: pravinpushkar --- .../configuration/grpc/ConfigurationClient.java | 14 +++++++++++--- .../java/io/dapr/client/DaprPreviewClient.java | 16 ++++++++++++---- .../io/dapr/client/DaprPreviewClientBuilder.java | 14 +++++++++++--- .../io/dapr/client/DaprPreviewClientProxy.java | 14 +++++++++++--- .../io/dapr/client/domain/ConfigurationItem.java | 14 +++++++++++--- .../domain/GetBulkConfigurationRequest.java | 14 +++++++++++--- .../client/domain/GetConfigurationRequest.java | 14 +++++++++++--- .../domain/SubscribeConfigurationRequest.java | 14 +++++++++++--- 8 files changed, 89 insertions(+), 25 deletions(-) diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java index 9abcfb072b..974de5e99b 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java @@ -1,7 +1,15 @@ /* - * Copyright (c) Microsoft Corporation and Dapr Contributors. - * Licensed under the MIT License. - */ + * Copyright 2021 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ package io.dapr.examples.configuration.grpc; diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java index 5bbeb4ee2a..c6d22da2b2 100644 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java @@ -1,7 +1,15 @@ /* - * Copyright (c) Microsoft Corporation and Dapr Contributors. - * Licensed under the MIT License. - */ + * Copyright 2021 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ package io.dapr.client; @@ -127,7 +135,7 @@ public interface DaprPreviewClient extends AutoCloseable { * * @param storeName Name of the configuration store * @param keys keys of the configurations which are to be subscribed - * @param metadata optional metadata + * @param metadata optional metadata * @return Flux of List of configuration items */ Flux> subscribeToConfigurations(String storeName, List keys, diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java index 21eb90dbbe..971c33cd25 100644 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java @@ -1,7 +1,15 @@ /* - * Copyright (c) Microsoft Corporation and Dapr Contributors. - * Licensed under the MIT License. - */ + * Copyright 2021 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ package io.dapr.client; diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java index 169e645a26..67726a0b0e 100644 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java @@ -1,7 +1,15 @@ /* - * Copyright (c) Microsoft Corporation and Dapr Contributors. - * Licensed under the MIT License. - */ + * Copyright 2021 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ package io.dapr.client; diff --git a/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java b/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java index aebb43de3e..484409c404 100644 --- a/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java +++ b/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java @@ -1,7 +1,15 @@ /* - * Copyright (c) Microsoft Corporation and Dapr Contributors. - * Licensed under the MIT License. - */ + * Copyright 2021 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ package io.dapr.client.domain; diff --git a/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java index cb4c890701..5d412a0868 100644 --- a/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java +++ b/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java @@ -1,7 +1,15 @@ /* - * Copyright (c) Microsoft Corporation and Dapr Contributors. - * Licensed under the MIT License. - */ + * Copyright 2021 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ package io.dapr.client.domain; diff --git a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java index 1669f35010..a8c9cd3b55 100644 --- a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java +++ b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java @@ -1,7 +1,15 @@ /* - * Copyright (c) Microsoft Corporation and Dapr Contributors. - * Licensed under the MIT License. - */ + * Copyright 2021 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ package io.dapr.client.domain; diff --git a/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java index 415a0343d4..c5fc6bd89c 100644 --- a/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java +++ b/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java @@ -1,7 +1,15 @@ /* - * Copyright (c) Microsoft Corporation and Dapr Contributors. - * Licensed under the MIT License. - */ + * Copyright 2021 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ package io.dapr.client.domain; From 2035de911d8a61d312c1eefef7b0822bfc69b2e0 Mon Sep 17 00:00:00 2001 From: pravinpushkar Date: Thu, 6 Jan 2022 12:20:25 +0530 Subject: [PATCH 06/13] Review comments fixes Signed-off-by: pravinpushkar --- .../grpc/ConfigurationClient.java | 82 +++++++++++------- .../examples/configuration/grpc/README.md | 78 +++++++++-------- .../grpc/ConfigurationClientIT.java | 84 ++++++++++++++++--- .../io/dapr/client/AbstractDaprClient.java | 10 ++- .../java/io/dapr/client/DaprClientGrpc.java | 44 +++++++--- .../dapr/client/domain/ConfigurationItem.java | 17 +++- .../domain/GetBulkConfigurationRequest.java | 2 +- .../domain/GetConfigurationRequest.java | 2 +- .../domain/SubscribeConfigurationRequest.java | 3 +- 9 files changed, 230 insertions(+), 92 deletions(-) diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java index 974de5e99b..ec1487084a 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java @@ -19,18 +19,21 @@ import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.GetConfigurationRequest; import io.dapr.client.domain.SubscribeConfigurationRequest; +import reactor.core.Disposable; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; import java.util.List; +import java.util.concurrent.atomic.AtomicReference; public class ConfigurationClient { private static final String CONFIG_STORE_NAME = "redisconfigstore"; - private static final List keys = new ArrayList<>(Arrays.asList("myconfig2", "myconfig3", "myconfig4")); + private static final List keys = new ArrayList<>(Arrays.asList("myconfig1", "myconfig3", "myconfig2")); /** * Executes various methods to check the different apis. @@ -44,7 +47,6 @@ public static void main(String[] args) throws Exception { getConfigurationsUsingVarargs(client); getConfigurations(client); getAllConfigurations(client); - subscribeConfigurationRequestWithIterator(client); subscribeConfigurationRequestWithSubscribe(client); } } @@ -55,7 +57,7 @@ public static void main(String[] args) throws Exception { * @param client DaprPreviewClient object */ public static void getConfigurationForaSingleKey(DaprPreviewClient client) { - System.out.println("*******trying to retrieve configuration a key********"); + System.out.println("*******trying to retrieve configuration given a single key********"); GetConfigurationRequest request = new GetConfigurationRequest(CONFIG_STORE_NAME, keys.get(0)); try { Mono item = client.getConfiguration(request); @@ -74,7 +76,7 @@ public static void getConfigurationsUsingVarargs(DaprPreviewClient client) { System.out.println("*******trying to retrieve configurations for a variable no. of keys********"); try { Mono> items = - client.getConfigurations(CONFIG_STORE_NAME, "configgrpc||myconfig", "myconfig2", "myconfig3"); + client.getConfigurations(CONFIG_STORE_NAME, "myconfig1", "myconfig3"); items.block().forEach(ConfigurationClient::print); } catch (Exception ex) { System.out.println(ex.getMessage()); @@ -89,10 +91,9 @@ public static void getConfigurationsUsingVarargs(DaprPreviewClient client) { public static void getConfigurations(DaprPreviewClient client) { System.out.println("*******trying to retrieve configurations for a list of keys********"); List keys = new ArrayList<>(); + keys.add("myconfig1"); keys.add("myconfig2"); keys.add("myconfig3"); - keys.add("myconfig4"); - keys.add("myconfig5"); GetBulkConfigurationRequest req = new GetBulkConfigurationRequest(CONFIG_STORE_NAME, keys); try { Mono> items = client.getConfigurations(req); @@ -117,21 +118,6 @@ public static void getAllConfigurations(DaprPreviewClient client) { } } - /** - * Subscribe to a list of keys. - * - * @param client DaprPreviewClient object - */ - public static void subscribeConfigurationRequestWithIterator(DaprPreviewClient client) { - System.out.println("*****Subscribing to keys: " + keys.toString() + " *****"); - SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(CONFIG_STORE_NAME, keys); - Iterator> itr = client.subscribeToConfigurations(req).toIterable().iterator(); - while (itr.hasNext()) { - List cis = itr.next(); - cis.forEach(ConfigurationClient::print); - } - } - /** * Subscribe to a list of keys.Optional to above iterator way of retrieving the changes * @@ -139,16 +125,56 @@ public static void subscribeConfigurationRequestWithIterator(DaprPreviewClient c */ public static void subscribeConfigurationRequestWithSubscribe(DaprPreviewClient client) { System.out.println("*****Subscribing to keys using subscribe method: " + keys.toString() + " *****"); + AtomicReference disposableAtomicReference = new AtomicReference<>(); SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(CONFIG_STORE_NAME, keys); - client.subscribeToConfigurations(req) - .subscribe( - cis -> cis.forEach(ConfigurationClient::print) - ); - // Below lines need to be uncommented to stop client from getting killed. - /*while (true) {}*/ + Runnable subscribeTask = () -> { + Flux> outFlux = client.subscribeToConfigurations(req); + disposableAtomicReference.set(outFlux + .subscribe( + cis -> cis.forEach(ConfigurationClient::print) + )); + }; + new Thread(subscribeTask).start(); + try { + // To ensure that subscribeThread gets scheduled + Thread.sleep(0); + } catch (InterruptedException e) { + e.printStackTrace(); + } + Runnable updateKeys = () -> { + executeDockerCommand(); + }; + new Thread(updateKeys).start(); + try { + // To ensure main thread does not die before outFlux subscribe gets called + Thread.sleep(3000); + disposableAtomicReference.get().dispose(); + } catch (InterruptedException e) { + e.printStackTrace(); + } } private static void print(ConfigurationItem item) { System.out.println(item.getValue() + " : key ->" + item.getKey()); } + + private static void executeDockerCommand() { + String[] command = new String[] { + "docker", "exec", "dapr_redis", "redis-cli", + "MSET", + "myconfig1", "update_myconfigvalue1||2", + "myconfig2", "update_myconfigvalue2||2", + "myconfig3", "update_myconfigvalue3||2" + }; + ProcessBuilder processBuilder = new ProcessBuilder(command); + Process process = null; + try { + process = processBuilder.start(); + process.waitFor(); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } } diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md b/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md index 1fdec9302a..c424645a72 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md @@ -3,6 +3,16 @@ This example provides the different capabilities provided by Dapr Java SDK for Configuration. For further information about Configuration APIs please refer to [this link](https://docs.dapr.io/developing-applications/building-blocks/configuration/) **This API is available in Preview Mode**. +### Using the ConfigurationAPI + +The java SDK exposes several methods for this - +* `client.getConfiguration(...)` for getting a configuration for a single key. +* `client.getConfigurations(...)` for getting a configurations by passing a variable no. of arguments or list of argumets. +* `client.getAllConfigurations(...)` for getting all configurations. +* `client.subscribeToConfigurations(...)` for subscribing to a list of keys for any change. + +The code uses the `DaprPreviewClient` created by the `DaprPreviewClientBuilder`. + ## Pre-requisites * [Dapr and Dapr Cli](https://docs.dapr.io/getting-started/install-dapr/). @@ -24,59 +34,63 @@ Then build the Maven project: # make sure you are in the `java-sdk` directory. mvn install ``` +## Store few dummy configurations in configurationstore + + +```bash +docker exec dapr_redis redis-cli MSET myconfig1 "val1||1" myconfig2 "val2||1" myconfig3 "val3||1" +``` + + +### Running the example Get into the examples' directory: ```sh cd examples ``` -### Using the ConfigurationAPI - -The java SDK exposes several methods for this - -* `client.getConfiguration(...)` for getting a configuration for a single key. -* `client.getConfigurations(...)` for getting a configurations by passing a variable no. of arguments or list of argumets. -* `client.getAllConfigurations(...)` for getting all configurations. -* `client.subscribeToConfigurations(...)` for subscribing to a list of keys for any change. +Use the following command to run this example- -### Running the example -The code uses the `DaprPreviewClient` created by the `DaprPreviewClientBuilder`. + ```bash dapr run --app-id configgrpc --log-level debug -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.configuration.grpc.ConfigurationClient ``` + + ### Sample output ``` == APP == Using preview client... -== APP == *******trying to retrieve configuration a key******** -== APP == Value ->"value2" key ->myconfig2 +== APP == *******trying to retrieve configuration given a single key******** +== APP == Value ->val1 key ->myconfig1 == APP == *******trying to retrieve configurations for a variable no. of keys******** -== APP == "wookie-pravin" : key ->configgrpc||myconfig -== APP == "value2" : key ->myconfig2 -== APP == "value3" : key ->myconfig3 +== APP == val1 : key ->myconfig1 +== APP == val3 : key ->myconfig3 == APP == *******trying to retrieve configurations for a list of keys******** -== APP == "value2" : key ->myconfig2 -== APP == "value3" : key ->myconfig3 -== APP == "value4" : key ->myconfig4 -== APP == "value5" : key ->myconfig5 +== APP == val1 : key ->myconfig1 +== APP == val2 : key ->myconfig2 +== APP == val3 : key ->myconfig3 == APP == *****Retrieving all configurations******* -== APP == "value4" : key ->myconfig4 -== APP == "wookie-pravin" : key ->configgrpc||myconfig -== APP == "value2" : key ->myconfig2 -== APP == "value6" : key ->"myconfig6" -== APP == "value5" : key ->myconfig5 -== APP == "value3" : key ->myconfig3 -== APP == *****Subscribing to keys: [myconfig2, myconfig3, myconfig4] ***** -DEBU[0030] Refreshing all mDNS addresses. app_id=configgrpc instance=LAPTOP-OS4MBC7R scope=dapr.contrib type=log ver=1.5.1 -DEBU[0030] no mDNS apps to refresh. app_id=configgrpc instance=LAPTOP-OS4MBC7R scope=dapr.contrib type=log ver=1.5.1 -DEBU[0060] Refreshing all mDNS addresses. app_id=configgrpc instance=LAPTOP-OS4MBC7R scope=dapr.contrib type=log ver=1.5.1 -DEBU[0060] no mDNS apps to refresh. app_id=configgrpc instance=LAPTOP-OS4MBC7R scope=dapr.contrib type=log ver=1.5.1 -== APP == "new-value" : key ->myconfig2 +== APP == val3 : key ->myconfig3 +== APP == val2 : key ->myconfig2 +== APP == val1 : key ->myconfig1 +== APP == *****Subscribing to keys using subscribe method: [myconfig1, myconfig3, myconfig2] ***** +== APP == update_myconfigvalue1 : key ->myconfig1 +== APP == update_myconfigvalue2 : key ->myconfig2 +== APP == update_myconfigvalue3 : key ->myconfig3 ``` ### Cleanup -To stop the apps run (or press CTRL+C): +To stop the app, run (or press CTRL+C): -Thanks for playing. - diff --git a/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java b/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java index e82d70d49f..7bc5344229 100644 --- a/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java +++ b/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java @@ -11,12 +11,14 @@ import io.dapr.it.BaseIT; import io.dapr.it.DaprRun; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.*; +import reactor.core.Disposable; import reactor.core.publisher.Flux; +import java.io.IOException; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import static org.junit.Assert.*; @@ -32,16 +34,24 @@ public class ConfigurationClientIT extends BaseIT { private static List keys = new ArrayList<>(Arrays.asList("myconfig1", "myconfig2", "myconfig3")); + private static String[] insertCmd = new String[] { + "docker", "exec", "dapr_redis", "redis-cli", + "MSET", + "myconfigkey1", "myconfigvalue1||1", + "myconfigkey2", "myconfigvalue2||1", + "myconfigkey3", "myconfigvalue3||1" + }; + + private static String[] updateCmd = new String[] { + "docker", "exec", "dapr_redis", "redis-cli", + "MSET", + "myconfigkey1", "update_myconfigvalue1||2", + "myconfigkey2", "update_myconfigvalue2||2", + "myconfigkey3", "update_myconfigvalue3||2" + }; + @BeforeClass public static void init() throws Exception { - /* setup redis configuration store to have below key-value pairs before running the tests. - this step is required as there is no save api for configuration data. - config store name -> redisconfigstore - below 3 key-value pairs - - myconfigkey1-myconfigvalue1 - myconfigkey2-myconfigvalue2 - myconfigkey3-myconfigvalue3 - */ daprRun = startDaprApp(ConfigurationClientIT.class.getSimpleName(), 5000); daprRun.switchToGRPC(); daprPreviewClient = new DaprPreviewClientBuilder().build(); @@ -52,6 +62,11 @@ public static void tearDown() throws Exception { daprPreviewClient.close(); } + @Before + public void setupConfigStore() { + executeDockerCommand(insertCmd); + } + @Test public void getConfiguration() { ConfigurationItem ci = daprPreviewClient.getConfiguration(CONFIG_STORE_NAME, "myconfigkey1").block(); @@ -85,7 +100,50 @@ public void getConfigurationsWithEmptyList() { @Test public void subscribeToConfiguration() { - Flux> outFlux = daprPreviewClient.subscribeToConfigurations(CONFIG_STORE_NAME, "myconfigkey1", "myconfigkey2"); - assertNotNull(outFlux); + List updatedValues = new ArrayList<>(); + AtomicReference disposable = new AtomicReference<>(); + Runnable subscribeTask = () -> { + Flux> outFlux = daprPreviewClient + .subscribeToConfigurations(CONFIG_STORE_NAME, "myconfigkey1", "myconfigkey2"); + disposable.set(outFlux.subscribe(update -> { + updatedValues.add(update.get(0).getValue()); + })); + }; + Thread subscribeThread = new Thread(subscribeTask); + subscribeThread.start(); + try { + // To ensure that subscribeThread gets scheduled + Thread.sleep(0); + } catch (InterruptedException e) { + e.printStackTrace(); + } + Runnable updateKeys = () -> { + executeDockerCommand(updateCmd); + }; + new Thread(updateKeys).start(); + try { + // To ensure main thread does not die before outFlux subscribe gets called + Thread.sleep(3000); + disposable.get().dispose(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + assertEquals(updatedValues.size(), 2); + assertTrue(updatedValues.contains("update_myconfigvalue1")); + assertTrue(updatedValues.contains("update_myconfigvalue2")); + assertFalse(updatedValues.contains("update_myconfigvalue3")); + } + + private static void executeDockerCommand(String[] command) { + ProcessBuilder processBuilder = new ProcessBuilder(command); + Process process = null; + try { + process = processBuilder.start(); + process.waitFor(); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } } } diff --git a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java index 8b50fef248..e2c5a73287 100644 --- a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java +++ b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java @@ -46,9 +46,11 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * Abstract class with convenient methods common between client implementations. @@ -445,7 +447,9 @@ public Mono getConfiguration(String storeName, String key, Ma */ @Override public Mono> getConfigurations(String storeName, String... keys) { - List listOfKeys = Flux.just(keys).filter(key -> !key.trim().isEmpty()).collectList().block(); + List listOfKeys = Arrays.stream(keys) + .filter(key -> !key.trim().isEmpty()) + .collect(Collectors.toList()); GetBulkConfigurationRequest request = new GetBulkConfigurationRequest(storeName, listOfKeys); return this.getConfigurations(request); } @@ -486,7 +490,9 @@ public Mono> getAllConfigurations(String storeName, Map< * {@inheritDoc} */ public Flux> subscribeToConfigurations(String storeName, String... keys) { - List listOfKeys = Flux.just(keys).collectList().block(); + List listOfKeys = Arrays.stream(keys) + .filter(key -> !key.trim().isEmpty()) + .collect(Collectors.toList()); SubscribeConfigurationRequest request = new SubscribeConfigurationRequest(storeName, listOfKeys); return this.subscribeToConfigurations(request); } diff --git a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java index 4d9df33f49..c7f8cbba3e 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java @@ -691,6 +691,7 @@ public Mono getConfiguration(GetConfigurationRequest request) try { final String configurationStoreName = request.getStoreName(); final String key = request.getKey(); + final Map metadata = request.getMetadata(); if ((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { throw new IllegalArgumentException("Configuration Store Name cannot be null or empty."); @@ -701,9 +702,12 @@ public Mono getConfiguration(GetConfigurationRequest request) DaprProtos.GetConfigurationRequest.Builder builder = DaprProtos.GetConfigurationRequest.newBuilder() .setStoreName(configurationStoreName) .addKeys(key); + if (metadata != null) { + builder.putAllMetadata(metadata); + } - DaprProtos.GetConfigurationRequest envelop = builder.build(); - return this.getConfigurationAlpha1(envelop).map( + DaprProtos.GetConfigurationRequest envelope = builder.build(); + return this.getConfigurationAlpha1(envelope).map( it -> it.get(0) ); } catch (Exception ex) { @@ -718,18 +722,23 @@ public Mono getConfiguration(GetConfigurationRequest request) public Mono> getConfigurations(GetBulkConfigurationRequest request) { try { final String configurationStoreName = request.getStoreName(); + final Map metadata = request.getMetadata(); final List keys = request.getKeys(); + if ((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { throw new IllegalArgumentException("Configuration Store Name cannot be null or empty."); } - if (keys.isEmpty() || keys == null) { + if (keys.isEmpty()) { throw new IllegalArgumentException("Keys can not be empty or null"); } DaprProtos.GetConfigurationRequest.Builder builder = DaprProtos.GetConfigurationRequest.newBuilder() .setStoreName(configurationStoreName).addAllKeys(keys); + if (metadata != null) { + builder.putAllMetadata(metadata); + } - DaprProtos.GetConfigurationRequest envelop = builder.build(); - return this.getConfigurationAlpha1(envelop); + DaprProtos.GetConfigurationRequest envelope = builder.build(); + return this.getConfigurationAlpha1(envelope); } catch (Exception ex) { return DaprException.wrapMono(ex); @@ -743,25 +752,30 @@ public Mono> getConfigurations(GetBulkConfigurationReque public Mono> getAllConfigurations(GetBulkConfigurationRequest request) { try { final String configurationStoreName = request.getStoreName(); + final Map metadata = request.getMetadata(); + if ((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { throw new IllegalArgumentException("Configuration Store Name cannot be null or empty."); } DaprProtos.GetConfigurationRequest.Builder builder = DaprProtos.GetConfigurationRequest.newBuilder() .setStoreName(configurationStoreName); + if (metadata != null) { + builder.putAllMetadata(metadata); + } - DaprProtos.GetConfigurationRequest envelop = builder.build(); - return this.getConfigurationAlpha1(envelop); + DaprProtos.GetConfigurationRequest envelope = builder.build(); + return this.getConfigurationAlpha1(envelope); } catch (Exception ex) { return DaprException.wrapMono(ex); } } - private Mono> getConfigurationAlpha1(DaprProtos.GetConfigurationRequest envelop) { + private Mono> getConfigurationAlpha1(DaprProtos.GetConfigurationRequest envelope) { return Mono.subscriberContext().flatMap( context -> this.createMono( - it -> intercept(context, asyncStub).getConfigurationAlpha1(envelop, it) + it -> intercept(context, asyncStub).getConfigurationAlpha1(envelope, it) ) ).map( it -> @@ -784,18 +798,24 @@ public Flux> subscribeToConfigurations(SubscribeConfigur try { final String configurationStoreName = request.getStoreName(); final List keys = request.getKeys(); + final Map metadata = request.getMetadata(); + if (configurationStoreName == null || (configurationStoreName.trim().isEmpty())) { throw new IllegalArgumentException("Configuration Store Name can not be null or empty."); } - if (keys == null || keys.isEmpty()) { + if (keys.isEmpty()) { throw new IllegalArgumentException("Keys can not be null or empty."); } DaprProtos.SubscribeConfigurationRequest.Builder builder = DaprProtos.SubscribeConfigurationRequest.newBuilder() .setStoreName(configurationStoreName) .addAllKeys(keys); - DaprProtos.SubscribeConfigurationRequest envelop = builder.build(); + if (metadata != null) { + builder.putAllMetadata(metadata); + } + + DaprProtos.SubscribeConfigurationRequest envelope = builder.build(); return this.createFlux( - it -> intercept(asyncStub).subscribeConfigurationAlpha1(envelop, it) + it -> intercept(asyncStub).subscribeConfigurationAlpha1(envelope, it) ).map( it -> it.getItemsList().stream() diff --git a/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java b/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java index 484409c404..de5d1430a0 100644 --- a/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java +++ b/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java @@ -13,6 +13,7 @@ package io.dapr.client.domain; +import java.util.Collections; import java.util.Map; public class ConfigurationItem { @@ -33,7 +34,21 @@ public ConfigurationItem(String key, String value, String version, Map keys) { this.storeName = storeName; - this.keys = keys == null ? Collections.unmodifiableList(new ArrayList<>()) : Collections.unmodifiableList(keys); + this.keys = keys == null ? Collections.EMPTY_LIST : Collections.unmodifiableList(keys); } public GetBulkConfigurationRequest setMetadata(Map metadata) { diff --git a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java index a8c9cd3b55..05f19cfedc 100644 --- a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java +++ b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java @@ -28,7 +28,7 @@ public GetConfigurationRequest(String storeName, String key) { } public GetConfigurationRequest setMetadata(Map metadata) { - this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata); + this.metadata = metadata == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(metadata); return this; } diff --git a/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java index c5fc6bd89c..ac8ea2c81d 100644 --- a/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java +++ b/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java @@ -13,6 +13,7 @@ package io.dapr.client.domain; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -24,7 +25,7 @@ public class SubscribeConfigurationRequest { public SubscribeConfigurationRequest(String storeName, List keys) { this.storeName = storeName; - this.keys = Collections.unmodifiableList(keys); + this.keys = keys == null ? Collections.EMPTY_LIST : Collections.unmodifiableList(keys); } public SubscribeConfigurationRequest setMetadata(Map metadata) { From 3be157628a715faf84d4bbb7aa2fe7b8ded4eab1 Mon Sep 17 00:00:00 2001 From: pravinpushkar Date: Thu, 6 Jan 2022 14:12:19 +0530 Subject: [PATCH 07/13] Removed DaprPreviewClientProxy and updated example README Signed-off-by: pravinpushkar --- .../configuration/redis_configstore.yaml | 12 ++ .../examples/configuration/grpc/README.md | 2 +- .../dapr/client/DaprPreviewClientBuilder.java | 11 -- .../dapr/client/DaprPreviewClientProxy.java | 186 ------------------ .../client/DaprPreviewClientGrpcTest.java | 34 +++- .../client/DaprPreviewClientHttpTest.java | 10 +- .../client/DaprPreviewClientProxyTest.java | 56 ------ 7 files changed, 51 insertions(+), 260 deletions(-) create mode 100644 examples/components/configuration/redis_configstore.yaml delete mode 100644 sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java delete mode 100644 sdk/src/test/java/io/dapr/client/DaprPreviewClientProxyTest.java diff --git a/examples/components/configuration/redis_configstore.yaml b/examples/components/configuration/redis_configstore.yaml new file mode 100644 index 0000000000..5b0e4090da --- /dev/null +++ b/examples/components/configuration/redis_configstore.yaml @@ -0,0 +1,12 @@ +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: configstore +spec: + type: configuration.redis + version: v1 + metadata: + - name: redisHost + value: localhost:6379 + - name: redisPassword + value: "" diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md b/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md index c424645a72..d34fbe8899 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md @@ -61,7 +61,7 @@ name: Run ConfigurationClient example --> ```bash -dapr run --app-id configgrpc --log-level debug -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.configuration.grpc.ConfigurationClient +dapr run --components-path ./components/configuration --app-id configgrpc --log-level debug -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.configuration.grpc.ConfigurationClient ``` diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java index 971c33cd25..db5d92862c 100644 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java @@ -29,11 +29,6 @@ public class DaprPreviewClientBuilder { */ private final DaprApiProtocol apiProtocol; - /** - * Determine if this builder will use HTTP client for service method invocation APIs. - */ - private final DaprApiProtocol methodInvocationApiProtocol; - /** * Builder for Dapr's HTTP Client. */ @@ -59,7 +54,6 @@ public DaprPreviewClientBuilder() { this.objectSerializer = new DefaultObjectSerializer(); this.stateSerializer = new DefaultObjectSerializer(); this.apiProtocol = Properties.API_PROTOCOL.get(); - this.methodInvocationApiProtocol = Properties.API_METHOD_INVOCATION_PROTOCOL.get(); this.daprHttpBuilder = new DaprHttpBuilder(); } @@ -106,11 +100,6 @@ public DaprPreviewClientBuilder withStateSerializer(DaprObjectSerializer stateSe * @throws IllegalStateException if any required field is missing */ public DaprPreviewClient build() { - if (this.apiProtocol != this.methodInvocationApiProtocol) { - return new DaprPreviewClientProxy(buildDaprPreviewClient(this.apiProtocol), - buildDaprPreviewClient(this.methodInvocationApiProtocol)); - } - return buildDaprPreviewClient(this.apiProtocol); } diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java deleted file mode 100644 index 67726a0b0e..0000000000 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClientProxy.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2021 The Dapr Authors - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and -limitations under the License. -*/ - -package io.dapr.client; - -import io.dapr.client.domain.ConfigurationItem; -import io.dapr.client.domain.GetBulkConfigurationRequest; -import io.dapr.client.domain.GetConfigurationRequest; -import io.dapr.client.domain.SubscribeConfigurationRequest; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import java.util.List; -import java.util.Map; - -public class DaprPreviewClientProxy implements DaprPreviewClient { - - /** - * Client for all API invocations. - */ - private final DaprPreviewClient client; - - /** - * Client to override Dapr's service invocation APIs. - */ - private final DaprPreviewClient methodInvocationOverrideClient; - - /** - * Constructor with delegate client. - * - * @param client Client for all API invocations. - * @see DaprPreviewClientBuilder - */ - DaprPreviewClientProxy(DaprPreviewClient client) { - this(client, client); - } - - /** - * Constructor with delegate client and override client for Dapr's method invocation APIs. - * - * @param client Client for all API invocations, except override below. - * @param methodInvocationOverrideClient Client to override Dapr's service invocation APIs. - * @see DaprClientBuilder - */ - DaprPreviewClientProxy( - DaprPreviewClient client, - DaprPreviewClient methodInvocationOverrideClient) { - this.client = client; - this.methodInvocationOverrideClient = methodInvocationOverrideClient; - } - - /** - * {@inheritDoc} - */ - @Override - public Mono waitForSidecar(int timeoutInMilliseconds) { - return client.waitForSidecar(timeoutInMilliseconds); - } - - /** - * {@inheritDoc} - */ - @Override - public void close() throws Exception { - client.close(); - if (client != methodInvocationOverrideClient) { - methodInvocationOverrideClient.close(); - } - } - - /** - * {@inheritDoc} - */ - @Override - public Mono shutdown() { - return client.shutdown(); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono getConfiguration(String storeName, String key) { - return client.getConfiguration(storeName, key); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono getConfiguration(String storeName, String key, Map metadata) { - return client.getConfiguration(storeName, key, metadata); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono getConfiguration(GetConfigurationRequest request) { - return client.getConfiguration(request); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono> getConfigurations(String storeName, String... keys) { - return client.getConfigurations(storeName, keys); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono> getConfigurations(String storeName, List keys, - Map metadata) { - return client.getConfigurations(storeName, keys, metadata); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono> getConfigurations(GetBulkConfigurationRequest request) { - return client.getConfigurations(request); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono> getAllConfigurations(String storeName) { - return client.getAllConfigurations(storeName); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono> getAllConfigurations(String storeName, Map metadata) { - return client.getAllConfigurations(storeName, metadata); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono> getAllConfigurations(GetBulkConfigurationRequest request) { - return client.getAllConfigurations(request); - } - - /** - * {@inheritDoc} - */ - @Override - public Flux> subscribeToConfigurations(String storeName, String... keys) { - return client.subscribeToConfigurations(storeName, keys); - } - - /** - * {@inheritDoc} - */ - @Override - public Flux> subscribeToConfigurations(String storeName, List keys, - Map metadata) { - return client.subscribeToConfigurations(storeName, keys, metadata); - } - - /** - * {@inheritDoc} - */ - @Override - public Flux> subscribeToConfigurations(SubscribeConfigurationRequest request) { - return client.subscribeToConfigurations(request); - } -} diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java index 23a2c9f9e0..3c5717cc05 100644 --- a/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -47,8 +48,8 @@ public void setup() throws IOException { closeable = mock(Closeable.class); daprStub = mock(DaprGrpc.DaprStub.class); when(daprStub.withInterceptors(any())).thenReturn(daprStub); - previewClient = new DaprPreviewClientProxy(new DaprClientGrpc( - closeable, daprStub, new DefaultObjectSerializer(), new DefaultObjectSerializer())); + previewClient = new DaprClientGrpc( + closeable, daprStub, new DefaultObjectSerializer(), new DefaultObjectSerializer()); serializer = new ObjectSerializer(); doNothing().when(closeable).close(); } @@ -228,4 +229,33 @@ public void subscribeConfigurationTest() { assertEquals("configkey1", itr.next().get(0).getKey()); assertFalse(itr.hasNext()); } + + @Test + public void subscribeConfigurationTestWithMetadata() { + Map metadata = new HashMap<>(); + metadata.put("meta1", "value1"); + DaprProtos.SubscribeConfigurationResponse responseEnvelope = DaprProtos.SubscribeConfigurationResponse.newBuilder() + .addItems(CommonProtos.ConfigurationItem.newBuilder() + .setKey("configkey1") + .setValue("configvalue1") + .setVersion("1") + .putAllMetadata(metadata) + .build()) + .build(); + + doAnswer((Answer) invocation -> { + StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; + observer.onNext(responseEnvelope); + observer.onCompleted(); + return null; + }).when(daprStub).subscribeConfigurationAlpha1(any(DaprProtos.SubscribeConfigurationRequest.class), any()); + + Map reqMetadata = new HashMap<>(); + List keys = Arrays.asList("configkey1"); + + Iterator> itr = previewClient.subscribeToConfigurations(CONFIG_STORE_NAME, keys, reqMetadata).toIterable().iterator(); + assertTrue(itr.hasNext()); + assertEquals("configkey1", itr.next().get(0).getKey()); + assertFalse(itr.hasNext()); + } } diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java index a41ba026e5..b20d70c0ab 100644 --- a/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java @@ -45,10 +45,12 @@ public void setUp() { mockInterceptor = new MockInterceptor(Behavior.UNORDERED); okHttpClient = new OkHttpClient.Builder().addInterceptor(mockInterceptor).build(); daprHttp = new DaprHttp(Properties.SIDECAR_IP.get(), 3000, okHttpClient); - daprPreviewClientHttp = new DaprPreviewClientProxy(new DaprClientHttp(daprHttp)); - daprPreviewClientHttpXML = new DaprPreviewClientProxy( - new DaprClientHttp(daprHttp, new DaprPreviewClientHttpTest.XmlSerializer(), - new DaprPreviewClientHttpTest.XmlSerializer())); + daprPreviewClientHttp = new DaprClientHttp(daprHttp); + daprPreviewClientHttpXML = new DaprClientHttp( + daprHttp, + new DaprPreviewClientHttpTest.XmlSerializer(), + new DaprPreviewClientHttpTest.XmlSerializer() + ); } @Test diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientProxyTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientProxyTest.java deleted file mode 100644 index 0a8b9d93ad..0000000000 --- a/sdk/src/test/java/io/dapr/client/DaprPreviewClientProxyTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) Microsoft Corporation and Dapr Contributors. - * Licensed under the MIT License. - */ - -package io.dapr.client; - -import io.dapr.client.domain.SubscribeConfigurationRequest; -import org.junit.Test; -import org.mockito.Mockito; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import java.util.*; - -import static org.mockito.Mockito.times; - -public class DaprPreviewClientProxyTest { - - @Test - public void getconfigurationAPI() { - DaprPreviewClient client = Mockito.mock(DaprPreviewClient.class); - Mockito.when(client.getConfiguration("store", "key")).thenReturn(Mono.empty()); - Mockito.when(client.getConfigurations("store", "key")).thenReturn(Mono.empty()); - Mockito.when(client.getAllConfigurations("store")).thenReturn(Mono.empty()); - - DaprPreviewClient proxy = new DaprPreviewClientProxy(client); - - proxy.getConfiguration("store", "key").block(); - proxy.getConfigurations("store", "key").block(); - proxy.getAllConfigurations("store").block(); - - Mockito.verify(client, times(1)).getConfiguration("store", "key"); - Mockito.verify(client, times(1)).getConfigurations("store", "key"); - Mockito.verify(client, times(1)).getAllConfigurations("store"); - } - - @Test - public void subscribeConfigurationAPI() { - Map metadata = new HashMap<>(); - List keys = new ArrayList<>(Arrays.asList("key")); - SubscribeConfigurationRequest req = new SubscribeConfigurationRequest("store", keys); - DaprPreviewClient client = Mockito.mock(DaprPreviewClient.class); - Mockito.when(client.subscribeToConfigurations("store", "key")).thenReturn(Flux.empty()); - - DaprPreviewClient proxy = new DaprPreviewClientProxy(client); - - proxy.subscribeToConfigurations("store", "key"); - proxy.subscribeToConfigurations("store", keys, metadata); - proxy.subscribeToConfigurations(req); - - Mockito.verify(client, times(1)).subscribeToConfigurations("store", "key"); - Mockito.verify(client, times(1)).subscribeToConfigurations("store", keys, metadata); - Mockito.verify(client, times(1)).subscribeToConfigurations(req); - } -} From 97d4fa01e7f67f52e21562aee1b60ba5bf4041d8 Mon Sep 17 00:00:00 2001 From: pravinpushkar Date: Fri, 7 Jan 2022 15:38:00 +0530 Subject: [PATCH 08/13] Adding validate workflow for cofiguration api example Signed-off-by: pravinpushkar --- .github/workflows/validate.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 7c2f53ca0b..f33585c60a 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -150,3 +150,7 @@ jobs: working-directory: ./examples run: | mm.py ./src/main/java/io/dapr/examples/unittesting/README.md + - name: Validate Configuration API example + working-directory: ./examples + run: | + mm.py ./src/main/java/io/dapr/examples/configuration/grpc/README.md \ No newline at end of file From b837bc80a46f6fdc096167710c93f3370accb77d Mon Sep 17 00:00:00 2001 From: pravinpushkar Date: Fri, 7 Jan 2022 18:55:58 +0530 Subject: [PATCH 09/13] fixing example autovalidation and code coverage Signed-off-by: pravinpushkar --- .../grpc/ConfigurationClient.java | 2 +- .../examples/configuration/grpc/README.md | 24 +++ sdk-tests/components/redisconfigstore.yaml | 2 - .../java/io/dapr/client/DaprClientGrpc.java | 19 +- .../domain/GetConfigurationRequest.java | 2 +- .../client/DaprPreviewClientGrpcTest.java | 180 ++++++++++++------ 6 files changed, 154 insertions(+), 75 deletions(-) diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java index ec1487084a..cd3becfd80 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java @@ -31,7 +31,7 @@ public class ConfigurationClient { - private static final String CONFIG_STORE_NAME = "redisconfigstore"; + private static final String CONFIG_STORE_NAME = "configstore"; private static final List keys = new ArrayList<>(Arrays.asList("myconfig1", "myconfig3", "myconfig2")); diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md b/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md index d34fbe8899..027503708a 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md @@ -58,6 +58,30 @@ Use the following command to run this example- ```bash diff --git a/sdk-tests/components/redisconfigstore.yaml b/sdk-tests/components/redisconfigstore.yaml index 5cf0ee23f3..cd4a025c17 100644 --- a/sdk-tests/components/redisconfigstore.yaml +++ b/sdk-tests/components/redisconfigstore.yaml @@ -10,5 +10,3 @@ spec: value: localhost:6379 - name: redisPassword value: "" - - name: actorStateStore - value: "true" diff --git a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java index c7f8cbba3e..2137a39a45 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java @@ -780,13 +780,7 @@ private Mono> getConfigurationAlpha1(DaprProtos.GetConfi ).map( it -> it.getItemsList().stream() - .map(b -> { - try { - return buildConfigurationItem(b); - } catch (Exception e) { - throw DaprException.propagate(e); - } - }).collect(Collectors.toList()) + .map(this::buildConfigurationItem).collect(Collectors.toList()) ); } @@ -819,13 +813,7 @@ public Flux> subscribeToConfigurations(SubscribeConfigur ).map( it -> it.getItemsList().stream() - .map(item -> { - try { - return buildConfigurationItem(item); - } catch (Exception ex) { - throw DaprException.propagate(ex); - } - }).collect(Collectors.toList()) + .map(this::buildConfigurationItem).collect(Collectors.toList()) ); } catch (Exception ex) { return DaprException.wrapFlux(ex); @@ -837,10 +825,9 @@ public Flux> subscribeToConfigurations(SubscribeConfigur * * @param configurationItem CommonProtos.ConfigurationItem * @return io.dapr.client.domain.ConfigurationItem - * @throws IOException throws IOException */ private ConfigurationItem buildConfigurationItem( - CommonProtos.ConfigurationItem configurationItem) throws IOException { + CommonProtos.ConfigurationItem configurationItem) { return new ConfigurationItem( configurationItem.getKey(), configurationItem.getValue(), diff --git a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java index 05f19cfedc..a8c9cd3b55 100644 --- a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java +++ b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java @@ -28,7 +28,7 @@ public GetConfigurationRequest(String storeName, String key) { } public GetConfigurationRequest setMetadata(Map metadata) { - this.metadata = metadata == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(metadata); + this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata); return this; } diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java index 3c5717cc05..726a125171 100644 --- a/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java @@ -27,7 +27,9 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutionException; +import static io.dapr.utils.TestUtils.assertThrowsDaprException; import static io.dapr.utils.TestUtils.findFreePort; import static org.junit.Assert.*; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -111,19 +113,10 @@ public void getConfigurationIllegalArgumentExceptionTest() { @Test public void getSingleConfigurationTest() { - Map metadata = new HashMap<>(); - metadata.put("meta1", "value1"); - DaprProtos.GetConfigurationResponse responseEnvelope = DaprProtos.GetConfigurationResponse.newBuilder() - .addItems(CommonProtos.ConfigurationItem.newBuilder() - .setKey("configkey1") - .setValue("configvalue1") - .setVersion("1") - .putAllMetadata(metadata) - .build() - ).build(); doAnswer((Answer) invocation -> { - StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; - observer.onNext(responseEnvelope); + StreamObserver observer = + (StreamObserver) invocation.getArguments()[1]; + observer.onNext(getSingleMockResponse()); observer.onCompleted(); return null; }).when(daprStub).getConfigurationAlpha1(any(DaprProtos.GetConfigurationRequest.class), any()); @@ -131,32 +124,33 @@ public void getSingleConfigurationTest() { ConfigurationItem ci = previewClient.getConfiguration(CONFIG_STORE_NAME, "configkey1").block(); assertEquals("configkey1", ci.getKey()); assertEquals("configvalue1", ci.getValue()); - assertEquals(metadata, ci.getMetadata()); assertEquals("1", ci.getVersion()); } @Test - public void getMultipleConfigurationTest() { - Map metadata = new HashMap<>(); - metadata.put("meta1", "value1"); - DaprProtos.GetConfigurationResponse responseEnvelope = DaprProtos.GetConfigurationResponse.newBuilder() - .addItems(CommonProtos.ConfigurationItem.newBuilder() - .setKey("configkey1") - .setValue("configvalue1") - .setVersion("1") - .putAllMetadata(metadata) - .build()) - .addItems(CommonProtos.ConfigurationItem.newBuilder() - .setKey("configkey2") - .setValue("configvalue2") - .setVersion("1") - .putAllMetadata(metadata) - .build()) - .build(); + public void getSingleConfigurationWithMetadataTest() { + doAnswer((Answer) invocation -> { + StreamObserver observer = + (StreamObserver) invocation.getArguments()[1]; + observer.onNext(getSingleMockResponse()); + observer.onCompleted(); + return null; + }).when(daprStub).getConfigurationAlpha1(any(DaprProtos.GetConfigurationRequest.class), any()); + Map reqMetadata = new HashMap<>(); + reqMetadata.put("meta1", "value1"); + ConfigurationItem ci = previewClient.getConfiguration(CONFIG_STORE_NAME, "configkey1", reqMetadata).block(); + assertEquals("configkey1", ci.getKey()); + assertEquals("configvalue1", ci.getValue()); + assertEquals("1", ci.getVersion()); + } + + @Test + public void getMultipleConfigurationTest() { doAnswer((Answer) invocation -> { - StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; - observer.onNext(responseEnvelope); + StreamObserver observer = + (StreamObserver) invocation.getArguments()[1]; + observer.onNext(getMultipleMockResponse()); observer.onCompleted(); return null; }).when(daprStub).getConfigurationAlpha1(any(DaprProtos.GetConfigurationRequest.class), any()); @@ -165,37 +159,38 @@ public void getMultipleConfigurationTest() { assertEquals(2, cis.size()); assertEquals("configkey1", cis.stream().findFirst().get().getKey()); assertEquals("configvalue1", cis.stream().findFirst().get().getValue()); - assertEquals(metadata, cis.stream().findFirst().get().getMetadata()); assertEquals("1", cis.stream().findFirst().get().getVersion()); assertEquals("configkey2", cis.stream().skip(1).findFirst().get().getKey()); assertEquals("configvalue2", cis.stream().skip(1).findFirst().get().getValue()); - assertEquals(metadata, cis.stream().skip(1).findFirst().get().getMetadata()); assertEquals("1", cis.stream().skip(1).findFirst().get().getVersion()); } @Test - public void getAllConfigurationTest() { - Map metadata = new HashMap<>(); - metadata.put("meta1", "value1"); - DaprProtos.GetConfigurationResponse responseEnvelope = DaprProtos.GetConfigurationResponse.newBuilder() - .addItems(CommonProtos.ConfigurationItem.newBuilder() - .setKey("configkey1") - .setValue("configvalue1") - .setVersion("1") - .putAllMetadata(metadata) - .build()) - .addItems(CommonProtos.ConfigurationItem.newBuilder() - .setKey("configkey2") - .setValue("configvalue2") - .setVersion("1") - .putAllMetadata(metadata) - .build()) - .build(); + public void getMultipleConfigurationWithMetadataTest() { + doAnswer((Answer) invocation -> { + StreamObserver observer = + (StreamObserver) invocation.getArguments()[1]; + observer.onNext(getMultipleMockResponse()); + observer.onCompleted(); + return null; + }).when(daprStub).getConfigurationAlpha1(any(DaprProtos.GetConfigurationRequest.class), any()); + + Map reqMetadata = new HashMap<>(); + reqMetadata.put("meta1", "value1"); + List keys = Arrays.asList("configkey1","configkey2"); + List cis = previewClient.getConfigurations(CONFIG_STORE_NAME, keys, reqMetadata).block(); + assertEquals(2, cis.size()); + assertEquals("configkey1", cis.stream().findFirst().get().getKey()); + assertEquals("configvalue1", cis.stream().findFirst().get().getValue()); + } + @Test + public void getAllConfigurationTest() { doAnswer((Answer) invocation -> { - StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; - observer.onNext(responseEnvelope); + StreamObserver observer = + (StreamObserver) invocation.getArguments()[1]; + observer.onNext(getMultipleMockResponse()); observer.onCompleted(); return null; }).when(daprStub).getConfigurationAlpha1(any(DaprProtos.GetConfigurationRequest.class), any()); @@ -204,6 +199,22 @@ public void getAllConfigurationTest() { assertEquals(2, cis.size()); } + @Test + public void getAllConfigurationWithMetadataTest() { + doAnswer((Answer) invocation -> { + StreamObserver observer = + (StreamObserver) invocation.getArguments()[1]; + observer.onNext(getMultipleMockResponse()); + observer.onCompleted(); + return null; + }).when(daprStub).getConfigurationAlpha1(any(DaprProtos.GetConfigurationRequest.class), any()); + + Map reqMetadata = new HashMap<>(); + reqMetadata.put("meta1", "value1"); + List cis = previewClient.getAllConfigurations(CONFIG_STORE_NAME, reqMetadata).block(); + assertEquals(2, cis.size()); + } + @Test public void subscribeConfigurationTest() { Map metadata = new HashMap<>(); @@ -218,7 +229,8 @@ public void subscribeConfigurationTest() { .build(); doAnswer((Answer) invocation -> { - StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; + StreamObserver observer = + (StreamObserver) invocation.getArguments()[1]; observer.onNext(responseEnvelope); observer.onCompleted(); return null; @@ -244,7 +256,8 @@ public void subscribeConfigurationTestWithMetadata() { .build(); doAnswer((Answer) invocation -> { - StreamObserver observer = (StreamObserver) invocation.getArguments()[1]; + StreamObserver observer = + (StreamObserver) invocation.getArguments()[1]; observer.onNext(responseEnvelope); observer.onCompleted(); return null; @@ -258,4 +271,61 @@ public void subscribeConfigurationTestWithMetadata() { assertEquals("configkey1", itr.next().get(0).getKey()); assertFalse(itr.hasNext()); } + + @Test + public void subscribeConfigurationWithErrorTest() { + doAnswer((Answer) invocation -> { + StreamObserver observer = + (StreamObserver) invocation.getArguments()[1]; + observer.onError(new RuntimeException()); + observer.onCompleted(); + return null; + }).when(daprStub).subscribeConfigurationAlpha1(any(DaprProtos.SubscribeConfigurationRequest.class), any()); + + assertThrowsDaprException(ExecutionException.class, () -> { + previewClient.subscribeToConfigurations(CONFIG_STORE_NAME, "key").blockFirst(); + }); + + assertThrows(IllegalArgumentException.class, () -> { + previewClient.subscribeToConfigurations("", "key").blockFirst(); + }); + + assertThrows(IllegalArgumentException.class, () -> { + previewClient.subscribeToConfigurations("store", "").blockFirst(); + }); + } + + private DaprProtos.GetConfigurationResponse getSingleMockResponse() { + Map metadata = new HashMap<>(); + metadata.put("meta1", "value1"); + DaprProtos.GetConfigurationResponse responseEnvelope = DaprProtos.GetConfigurationResponse.newBuilder() + .addItems(CommonProtos.ConfigurationItem.newBuilder() + .setKey("configkey1") + .setValue("configvalue1") + .setVersion("1") + .putAllMetadata(metadata) + .build() + ).build(); + return responseEnvelope; + } + + private DaprProtos.GetConfigurationResponse getMultipleMockResponse() { + Map metadata = new HashMap<>(); + metadata.put("meta1", "value1"); + DaprProtos.GetConfigurationResponse responseEnvelope = DaprProtos.GetConfigurationResponse.newBuilder() + .addItems(CommonProtos.ConfigurationItem.newBuilder() + .setKey("configkey1") + .setValue("configvalue1") + .setVersion("1") + .putAllMetadata(metadata) + .build()) + .addItems(CommonProtos.ConfigurationItem.newBuilder() + .setKey("configkey2") + .setValue("configvalue2") + .setVersion("1") + .putAllMetadata(metadata) + .build()) + .build(); + return responseEnvelope; + } } From 660744d897da89647a3601c995708f6884f11c03 Mon Sep 17 00:00:00 2001 From: pravinpushkar Date: Sat, 8 Jan 2022 00:38:19 +0530 Subject: [PATCH 10/13] Fixing autovalidation and removing getAllConfiguration Signed-off-by: pravinpushkar --- .../grpc/ConfigurationClient.java | 32 +++++------------ .../examples/configuration/grpc/README.md | 26 ++++---------- .../io/dapr/client/AbstractDaprClient.java | 19 ----------- .../java/io/dapr/client/DaprClientGrpc.java | 26 -------------- .../java/io/dapr/client/DaprClientHttp.java | 8 ----- .../io/dapr/client/DaprPreviewClient.java | 25 -------------- .../client/DaprPreviewClientGrpcTest.java | 34 ------------------- .../client/DaprPreviewClientHttpTest.java | 7 ---- 8 files changed, 16 insertions(+), 161 deletions(-) diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java index cd3becfd80..24dd46cdc3 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java @@ -46,7 +46,6 @@ public static void main(String[] args) throws Exception { getConfigurationForaSingleKey(client); getConfigurationsUsingVarargs(client); getConfigurations(client); - getAllConfigurations(client); subscribeConfigurationRequestWithSubscribe(client); } } @@ -103,21 +102,6 @@ public static void getConfigurations(DaprPreviewClient client) { } } - /** - * Gets all configurations. - * - * @param client DaprPreviewClient object - */ - public static void getAllConfigurations(DaprPreviewClient client) { - System.out.println("*****Retrieving all configurations*******"); - try { - Mono> items = client.getAllConfigurations(CONFIG_STORE_NAME); - items.block().forEach(ConfigurationClient::print); - } catch (Exception ex) { - System.out.println(ex.getMessage()); - } - } - /** * Subscribe to a list of keys.Optional to above iterator way of retrieving the changes * @@ -142,12 +126,16 @@ public static void subscribeConfigurationRequestWithSubscribe(DaprPreviewClient e.printStackTrace(); } Runnable updateKeys = () -> { - executeDockerCommand(); + int i = 1; + while (i <= 3) { + executeDockerCommand(i); + i++; + } }; new Thread(updateKeys).start(); try { // To ensure main thread does not die before outFlux subscribe gets called - Thread.sleep(3000); + Thread.sleep(10000); disposableAtomicReference.get().dispose(); } catch (InterruptedException e) { e.printStackTrace(); @@ -158,13 +146,11 @@ private static void print(ConfigurationItem item) { System.out.println(item.getValue() + " : key ->" + item.getKey()); } - private static void executeDockerCommand() { + private static void executeDockerCommand(int postfix) { String[] command = new String[] { "docker", "exec", "dapr_redis", "redis-cli", - "MSET", - "myconfig1", "update_myconfigvalue1||2", - "myconfig2", "update_myconfigvalue2||2", - "myconfig3", "update_myconfigvalue3||2" + "SET", + "myconfig" + postfix, "update_myconfigvalue" + postfix + "||2" }; ProcessBuilder processBuilder = new ProcessBuilder(command); Process process = null; diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md b/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md index 027503708a..6002b387a0 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md @@ -8,7 +8,6 @@ This example provides the different capabilities provided by Dapr Java SDK for C The java SDK exposes several methods for this - * `client.getConfiguration(...)` for getting a configuration for a single key. * `client.getConfigurations(...)` for getting a configurations by passing a variable no. of arguments or list of argumets. -* `client.getAllConfigurations(...)` for getting all configurations. * `client.subscribeToConfigurations(...)` for subscribing to a list of keys for any change. The code uses the `DaprPreviewClient` created by the `DaprPreviewClientBuilder`. @@ -61,25 +60,18 @@ name: Run ConfigurationClient example expected_stdout_lines: - "== APP == Using preview client..." - "== APP == *******trying to retrieve configuration given a single key********" - - "== APP == Value ->update_myconfigvalue1 key ->myconfig1" + - "== APP == Value ->val1 key ->myconfig1" - "== APP == *******trying to retrieve configurations for a variable no. of keys********" - - "== APP == update_myconfigvalue1 : key ->myconfig1" - - "== APP == update_myconfigvalue3 : key ->myconfig3" + - "== APP == val1 : key ->myconfig1" + - "== APP == val3 : key ->myconfig3" - "== APP == *******trying to retrieve configurations for a list of keys********" + - "== APP == val1 : key ->myconfig1" + - "== APP == val2 : key ->myconfig2" + - "== APP == val3 : key ->myconfig3" + - "== APP == *****Subscribing to keys using subscribe method: [myconfig1, myconfig3, myconfig2] *****" - "== APP == update_myconfigvalue1 : key ->myconfig1" - "== APP == update_myconfigvalue2 : key ->myconfig2" - "== APP == update_myconfigvalue3 : key ->myconfig3" - - "== APP == *****Retrieving all configurations*******" - - "== APP == update_myconfigvalue1 : key ->myconfig1" - - "== APP == update_myconfigvalue2 : key ->myconfig2" - - "== APP == update_myconfigvalue3 : key ->myconfig3" - - "== APP == myconfigvalue1 : key ->myconfigkey1" - - "== APP == myconfigvalue2 : key ->myconfigkey2" - - "== APP == myconfigvalue3 : key ->myconfigkey3" - - "== APP == *****Subscribing to keys using subscribe method: [myconfig1, myconfig3, myconfig2] *****" - - "== APP == update_myconfigvalue3 : key ->myconfig3" - - "== APP == update_myconfigvalue2 : key ->myconfig2" - - "== APP == update_myconfigvalue1 : key ->myconfig1" background: true sleep: 5 --> @@ -102,10 +94,6 @@ dapr run --components-path ./components/configuration --app-id configgrpc --log- == APP == val1 : key ->myconfig1 == APP == val2 : key ->myconfig2 == APP == val3 : key ->myconfig3 -== APP == *****Retrieving all configurations******* -== APP == val3 : key ->myconfig3 -== APP == val2 : key ->myconfig2 -== APP == val1 : key ->myconfig1 == APP == *****Subscribing to keys using subscribe method: [myconfig1, myconfig3, myconfig2] ***** == APP == update_myconfigvalue1 : key ->myconfig1 == APP == update_myconfigvalue2 : key ->myconfig2 diff --git a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java index e2c5a73287..69c7df3e1f 100644 --- a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java +++ b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java @@ -467,25 +467,6 @@ public Mono> getConfigurations( return this.getConfigurations(request); } - /** - * {@inheritDoc} - */ - @Override - public Mono> getAllConfigurations(String storeName) { - GetBulkConfigurationRequest request = new GetBulkConfigurationRequest(storeName, null); - return this.getAllConfigurations(request); - } - - /** - * {@inheritDoc} - */ - @Override - public Mono> getAllConfigurations(String storeName, Map metadata) { - GetBulkConfigurationRequest request = new GetBulkConfigurationRequest(storeName, null); - request.setMetadata(metadata); - return this.getAllConfigurations(request); - } - /** * {@inheritDoc} */ diff --git a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java index 2137a39a45..b419b4df24 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java @@ -745,32 +745,6 @@ public Mono> getConfigurations(GetBulkConfigurationReque } } - /** - * {@inheritDoc} - */ - @Override - public Mono> getAllConfigurations(GetBulkConfigurationRequest request) { - try { - final String configurationStoreName = request.getStoreName(); - final Map metadata = request.getMetadata(); - - if ((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { - throw new IllegalArgumentException("Configuration Store Name cannot be null or empty."); - } - DaprProtos.GetConfigurationRequest.Builder builder = DaprProtos.GetConfigurationRequest.newBuilder() - .setStoreName(configurationStoreName); - if (metadata != null) { - builder.putAllMetadata(metadata); - } - - DaprProtos.GetConfigurationRequest envelope = builder.build(); - return this.getConfigurationAlpha1(envelope); - - } catch (Exception ex) { - return DaprException.wrapMono(ex); - } - } - private Mono> getConfigurationAlpha1(DaprProtos.GetConfigurationRequest envelope) { return Mono.subscriberContext().flatMap( context -> diff --git a/sdk/src/main/java/io/dapr/client/DaprClientHttp.java b/sdk/src/main/java/io/dapr/client/DaprClientHttp.java index de01836e5e..b432913488 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientHttp.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientHttp.java @@ -686,14 +686,6 @@ public Mono> getConfigurations(GetBulkConfigurationReque throw new DaprException("501", "Implementation not supported"); } - /** - * {@inheritDoc} - */ - @Override - public Mono> getAllConfigurations(GetBulkConfigurationRequest request) { - throw new DaprException("501", "Implementation not supported"); - } - /** * {@inheritDoc} */ diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java index c6d22da2b2..00edfa6140 100644 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java @@ -96,31 +96,6 @@ public interface DaprPreviewClient extends AutoCloseable { Mono> getConfigurations(GetBulkConfigurationRequest request); - /** - * Retrieve List of configurations based on a provided configuration request object. - * - * @param storeName Name of the configuration store - * @return Mono of List of ConfigurationItems - */ - Mono> getAllConfigurations(String storeName); - - /** - * Retrieve List of configurations based on a provided configuration request object. - * - * @param storeName Name of the configuration store - * @param metadata optional metadata - * @return Mono of List of ConfigurationItems - */ - Mono> getAllConfigurations(String storeName, Map metadata); - - /** - * Retrieve List of configurations based on a provided configuration request object. - * - * @param request request for retrieving Configurations for a list keys - * @return Mono of List of ConfigurationItems - */ - Mono> getAllConfigurations(GetBulkConfigurationRequest request); - /** * Subscribe to the keys for any change. * diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java index 726a125171..ec057f4ec0 100644 --- a/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java @@ -97,10 +97,6 @@ public void getConfigurationIllegalArgumentExceptionTest() { assertThrows(IllegalArgumentException.class, () -> { previewClient.getConfigurations("", "key1").block(); }); - //Empty store name - assertThrows(IllegalArgumentException.class, () -> { - previewClient.getAllConfigurations("").block(); - }); // Empty key assertThrows(IllegalArgumentException.class, () -> { previewClient.getConfiguration(CONFIG_STORE_NAME, "").block(); @@ -185,36 +181,6 @@ public void getMultipleConfigurationWithMetadataTest() { assertEquals("configvalue1", cis.stream().findFirst().get().getValue()); } - @Test - public void getAllConfigurationTest() { - doAnswer((Answer) invocation -> { - StreamObserver observer = - (StreamObserver) invocation.getArguments()[1]; - observer.onNext(getMultipleMockResponse()); - observer.onCompleted(); - return null; - }).when(daprStub).getConfigurationAlpha1(any(DaprProtos.GetConfigurationRequest.class), any()); - - List cis = previewClient.getAllConfigurations(CONFIG_STORE_NAME).block(); - assertEquals(2, cis.size()); - } - - @Test - public void getAllConfigurationWithMetadataTest() { - doAnswer((Answer) invocation -> { - StreamObserver observer = - (StreamObserver) invocation.getArguments()[1]; - observer.onNext(getMultipleMockResponse()); - observer.onCompleted(); - return null; - }).when(daprStub).getConfigurationAlpha1(any(DaprProtos.GetConfigurationRequest.class), any()); - - Map reqMetadata = new HashMap<>(); - reqMetadata.put("meta1", "value1"); - List cis = previewClient.getAllConfigurations(CONFIG_STORE_NAME, reqMetadata).block(); - assertEquals(2, cis.size()); - } - @Test public void subscribeConfigurationTest() { Map metadata = new HashMap<>(); diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java index b20d70c0ab..d47ad14f02 100644 --- a/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java @@ -95,13 +95,6 @@ public void getConfigurations() { }); } - @Test - public void getAllConfigurations() { - assertThrows(DaprException.class, () -> { - daprPreviewClientHttp.getAllConfigurations(CONFIG_STORE_NAME).block(); - }); - } - @Test public void subscribeConfigurations() { assertThrows(DaprException.class, () -> { From 6e8a4ecf2f41fdacf4a72d6cf0715178db542e0d Mon Sep 17 00:00:00 2001 From: pravinpushkar Date: Wed, 12 Jan 2022 22:13:55 +0530 Subject: [PATCH 11/13] Fixing review comments Signed-off-by: pravinpushkar --- .../grpc/ConfigurationClient.java | 16 +- .../examples/configuration/grpc/README.md | 5 +- .../grpc/ConfigurationClientIT.java | 10 +- .../io/dapr/client/AbstractDaprClient.java | 53 +++--- .../io/dapr/client/DaprClientBuilder.java | 10 ++ .../java/io/dapr/client/DaprClientGrpc.java | 38 +---- .../java/io/dapr/client/DaprClientHttp.java | 17 +- .../io/dapr/client/DaprPreviewClient.java | 39 +---- .../dapr/client/DaprPreviewClientBuilder.java | 158 ------------------ .../dapr/client/domain/ConfigurationItem.java | 2 +- .../domain/GetBulkConfigurationRequest.java | 47 ------ .../domain/GetConfigurationRequest.java | 10 +- .../client/DaprPreviewClientBuilderTest.java | 43 ----- .../client/DaprPreviewClientGrpcTest.java | 60 +------ .../client/DaprPreviewClientHttpTest.java | 92 +--------- 15 files changed, 75 insertions(+), 525 deletions(-) delete mode 100644 sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java delete mode 100644 sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java delete mode 100644 sdk/src/test/java/io/dapr/client/DaprPreviewClientBuilderTest.java diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java index 24dd46cdc3..e549a43a55 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java @@ -13,10 +13,9 @@ package io.dapr.examples.configuration.grpc; +import io.dapr.client.DaprClientBuilder; import io.dapr.client.DaprPreviewClient; -import io.dapr.client.DaprPreviewClientBuilder; import io.dapr.client.domain.ConfigurationItem; -import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.GetConfigurationRequest; import io.dapr.client.domain.SubscribeConfigurationRequest; import reactor.core.Disposable; @@ -41,7 +40,7 @@ public class ConfigurationClient { * @throws Exception throws Exception */ public static void main(String[] args) throws Exception { - try (DaprPreviewClient client = (new DaprPreviewClientBuilder()).build()) { + try (DaprPreviewClient client = (new DaprClientBuilder()).buildPreviewClient()) { System.out.println("Using preview client..."); getConfigurationForaSingleKey(client); getConfigurationsUsingVarargs(client); @@ -57,9 +56,8 @@ public static void main(String[] args) throws Exception { */ public static void getConfigurationForaSingleKey(DaprPreviewClient client) { System.out.println("*******trying to retrieve configuration given a single key********"); - GetConfigurationRequest request = new GetConfigurationRequest(CONFIG_STORE_NAME, keys.get(0)); try { - Mono item = client.getConfiguration(request); + Mono item = client.getConfiguration(CONFIG_STORE_NAME, keys.get(0)); System.out.println("Value ->" + item.block().getValue() + " key ->" + item.block().getKey()); } catch (Exception ex) { System.out.println(ex.getMessage()); @@ -75,7 +73,7 @@ public static void getConfigurationsUsingVarargs(DaprPreviewClient client) { System.out.println("*******trying to retrieve configurations for a variable no. of keys********"); try { Mono> items = - client.getConfigurations(CONFIG_STORE_NAME, "myconfig1", "myconfig3"); + client.getConfiguration(CONFIG_STORE_NAME, "myconfig1", "myconfig3"); items.block().forEach(ConfigurationClient::print); } catch (Exception ex) { System.out.println(ex.getMessage()); @@ -93,9 +91,9 @@ public static void getConfigurations(DaprPreviewClient client) { keys.add("myconfig1"); keys.add("myconfig2"); keys.add("myconfig3"); - GetBulkConfigurationRequest req = new GetBulkConfigurationRequest(CONFIG_STORE_NAME, keys); + GetConfigurationRequest req = new GetConfigurationRequest(CONFIG_STORE_NAME, keys); try { - Mono> items = client.getConfigurations(req); + Mono> items = client.getConfiguration(req); items.block().forEach(ConfigurationClient::print); } catch (Exception ex) { System.out.println(ex.getMessage()); @@ -112,7 +110,7 @@ public static void subscribeConfigurationRequestWithSubscribe(DaprPreviewClient AtomicReference disposableAtomicReference = new AtomicReference<>(); SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(CONFIG_STORE_NAME, keys); Runnable subscribeTask = () -> { - Flux> outFlux = client.subscribeToConfigurations(req); + Flux> outFlux = client.subscribeToConfiguration(req); disposableAtomicReference.set(outFlux .subscribe( cis -> cis.forEach(ConfigurationClient::print) diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md b/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md index 6002b387a0..b784912042 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/README.md @@ -6,12 +6,9 @@ This example provides the different capabilities provided by Dapr Java SDK for C ### Using the ConfigurationAPI The java SDK exposes several methods for this - -* `client.getConfiguration(...)` for getting a configuration for a single key. -* `client.getConfigurations(...)` for getting a configurations by passing a variable no. of arguments or list of argumets. +* `client.getConfiguration(...)` for getting a configuration for a single/multiple keys. * `client.subscribeToConfigurations(...)` for subscribing to a list of keys for any change. -The code uses the `DaprPreviewClient` created by the `DaprPreviewClientBuilder`. - ## Pre-requisites * [Dapr and Dapr Cli](https://docs.dapr.io/getting-started/install-dapr/). diff --git a/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java b/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java index 7bc5344229..612dc4dc8f 100644 --- a/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java +++ b/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java @@ -5,8 +5,8 @@ package io.dapr.it.configuration.grpc; +import io.dapr.client.DaprClientBuilder; import io.dapr.client.DaprPreviewClient; -import io.dapr.client.DaprPreviewClientBuilder; import io.dapr.client.domain.ConfigurationItem; import io.dapr.it.BaseIT; import io.dapr.it.DaprRun; @@ -54,7 +54,7 @@ public class ConfigurationClientIT extends BaseIT { public static void init() throws Exception { daprRun = startDaprApp(ConfigurationClientIT.class.getSimpleName(), 5000); daprRun.switchToGRPC(); - daprPreviewClient = new DaprPreviewClientBuilder().build(); + daprPreviewClient = new DaprClientBuilder().buildPreviewClient(); } @AfterClass @@ -83,7 +83,7 @@ public void getConfigurationWithEmptyKey() { @Test public void getConfigurations() { - List cis = daprPreviewClient.getConfigurations(CONFIG_STORE_NAME, "myconfigkey1", "myconfigkey2").block(); + List cis = daprPreviewClient.getConfiguration(CONFIG_STORE_NAME, "myconfigkey1", "myconfigkey2").block(); assertTrue(cis.size() == 2); assertEquals(cis.get(0).getKey(), "myconfigkey1"); assertEquals(cis.get(1).getValue(), "myconfigvalue2"); @@ -94,7 +94,7 @@ public void getConfigurationsWithEmptyList() { List listOfKeys = new ArrayList<>(); Map metadata = new HashMap<>(); assertThrows(IllegalArgumentException.class, () -> { - daprPreviewClient.getConfigurations(CONFIG_STORE_NAME, listOfKeys, metadata).block(); + daprPreviewClient.getConfiguration(CONFIG_STORE_NAME, listOfKeys, metadata).block(); }); } @@ -104,7 +104,7 @@ public void subscribeToConfiguration() { AtomicReference disposable = new AtomicReference<>(); Runnable subscribeTask = () -> { Flux> outFlux = daprPreviewClient - .subscribeToConfigurations(CONFIG_STORE_NAME, "myconfigkey1", "myconfigkey2"); + .subscribeToConfiguration(CONFIG_STORE_NAME, "myconfigkey1", "myconfigkey2"); disposable.set(outFlux.subscribe(update -> { updatedValues.add(update.get(0).getValue()); })); diff --git a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java index 69c7df3e1f..cfc4b47337 100644 --- a/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java +++ b/sdk/src/main/java/io/dapr/client/AbstractDaprClient.java @@ -15,28 +15,17 @@ import io.dapr.client.domain.ConfigurationItem; import io.dapr.client.domain.DeleteStateRequest; -import io.dapr.client.domain.DeleteStateRequestBuilder; import io.dapr.client.domain.ExecuteStateTransactionRequest; -import io.dapr.client.domain.ExecuteStateTransactionRequestBuilder; -import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.GetBulkSecretRequest; -import io.dapr.client.domain.GetBulkSecretRequestBuilder; import io.dapr.client.domain.GetBulkStateRequest; -import io.dapr.client.domain.GetBulkStateRequestBuilder; import io.dapr.client.domain.GetConfigurationRequest; import io.dapr.client.domain.GetSecretRequest; -import io.dapr.client.domain.GetSecretRequestBuilder; import io.dapr.client.domain.GetStateRequest; -import io.dapr.client.domain.GetStateRequestBuilder; import io.dapr.client.domain.HttpExtension; import io.dapr.client.domain.InvokeBindingRequest; -import io.dapr.client.domain.InvokeBindingRequestBuilder; import io.dapr.client.domain.InvokeMethodRequest; -import io.dapr.client.domain.InvokeMethodRequestBuilder; import io.dapr.client.domain.PublishEventRequest; -import io.dapr.client.domain.PublishEventRequestBuilder; import io.dapr.client.domain.SaveStateRequest; -import io.dapr.client.domain.SaveStateRequestBuilder; import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; import io.dapr.client.domain.SubscribeConfigurationRequest; @@ -428,8 +417,8 @@ public Mono>> getBulkSecret(String storeName, Ma */ @Override public Mono getConfiguration(String storeName, String key) { - GetConfigurationRequest request = new GetConfigurationRequest(storeName, key); - return this.getConfiguration(request); + GetConfigurationRequest request = new GetConfigurationRequest(storeName, filterEmptyKeys(key)); + return this.getConfiguration(request).map(data -> data.get(0)); } /** @@ -437,56 +426,58 @@ public Mono getConfiguration(String storeName, String key) { */ @Override public Mono getConfiguration(String storeName, String key, Map metadata) { - GetConfigurationRequest request = new GetConfigurationRequest(storeName, key); + GetConfigurationRequest request = new GetConfigurationRequest(storeName, filterEmptyKeys(key)); request.setMetadata(metadata); - return this.getConfiguration(request); + return this.getConfiguration(request).map(data -> data.get(0)); } /** * {@inheritDoc} */ @Override - public Mono> getConfigurations(String storeName, String... keys) { - List listOfKeys = Arrays.stream(keys) - .filter(key -> !key.trim().isEmpty()) - .collect(Collectors.toList()); - GetBulkConfigurationRequest request = new GetBulkConfigurationRequest(storeName, listOfKeys); - return this.getConfigurations(request); + public Mono> getConfiguration(String storeName, String... keys) { + List listOfKeys = filterEmptyKeys(keys); + GetConfigurationRequest request = new GetConfigurationRequest(storeName, listOfKeys); + return this.getConfiguration(request); } /** * {@inheritDoc} */ @Override - public Mono> getConfigurations( + public Mono> getConfiguration( String storeName, List keys, Map metadata) { - GetBulkConfigurationRequest request = new GetBulkConfigurationRequest(storeName, keys); + GetConfigurationRequest request = new GetConfigurationRequest(storeName, keys); request.setMetadata(metadata); - return this.getConfigurations(request); + return this.getConfiguration(request); } /** * {@inheritDoc} */ - public Flux> subscribeToConfigurations(String storeName, String... keys) { - List listOfKeys = Arrays.stream(keys) - .filter(key -> !key.trim().isEmpty()) - .collect(Collectors.toList()); + public Flux> subscribeToConfiguration(String storeName, String... keys) { + List listOfKeys = filterEmptyKeys(keys); SubscribeConfigurationRequest request = new SubscribeConfigurationRequest(storeName, listOfKeys); - return this.subscribeToConfigurations(request); + return this.subscribeToConfiguration(request); } /** * {@inheritDoc} */ - public Flux> subscribeToConfigurations( + public Flux> subscribeToConfiguration( String storeName, List keys, Map metadata) { SubscribeConfigurationRequest request = new SubscribeConfigurationRequest(storeName, keys); request.setMetadata(metadata); - return this.subscribeToConfigurations(request); + return this.subscribeToConfiguration(request); + } + + private List filterEmptyKeys(String... keys) { + return Arrays.stream(keys) + .filter(key -> !key.trim().isEmpty()) + .collect(Collectors.toList()); } } diff --git a/sdk/src/main/java/io/dapr/client/DaprClientBuilder.java b/sdk/src/main/java/io/dapr/client/DaprClientBuilder.java index ba4a2229fe..855c6013e1 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientBuilder.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientBuilder.java @@ -117,6 +117,16 @@ public DaprClient build() { return buildDaprClient(this.apiProtocol); } + /** + * Build an instance of the Client based on the provided setup. + * + * @return an instance of the setup Client + * @throws IllegalStateException if any required field is missing + */ + public DaprPreviewClient buildPreviewClient() { + return (DaprPreviewClient) buildDaprClient(this.apiProtocol); + } + /** * Creates an instance of a Dapr Client based on the chosen protocol. * diff --git a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java index b419b4df24..401b7690df 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java @@ -20,7 +20,6 @@ import io.dapr.client.domain.ConfigurationItem; import io.dapr.client.domain.DeleteStateRequest; import io.dapr.client.domain.ExecuteStateTransactionRequest; -import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.GetBulkSecretRequest; import io.dapr.client.domain.GetBulkStateRequest; import io.dapr.client.domain.GetConfigurationRequest; @@ -683,48 +682,15 @@ public Mono shutdown() { ).then(); } - /** - *{@inheritDoc} - */ - @Override - public Mono getConfiguration(GetConfigurationRequest request) { - try { - final String configurationStoreName = request.getStoreName(); - final String key = request.getKey(); - final Map metadata = request.getMetadata(); - - if ((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { - throw new IllegalArgumentException("Configuration Store Name cannot be null or empty."); - } - if ((key == null) || (key.trim().isEmpty())) { - throw new IllegalArgumentException("Key cannot be null or empty."); - } - DaprProtos.GetConfigurationRequest.Builder builder = DaprProtos.GetConfigurationRequest.newBuilder() - .setStoreName(configurationStoreName) - .addKeys(key); - if (metadata != null) { - builder.putAllMetadata(metadata); - } - - DaprProtos.GetConfigurationRequest envelope = builder.build(); - return this.getConfigurationAlpha1(envelope).map( - it -> it.get(0) - ); - } catch (Exception ex) { - return DaprException.wrapMono(ex); - } - } - /** * {@inheritDoc} */ @Override - public Mono> getConfigurations(GetBulkConfigurationRequest request) { + public Mono> getConfiguration(GetConfigurationRequest request) { try { final String configurationStoreName = request.getStoreName(); final Map metadata = request.getMetadata(); final List keys = request.getKeys(); - if ((configurationStoreName == null) || (configurationStoreName.trim().isEmpty())) { throw new IllegalArgumentException("Configuration Store Name cannot be null or empty."); } @@ -762,7 +728,7 @@ private Mono> getConfigurationAlpha1(DaprProtos.GetConfi * {@inheritDoc} */ @Override - public Flux> subscribeToConfigurations(SubscribeConfigurationRequest request) { + public Flux> subscribeToConfiguration(SubscribeConfigurationRequest request) { try { final String configurationStoreName = request.getStoreName(); final List keys = request.getKeys(); diff --git a/sdk/src/main/java/io/dapr/client/DaprClientHttp.java b/sdk/src/main/java/io/dapr/client/DaprClientHttp.java index b432913488..ed4522c996 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientHttp.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientHttp.java @@ -18,7 +18,6 @@ import io.dapr.client.domain.ConfigurationItem; import io.dapr.client.domain.DeleteStateRequest; import io.dapr.client.domain.ExecuteStateTransactionRequest; -import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.GetBulkSecretRequest; import io.dapr.client.domain.GetBulkStateRequest; import io.dapr.client.domain.GetConfigurationRequest; @@ -674,24 +673,16 @@ public Mono shutdown() { * {@inheritDoc} */ @Override - public Mono getConfiguration(GetConfigurationRequest request) { - throw new DaprException("501", "Implementation not supported"); + public Mono> getConfiguration(GetConfigurationRequest request) { + return DaprException.wrapMono(new UnsupportedOperationException()); } /** * {@inheritDoc} */ @Override - public Mono> getConfigurations(GetBulkConfigurationRequest request) { - throw new DaprException("501", "Implementation not supported"); - } - - /** - * {@inheritDoc} - */ - @Override - public Flux> subscribeToConfigurations(SubscribeConfigurationRequest request) { - throw new DaprException("501", "Implementation not supported"); + public Flux> subscribeToConfiguration(SubscribeConfigurationRequest request) { + return DaprException.wrapFlux(new UnsupportedOperationException()); } /** diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java index 00edfa6140..ffe58f3cd4 100644 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java @@ -14,7 +14,6 @@ package io.dapr.client; import io.dapr.client.domain.ConfigurationItem; -import io.dapr.client.domain.GetBulkConfigurationRequest; import io.dapr.client.domain.GetConfigurationRequest; import io.dapr.client.domain.SubscribeConfigurationRequest; import reactor.core.publisher.Flux; @@ -25,22 +24,6 @@ public interface DaprPreviewClient extends AutoCloseable { - - /** - * Waits for the sidecar, giving up after timeout. - * - * @param timeoutInMilliseconds Timeout in milliseconds to wait for sidecar. - * @return a Mono plan of type Void. - */ - Mono waitForSidecar(int timeoutInMilliseconds); - - /** - * Gracefully shutdown the dapr runtime. - * - * @return a Mono plan of type Void. - */ - Mono shutdown(); - /** * Retrieve a configuration based on a provided key. * @@ -60,14 +43,6 @@ public interface DaprPreviewClient extends AutoCloseable { */ Mono getConfiguration(String storeName, String key, Map metadata); - /** - * Retrieve a configuration based on a provided request object. - * - * @param request request for retrieving Configuration for a single key - * @return Mono of the Configuration Item - */ - Mono getConfiguration(GetConfigurationRequest request); - /** * Retrieve List of configurations based on a provided variable number of keys. * @@ -75,7 +50,7 @@ public interface DaprPreviewClient extends AutoCloseable { * @param keys keys of the configurations which are to be retrieved * @return Mono of List of ConfigurationItems */ - Mono> getConfigurations(String storeName, String... keys); + Mono> getConfiguration(String storeName, String... keys); /** * Retrieve List of configurations based on a provided variable number of keys. @@ -85,7 +60,7 @@ public interface DaprPreviewClient extends AutoCloseable { * @param metadata optional metadata * @return Mono of List of ConfigurationItems */ - Mono> getConfigurations(String storeName, List keys, Map metadata); + Mono> getConfiguration(String storeName, List keys, Map metadata); /** * Retrieve List of configurations based on a provided configuration request object. @@ -94,7 +69,7 @@ public interface DaprPreviewClient extends AutoCloseable { * @return Mono of List of ConfigurationItems */ - Mono> getConfigurations(GetBulkConfigurationRequest request); + Mono> getConfiguration(GetConfigurationRequest request); /** * Subscribe to the keys for any change. @@ -103,7 +78,7 @@ public interface DaprPreviewClient extends AutoCloseable { * @param keys keys of the configurations which are to be subscribed * @return Flux of List of configuration items */ - Flux> subscribeToConfigurations(String storeName, String... keys); + Flux> subscribeToConfiguration(String storeName, String... keys); /** * Subscribe to the keys for any change. @@ -113,8 +88,8 @@ public interface DaprPreviewClient extends AutoCloseable { * @param metadata optional metadata * @return Flux of List of configuration items */ - Flux> subscribeToConfigurations(String storeName, List keys, - Map metadata); + Flux> subscribeToConfiguration(String storeName, List keys, + Map metadata); /** * Subscribe to the keys for any change. @@ -122,5 +97,5 @@ Flux> subscribeToConfigurations(String storeName, List> subscribeToConfigurations(SubscribeConfigurationRequest request); + Flux> subscribeToConfiguration(SubscribeConfigurationRequest request); } diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java deleted file mode 100644 index db5d92862c..0000000000 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClientBuilder.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2021 The Dapr Authors - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and -limitations under the License. -*/ - -package io.dapr.client; - -import io.dapr.config.Properties; -import io.dapr.serializer.DaprObjectSerializer; -import io.dapr.serializer.DefaultObjectSerializer; -import io.dapr.v1.DaprGrpc; -import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; - -import java.io.Closeable; - -public class DaprPreviewClientBuilder { - - /** - * Determine if this builder will create GRPC clients instead of HTTP clients. - */ - private final DaprApiProtocol apiProtocol; - - /** - * Builder for Dapr's HTTP Client. - */ - private final DaprHttpBuilder daprHttpBuilder; - - /** - * Serializer used for request and response objects in DaprClient. - */ - private DaprObjectSerializer objectSerializer; - - /** - * Serializer used for state objects in DaprClient. - */ - private DaprObjectSerializer stateSerializer; - - /** - * Creates a constructor for DaprClient. - * - * {@link DefaultObjectSerializer} is used for object and state serializers by defaul but is not recommended - * for production scenarios. - */ - public DaprPreviewClientBuilder() { - this.objectSerializer = new DefaultObjectSerializer(); - this.stateSerializer = new DefaultObjectSerializer(); - this.apiProtocol = Properties.API_PROTOCOL.get(); - this.daprHttpBuilder = new DaprHttpBuilder(); - } - - /** - * Sets the serializer for objects to be sent and received from Dapr. - * See {@link DefaultObjectSerializer} as possible serializer for non-production scenarios. - * - * @param objectSerializer Serializer for objects to be sent and received from Dapr. - * @return This instance. - */ - public DaprPreviewClientBuilder withObjectSerializer(DaprObjectSerializer objectSerializer) { - if (objectSerializer == null) { - throw new IllegalArgumentException("Object serializer is required"); - } - - if (objectSerializer.getContentType() == null || objectSerializer.getContentType().isEmpty()) { - throw new IllegalArgumentException("Content Type should not be null or empty"); - } - - this.objectSerializer = objectSerializer; - return this; - } - - /** - * Sets the serializer for objects to be persisted. - * See {@link DefaultObjectSerializer} as possible serializer for non-production scenarios. - * - * @param stateSerializer Serializer for objects to be persisted. - * @return This instance. - */ - public DaprPreviewClientBuilder withStateSerializer(DaprObjectSerializer stateSerializer) { - if (stateSerializer == null) { - throw new IllegalArgumentException("State serializer is required"); - } - - this.stateSerializer = stateSerializer; - return this; - } - - /** - * Build an instance of the Client based on the provided setup. - * - * @return an instance of the setup Client - * @throws IllegalStateException if any required field is missing - */ - public DaprPreviewClient build() { - return buildDaprPreviewClient(this.apiProtocol); - } - - /** - * Creates an instance of a Dapr Client based on the chosen protocol. - * - * @param protocol Dapr API's protocol. - * @return the GRPC Client. - * @throws IllegalStateException if either host is missing or if port is missing or a negative number. - */ - private DaprPreviewClient buildDaprPreviewClient(DaprApiProtocol protocol) { - if (protocol == null) { - throw new IllegalStateException("Protocol is required."); - } - - switch (protocol) { - case GRPC: - return buildDaprClientGrpc(); - case HTTP: - return buildDaprClientHttp(); - default: - throw new IllegalStateException("Unsupported protocol: " + protocol.name()); - } - } - - /** - * Creates an instance of the GPRC Client. - * - * @return the GRPC Client. - * @throws IllegalStateException if either host is missing or if port is missing or a negative number. - */ - private DaprPreviewClient buildDaprClientGrpc() { - int port = Properties.GRPC_PORT.get(); - if (port <= 0) { - throw new IllegalArgumentException("Invalid port."); - } - ManagedChannel channel = ManagedChannelBuilder.forAddress( - Properties.SIDECAR_IP.get(), port).usePlaintext().build(); - Closeable closeableChannel = () -> { - if (channel != null && !channel.isShutdown()) { - channel.shutdown(); - } - }; - DaprGrpc.DaprStub asyncStub = DaprGrpc.newStub(channel); - return new DaprClientGrpc(closeableChannel, asyncStub, this.objectSerializer, this.stateSerializer); - } - - /** - * Creates and instance of DaprClient over HTTP. - * - * @return DaprClient over HTTP. - */ - private DaprPreviewClient buildDaprClientHttp() { - return new DaprClientHttp(this.daprHttpBuilder.build(), this.objectSerializer, this.stateSerializer); - } -} diff --git a/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java b/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java index de5d1430a0..ec61e9d174 100644 --- a/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java +++ b/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java @@ -48,7 +48,7 @@ public ConfigurationItem(String key, String value, String version) { this.key = key; this.value = value; this.version = version; - this.metadata = null; + this.metadata = Collections.emptyMap(); } public String getKey() { diff --git a/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java deleted file mode 100644 index 4c95af0a75..0000000000 --- a/sdk/src/main/java/io/dapr/client/domain/GetBulkConfigurationRequest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2021 The Dapr Authors - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and -limitations under the License. -*/ - -package io.dapr.client.domain; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public class GetBulkConfigurationRequest { - private final String storeName; - private final List keys; - private Map metadata; - - public GetBulkConfigurationRequest(String storeName, List keys) { - this.storeName = storeName; - this.keys = keys == null ? Collections.EMPTY_LIST : Collections.unmodifiableList(keys); - } - - public GetBulkConfigurationRequest setMetadata(Map metadata) { - this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata); - return this; - } - - public String getStoreName() { - return storeName; - } - - public List getKeys() { - return keys; - } - - public Map getMetadata() { - return metadata; - } -} diff --git a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java index a8c9cd3b55..e72051b2eb 100644 --- a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java +++ b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java @@ -19,12 +19,12 @@ public class GetConfigurationRequest { private final String storeName; - private final String key; + private final List keys; private Map metadata; - public GetConfigurationRequest(String storeName, String key) { + public GetConfigurationRequest(String storeName, List keys) { this.storeName = storeName; - this.key = key; + this.keys = keys == null ? Collections.EMPTY_LIST : Collections.unmodifiableList(keys); } public GetConfigurationRequest setMetadata(Map metadata) { @@ -36,8 +36,8 @@ public String getStoreName() { return storeName; } - public String getKey() { - return key; + public List getKeys() { + return keys; } public Map getMetadata() { diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientBuilderTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientBuilderTest.java deleted file mode 100644 index e1e1e289e9..0000000000 --- a/sdk/src/test/java/io/dapr/client/DaprPreviewClientBuilderTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) Microsoft Corporation and Dapr Contributors. - * Licensed under the MIT License. - */ - -package io.dapr.client; - -import io.dapr.serializer.DaprObjectSerializer; -import org.junit.Test; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class DaprPreviewClientBuilderTest { - - @Test - public void build() { - DaprObjectSerializer objectSerializer = mock(DaprObjectSerializer.class); - when(objectSerializer.getContentType()).thenReturn("application/json"); - DaprObjectSerializer stateSerializer = mock(DaprObjectSerializer.class); - DaprPreviewClientBuilder daprPreviewClientBuilder = new DaprPreviewClientBuilder(); - daprPreviewClientBuilder.withObjectSerializer(objectSerializer); - daprPreviewClientBuilder.withStateSerializer(stateSerializer); - DaprPreviewClient daprPreviewClient = daprPreviewClientBuilder.build(); - assertNotNull(daprPreviewClient); - } - - @Test(expected = IllegalArgumentException.class) - public void noObjectSerializer() { - new DaprPreviewClientBuilder().withObjectSerializer(null); - } - - @Test(expected = IllegalArgumentException.class) - public void blankContentTypeInObjectSerializer() { - new DaprPreviewClientBuilder().withObjectSerializer(mock(DaprObjectSerializer.class)); - } - - @Test(expected = IllegalArgumentException.class) - public void noStateSerializer() { - new DaprPreviewClientBuilder().withStateSerializer(null); - } -} diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java index ec057f4ec0..009e5bd3b4 100644 --- a/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java @@ -7,7 +7,6 @@ import io.dapr.client.domain.ConfigurationItem; -import io.dapr.config.Properties; import io.dapr.serializer.DefaultObjectSerializer; import io.dapr.v1.CommonProtos; import io.dapr.v1.DaprGrpc; @@ -20,8 +19,6 @@ import java.io.Closeable; import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; @@ -30,7 +27,6 @@ import java.util.concurrent.ExecutionException; import static io.dapr.utils.TestUtils.assertThrowsDaprException; -import static io.dapr.utils.TestUtils.findFreePort; import static org.junit.Assert.*; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -43,7 +39,6 @@ public class DaprPreviewClientGrpcTest { private Closeable closeable; private DaprGrpc.DaprStub daprStub; private DaprPreviewClient previewClient; - private ObjectSerializer serializer; @Before public void setup() throws IOException { @@ -52,7 +47,6 @@ public void setup() throws IOException { when(daprStub.withInterceptors(any())).thenReturn(daprStub); previewClient = new DaprClientGrpc( closeable, daprStub, new DefaultObjectSerializer(), new DefaultObjectSerializer()); - serializer = new ObjectSerializer(); doNothing().when(closeable).close(); } @@ -64,46 +58,12 @@ public void tearDown() throws Exception { } @Test - public void waitForSidecarTimeout() throws Exception { - int port = findFreePort(); - System.setProperty(Properties.GRPC_PORT.getName(), Integer.toString(port)); - assertThrows(RuntimeException.class, () -> previewClient.waitForSidecar(1).block()); - } - - @Test - public void waitForSidecarTimeoutOK() throws Exception { - try (ServerSocket serverSocket = new ServerSocket(0)) { - final int port = serverSocket.getLocalPort(); - System.setProperty(Properties.GRPC_PORT.getName(), Integer.toString(port)); - Thread t = new Thread(() -> { - try { - try (Socket socket = serverSocket.accept()) { - } - } catch (IOException e) { - } - }); - t.start(); - previewClient.waitForSidecar(10000).block(); - } - } - - @Test - public void getConfigurationIllegalArgumentExceptionTest() { - // Empty Store name - assertThrows(IllegalArgumentException.class, () -> { - previewClient.getConfiguration("", "key1").block(); - }); - //Empty store name - assertThrows(IllegalArgumentException.class, () -> { - previewClient.getConfigurations("", "key1").block(); - }); - // Empty key + public void getConfigurationTestErrorScenario() { assertThrows(IllegalArgumentException.class, () -> { previewClient.getConfiguration(CONFIG_STORE_NAME, "").block(); }); - // Empty key assertThrows(IllegalArgumentException.class, () -> { - previewClient.getConfigurations(CONFIG_STORE_NAME, "").block(); + previewClient.getConfiguration("", "key").block(); }); } @@ -151,7 +111,7 @@ public void getMultipleConfigurationTest() { return null; }).when(daprStub).getConfigurationAlpha1(any(DaprProtos.GetConfigurationRequest.class), any()); - List cis = previewClient.getConfigurations(CONFIG_STORE_NAME, "configkey1","configkey2").block(); + List cis = previewClient.getConfiguration(CONFIG_STORE_NAME, "configkey1","configkey2").block(); assertEquals(2, cis.size()); assertEquals("configkey1", cis.stream().findFirst().get().getKey()); assertEquals("configvalue1", cis.stream().findFirst().get().getValue()); @@ -175,7 +135,7 @@ public void getMultipleConfigurationWithMetadataTest() { Map reqMetadata = new HashMap<>(); reqMetadata.put("meta1", "value1"); List keys = Arrays.asList("configkey1","configkey2"); - List cis = previewClient.getConfigurations(CONFIG_STORE_NAME, keys, reqMetadata).block(); + List cis = previewClient.getConfiguration(CONFIG_STORE_NAME, keys, reqMetadata).block(); assertEquals(2, cis.size()); assertEquals("configkey1", cis.stream().findFirst().get().getKey()); assertEquals("configvalue1", cis.stream().findFirst().get().getValue()); @@ -202,7 +162,7 @@ public void subscribeConfigurationTest() { return null; }).when(daprStub).subscribeConfigurationAlpha1(any(DaprProtos.SubscribeConfigurationRequest.class), any()); - Iterator> itr = previewClient.subscribeToConfigurations(CONFIG_STORE_NAME, "configkey1").toIterable().iterator(); + Iterator> itr = previewClient.subscribeToConfiguration(CONFIG_STORE_NAME, "configkey1").toIterable().iterator(); assertTrue(itr.hasNext()); assertEquals("configkey1", itr.next().get(0).getKey()); assertFalse(itr.hasNext()); @@ -232,7 +192,7 @@ public void subscribeConfigurationTestWithMetadata() { Map reqMetadata = new HashMap<>(); List keys = Arrays.asList("configkey1"); - Iterator> itr = previewClient.subscribeToConfigurations(CONFIG_STORE_NAME, keys, reqMetadata).toIterable().iterator(); + Iterator> itr = previewClient.subscribeToConfiguration(CONFIG_STORE_NAME, keys, reqMetadata).toIterable().iterator(); assertTrue(itr.hasNext()); assertEquals("configkey1", itr.next().get(0).getKey()); assertFalse(itr.hasNext()); @@ -249,15 +209,11 @@ public void subscribeConfigurationWithErrorTest() { }).when(daprStub).subscribeConfigurationAlpha1(any(DaprProtos.SubscribeConfigurationRequest.class), any()); assertThrowsDaprException(ExecutionException.class, () -> { - previewClient.subscribeToConfigurations(CONFIG_STORE_NAME, "key").blockFirst(); - }); - - assertThrows(IllegalArgumentException.class, () -> { - previewClient.subscribeToConfigurations("", "key").blockFirst(); + previewClient.subscribeToConfiguration(CONFIG_STORE_NAME, "key").blockFirst(); }); assertThrows(IllegalArgumentException.class, () -> { - previewClient.subscribeToConfigurations("store", "").blockFirst(); + previewClient.subscribeToConfiguration("", "key").blockFirst(); }); } diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java index d47ad14f02..b70e223f4f 100644 --- a/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprPreviewClientHttpTest.java @@ -32,8 +32,6 @@ public class DaprPreviewClientHttpTest { private DaprPreviewClient daprPreviewClientHttp; - private DaprPreviewClient daprPreviewClientHttpXML; - private DaprHttp daprHttp; private OkHttpClient okHttpClient; @@ -46,39 +44,6 @@ public void setUp() { okHttpClient = new OkHttpClient.Builder().addInterceptor(mockInterceptor).build(); daprHttp = new DaprHttp(Properties.SIDECAR_IP.get(), 3000, okHttpClient); daprPreviewClientHttp = new DaprClientHttp(daprHttp); - daprPreviewClientHttpXML = new DaprClientHttp( - daprHttp, - new DaprPreviewClientHttpTest.XmlSerializer(), - new DaprPreviewClientHttpTest.XmlSerializer() - ); - } - - @Test - public void waitForSidecarTimeout() throws Exception { - int port = findFreePort(); - System.setProperty(Properties.HTTP_PORT.getName(), Integer.toString(port)); - daprHttp = new DaprHttp(Properties.SIDECAR_IP.get(), port, okHttpClient); - DaprClientHttp daprClientHttp = new DaprClientHttp(daprHttp); - assertThrows(RuntimeException.class, () -> daprClientHttp.waitForSidecar(1).block()); - } - - @Test - public void waitForSidecarTimeoutOK() throws Exception { - try (ServerSocket serverSocket = new ServerSocket(0)) { - final int port = serverSocket.getLocalPort(); - System.setProperty(Properties.HTTP_PORT.getName(), Integer.toString(port)); - Thread t = new Thread(() -> { - try { - try (Socket socket = serverSocket.accept()) { - } - } catch (IOException e) { - } - }); - t.start(); - daprHttp = new DaprHttp(Properties.SIDECAR_IP.get(), port, okHttpClient); - DaprClientHttp daprClientHttp = new DaprClientHttp(daprHttp); - daprClientHttp.waitForSidecar(10000).block(); - } } @Test @@ -89,67 +54,16 @@ public void getConfigurationWithSingleKey() { } @Test - public void getConfigurations() { + public void getConfiguration() { assertThrows(DaprException.class, () -> { - daprPreviewClientHttp.getConfigurations(CONFIG_STORE_NAME, "key1", "key2").block(); + daprPreviewClientHttp.getConfiguration(CONFIG_STORE_NAME, "key1", "key2").block(); }); } @Test public void subscribeConfigurations() { assertThrows(DaprException.class, () -> { - daprPreviewClientHttp.subscribeToConfigurations(CONFIG_STORE_NAME, "key1", "key2"); + daprPreviewClientHttp.subscribeToConfiguration(CONFIG_STORE_NAME, "key1", "key2").blockFirst(); }); } - - @Test - public void closeException() { - DaprHttp daprHttp = Mockito.mock(DaprHttp.class); - Mockito.doThrow(new RuntimeException()).when(daprHttp).close(); - - // This method does not throw DaprException because it already throws RuntimeException and does not call Dapr. - daprPreviewClientHttp = new DaprClientHttp(daprHttp); - assertThrows(RuntimeException.class, () -> daprPreviewClientHttp.close()); - } - - @Test - public void close() throws Exception { - DaprHttp daprHttp = Mockito.mock(DaprHttp.class); - Mockito.doNothing().when(daprHttp).close(); - - // This method does not throw DaprException because IOException is expected by the Closeable interface. - daprPreviewClientHttp = new DaprClientHttp(daprHttp); - daprPreviewClientHttp.close(); - } - - @Test - public void shutdown() throws Exception { - mockInterceptor.addRule() - .post("http://127.0.0.1:3000/v1.0/shutdown") - .respond(204); - - final Mono mono = daprPreviewClientHttp.shutdown(); - assertNull(mono.block()); - } - - private static class XmlSerializer implements DaprObjectSerializer { - - private static final XmlMapper XML_MAPPER = new XmlMapper(); - - @Override - public byte[] serialize(Object o) throws IOException { - return XML_MAPPER.writeValueAsBytes(o); - } - - @Override - public T deserialize(byte[] data, TypeRef type) throws IOException { - return XML_MAPPER.readValue(data, new TypeReference() { - }); - } - - @Override - public String getContentType() { - return "application/xml"; - } - } } From b353a1630ebf50015c17225fb5644e02889d8c26 Mon Sep 17 00:00:00 2001 From: Artur Souza Date: Wed, 12 Jan 2022 14:55:55 -0800 Subject: [PATCH 12/13] Add regex header checkstyle. Signed-off-by: Artur Souza --- .java_header | 12 ++++++++++++ checkstyle.xml | 5 ++--- 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 .java_header diff --git a/.java_header b/.java_header new file mode 100644 index 0000000000..255da1d1a5 --- /dev/null +++ b/.java_header @@ -0,0 +1,12 @@ +^/\*$ +^ \* Copyright \d\d\d\d The Dapr Authors$ +^ \* Licensed under the Apache License, Version 2.0 \(the "License"\)\;$ +^ \* you may not use this file except in compliance with the License\.$ +^ \* You may obtain a copy of the License at$ +^ \* http://www.apache.org/licenses/LICENSE-2\.0$ +^ \* Unless required by applicable law or agreed to in writing, software$ +^ \* distributed under the License is distributed on an "AS IS" BASIS,$ +^ \* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.$ +^ \* See the License for the specific language governing permissions and$ +^limitations under the License\.$ +^\*/$ \ No newline at end of file diff --git a/checkstyle.xml b/checkstyle.xml index 2b2eab09f3..6482adacaf 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -51,10 +51,9 @@ - + - - + From 4a916f7ae7406d4b487e4e278efbf7a09f27b70c Mon Sep 17 00:00:00 2001 From: Artur Souza Date: Wed, 12 Jan 2022 15:15:28 -0800 Subject: [PATCH 13/13] Fix headers and add javadocs to some. Signed-off-by: Artur Souza --- .../configuration/grpc/ConfigurationClient.java | 2 +- .../configuration/grpc/ConfigurationClientIT.java | 14 +++++++++++--- .../java/io/dapr/client/DaprPreviewClient.java | 7 ++++++- .../io/dapr/client/domain/ConfigurationItem.java | 5 ++++- .../client/domain/GetConfigurationRequest.java | 5 ++++- .../domain/SubscribeConfigurationRequest.java | 6 ++++-- .../io/dapr/client/DaprPreviewClientGrpcTest.java | 14 +++++++++++--- 7 files changed, 41 insertions(+), 12 deletions(-) diff --git a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java index e549a43a55..f586999bff 100644 --- a/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java +++ b/examples/src/main/java/io/dapr/examples/configuration/grpc/ConfigurationClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Dapr Authors + * Copyright 2022 The Dapr Authors * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java b/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java index 612dc4dc8f..7a6b39565d 100644 --- a/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java +++ b/sdk-tests/src/test/java/io/dapr/it/configuration/grpc/ConfigurationClientIT.java @@ -1,7 +1,15 @@ /* - * Copyright (c) Microsoft Corporation and Dapr Contributors. - * Licensed under the MIT License. - */ + * Copyright 2021 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ package io.dapr.it.configuration.grpc; diff --git a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java index ffe58f3cd4..5e41f5e35a 100644 --- a/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java +++ b/sdk/src/main/java/io/dapr/client/DaprPreviewClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Dapr Authors + * Copyright 2022 The Dapr Authors * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -22,6 +22,11 @@ import java.util.List; import java.util.Map; +/** + * Generic client interface for preview or alpha APIs in Dapr, regardless of GRPC or HTTP. + * + * @see io.dapr.client.DaprClientBuilder for information on how to make instance for this interface. + */ public interface DaprPreviewClient extends AutoCloseable { /** diff --git a/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java b/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java index ec61e9d174..df6ab818c4 100644 --- a/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java +++ b/sdk/src/main/java/io/dapr/client/domain/ConfigurationItem.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Dapr Authors + * Copyright 2022 The Dapr Authors * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,6 +16,9 @@ import java.util.Collections; import java.util.Map; +/** + * A configuration item from Dapr's configuration store. + */ public class ConfigurationItem { private final String key; private final String value; diff --git a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java index e72051b2eb..7e0d13c543 100644 --- a/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java +++ b/sdk/src/main/java/io/dapr/client/domain/GetConfigurationRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Dapr Authors + * Copyright 2022 The Dapr Authors * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -17,6 +17,9 @@ import java.util.List; import java.util.Map; +/** + * Request to get one or more configuration items from Dapr's configuration store. + */ public class GetConfigurationRequest { private final String storeName; private final List keys; diff --git a/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java b/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java index ac8ea2c81d..0684dce5e8 100644 --- a/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java +++ b/sdk/src/main/java/io/dapr/client/domain/SubscribeConfigurationRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Dapr Authors + * Copyright 2022 The Dapr Authors * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,11 +13,13 @@ package io.dapr.client.domain; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +/** + * Request to subscribe to one or more configuration items. + */ public class SubscribeConfigurationRequest { private final String storeName; private final List keys; diff --git a/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java b/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java index 009e5bd3b4..a5ce0a5927 100644 --- a/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprPreviewClientGrpcTest.java @@ -1,7 +1,15 @@ /* - * Copyright (c) Microsoft Corporation and Dapr Contributors. - * Licensed under the MIT License. - */ + * Copyright 2021 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ package io.dapr.client;