From 55b0e3a1e5a1b7049250868f266e02b3248ed4be Mon Sep 17 00:00:00 2001 From: Mukundan Sundararajan Date: Thu, 30 Jul 2020 10:44:25 -0700 Subject: [PATCH] Change Service Invocation API. Fix metadata bug. (#312) * Change Service Invocation API * Address review comments --- .../invoke/grpc/HelloWorldClient.java | 4 +- .../io/dapr/examples/invoke/grpc/README.md | 2 +- .../examples/invoke/http/InvokeClient.java | 6 +- .../io/dapr/examples/invoke/http/README.md | 4 +- .../io/dapr/it/binding/http/BindingIT.java | 18 +- .../it/methodinvoke/http/MethodInvokeIT.java | 33 ++-- .../java/io/dapr/it/pubsub/http/PubSubIT.java | 17 +- .../main/java/io/dapr/client/DaprClient.java | 186 ++++++++++-------- .../java/io/dapr/client/DaprClientGrpc.java | 78 ++++---- .../java/io/dapr/client/DaprClientHttp.java | 56 +++--- .../main/java/io/dapr/client/DaprHttp.java | 16 +- .../java/io/dapr/client/HttpExtension.java | 90 +++++++++ .../io/dapr/client/DaprClientGrpcTest.java | 100 +++++++--- .../io/dapr/client/DaprClientHttpTest.java | 51 +++-- .../java/io/dapr/runtime/DaprRuntimeTest.java | 6 +- 15 files changed, 429 insertions(+), 238 deletions(-) create mode 100644 sdk/src/main/java/io/dapr/client/HttpExtension.java diff --git a/examples/src/main/java/io/dapr/examples/invoke/grpc/HelloWorldClient.java b/examples/src/main/java/io/dapr/examples/invoke/grpc/HelloWorldClient.java index 4075ba064..047e34edb 100644 --- a/examples/src/main/java/io/dapr/examples/invoke/grpc/HelloWorldClient.java +++ b/examples/src/main/java/io/dapr/examples/invoke/grpc/HelloWorldClient.java @@ -7,7 +7,7 @@ package io.dapr.examples.invoke.grpc; import io.dapr.client.DaprClient; import io.dapr.client.DaprClientBuilder; -import io.dapr.client.domain.Verb; +import io.dapr.client.HttpExtension; /** * 1. Build and install jars: @@ -33,7 +33,7 @@ public class HelloWorldClient { while (true) { String message = "Message #" + (count++); System.out.println("Sending message: " + message); - client.invokeService(Verb.POST, serviceAppId, method, message).block(); + client.invokeService(serviceAppId, method, message, HttpExtension.NONE).block(); System.out.println("Message sent: " + message); Thread.sleep(1000); diff --git a/examples/src/main/java/io/dapr/examples/invoke/grpc/README.md b/examples/src/main/java/io/dapr/examples/invoke/grpc/README.md index 414638549..bbfef9f02 100644 --- a/examples/src/main/java/io/dapr/examples/invoke/grpc/README.md +++ b/examples/src/main/java/io/dapr/examples/invoke/grpc/README.md @@ -96,7 +96,7 @@ private static class HelloWorldClient { while (true) { String message = "Message #" + (count++); System.out.println("Sending message: " + message); - client.invokeService(Verb.POST, serviceAppId, method, message).block(); + client.invokeService(serviceAppId, method, message, HttpExtension.NONE).block(); System.out.println("Message sent: " + message); Thread.sleep(1000); diff --git a/examples/src/main/java/io/dapr/examples/invoke/http/InvokeClient.java b/examples/src/main/java/io/dapr/examples/invoke/http/InvokeClient.java index 9af34a185..835c45b40 100644 --- a/examples/src/main/java/io/dapr/examples/invoke/http/InvokeClient.java +++ b/examples/src/main/java/io/dapr/examples/invoke/http/InvokeClient.java @@ -7,7 +7,7 @@ package io.dapr.examples.invoke.http; import io.dapr.client.DaprClient; import io.dapr.client.DaprClientBuilder; -import io.dapr.client.domain.Verb; +import io.dapr.client.HttpExtension; /** * 1. Build and install jars: @@ -32,8 +32,8 @@ public class InvokeClient { public static void main(String[] args) { DaprClient client = (new DaprClientBuilder()).build(); for (String message : args) { - byte[] response = client.invokeService( - Verb.POST, SERVICE_APP_ID, "say", message, null, byte[].class).block(); + byte[] response = client.invokeService(SERVICE_APP_ID, "say", message, HttpExtension.POST, null, + byte[].class).block(); System.out.println(new String(response)); } diff --git a/examples/src/main/java/io/dapr/examples/invoke/http/README.md b/examples/src/main/java/io/dapr/examples/invoke/http/README.md index b967a4993..e37126c5b 100644 --- a/examples/src/main/java/io/dapr/examples/invoke/http/README.md +++ b/examples/src/main/java/io/dapr/examples/invoke/http/README.md @@ -113,8 +113,8 @@ private static final String SERVICE_APP_ID = "invokedemo"; public static void main(String[] args) { DaprClient client = (new DaprClientBuilder()).build(); for (String message : args) { - byte[] response = client.invokeService( - Verb.POST, SERVICE_APP_ID, "say", message, null, byte[].class).block(); + byte[] response = client.invokeService(SERVICE_APP_ID, "say", + message, HttpExtension.POST, null, byte[].class).block(); System.out.println(new String(response)); } } diff --git a/sdk-tests/src/test/java/io/dapr/it/binding/http/BindingIT.java b/sdk-tests/src/test/java/io/dapr/it/binding/http/BindingIT.java index 6502d0a78..432ce5d5b 100644 --- a/sdk-tests/src/test/java/io/dapr/it/binding/http/BindingIT.java +++ b/sdk-tests/src/test/java/io/dapr/it/binding/http/BindingIT.java @@ -8,22 +8,18 @@ package io.dapr.it.binding.http; import com.fasterxml.jackson.databind.ObjectMapper; import io.dapr.client.DaprClient; import io.dapr.client.DaprClientBuilder; -import io.dapr.client.domain.Verb; +import io.dapr.client.HttpExtension; import io.dapr.it.BaseIT; import io.dapr.it.DaprRun; -import io.dapr.it.services.EmptyService; -import io.dapr.serializer.DefaultObjectSerializer; -import java.util.Arrays; -import java.util.Collection; -import org.junit.Ignore; import org.junit.Test; - -import java.util.Base64; -import java.util.Collections; -import java.util.List; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + import static io.dapr.it.Retry.callWithRetry; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -100,10 +96,10 @@ public class BindingIT extends BaseIT { System.out.println("Checking results ..."); final List messages = client.invokeService( - Verb.GET, daprRun.getAppName(), "messages", null, + HttpExtension.GET, List.class).block(); assertEquals(2, messages.size()); diff --git a/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeIT.java b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeIT.java index bb760fc09..d244d9472 100644 --- a/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeIT.java +++ b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeIT.java @@ -2,20 +2,20 @@ package io.dapr.it.methodinvoke.http; import io.dapr.client.DaprClient; import io.dapr.client.DaprClientBuilder; -import io.dapr.client.domain.Verb; +import io.dapr.client.DaprHttp; +import io.dapr.client.HttpExtension; import io.dapr.it.BaseIT; import io.dapr.it.DaprRun; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.io.IOException; import java.util.*; import static org.junit.Assert.assertEquals; -import static org.junit.runners.Parameterized.*; +import static org.junit.runners.Parameterized.Parameter; +import static org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class MethodInvokeIT extends BaseIT { @@ -66,20 +66,21 @@ public class MethodInvokeIT extends BaseIT { for (int i = 0; i < NUM_MESSAGES; i++) { String message = String.format("This is message #%d", i); //Publishing messages - client.invokeService(Verb.POST, daprRun.getAppName(), "messages", message.getBytes()).block(); + client.invokeService(daprRun.getAppName(), "messages", message.getBytes(), HttpExtension.POST).block(); System.out.println("Invoke method messages : " + message); } - Map messages = client.invokeService(Verb.GET, daprRun.getAppName(), "messages", null, Map.class).block(); + Map messages = client.invokeService(daprRun.getAppName(), "messages", null, + HttpExtension.GET, Map.class).block(); assertEquals(10, messages.size()); - client.invokeService(Verb.DELETE,daprRun.getAppName(),"messages/1",null).block(); + client.invokeService(daprRun.getAppName(),"messages/1",null, HttpExtension.DELETE).block(); - messages = client.invokeService(Verb.GET, daprRun.getAppName(), "messages", null, Map.class).block(); + messages = client.invokeService(daprRun.getAppName(), "messages", null, HttpExtension.GET, Map.class).block(); assertEquals(9, messages.size()); - client.invokeService(Verb.PUT, daprRun.getAppName(), "messages/2", "updated message".getBytes()).block(); - messages = client.invokeService(Verb.GET, daprRun.getAppName(), "messages", null, Map.class).block(); + client.invokeService(daprRun.getAppName(), "messages/2", "updated message".getBytes(), HttpExtension.PUT).block(); + messages = client.invokeService(daprRun.getAppName(), "messages", null, HttpExtension.GET, Map.class).block(); assertEquals("updated message", messages.get("2")); } @@ -94,16 +95,16 @@ public class MethodInvokeIT extends BaseIT { person.setLastName(String.format("Last Name %d", i)); person.setBirthDate(new Date()); //Publishing messages - client.invokeService(Verb.POST, daprRun.getAppName(), "persons", person).block(); + client.invokeService(daprRun.getAppName(), "persons", person, HttpExtension.POST).block(); System.out.println("Invoke method persons with parameter : " + person); } - List persons = Arrays.asList(client.invokeService(Verb.GET, daprRun.getAppName(), "persons", null, Person[].class).block()); + List persons = Arrays.asList(client.invokeService(daprRun.getAppName(), "persons", null, HttpExtension.GET, Person[].class).block()); assertEquals(10, persons.size()); - client.invokeService(Verb.DELETE,daprRun.getAppName(),"persons/1",null).block(); + client.invokeService(daprRun.getAppName(),"persons/1",null, HttpExtension.DELETE).block(); - persons = Arrays.asList(client.invokeService(Verb.GET, daprRun.getAppName(), "persons", null, Person[].class).block()); + persons = Arrays.asList(client.invokeService(daprRun.getAppName(), "persons", null, HttpExtension.GET, Person[].class).block()); assertEquals(9, persons.size()); Person person= new Person(); @@ -111,9 +112,9 @@ public class MethodInvokeIT extends BaseIT { person.setLastName("Smith"); person.setBirthDate(Calendar.getInstance().getTime()); - client.invokeService(Verb.PUT, daprRun.getAppName(), "persons/2", person).block(); + client.invokeService(daprRun.getAppName(), "persons/2", person, HttpExtension.PUT).block(); - persons = Arrays.asList(client.invokeService(Verb.GET, daprRun.getAppName(), "persons", null, Person[].class).block()); + persons = Arrays.asList(client.invokeService(daprRun.getAppName(), "persons", null, HttpExtension.GET, Person[].class).block()); Person resultPerson= persons.get(1); assertEquals("John", resultPerson.getName()); assertEquals("Smith", resultPerson.getLastName()); diff --git a/sdk-tests/src/test/java/io/dapr/it/pubsub/http/PubSubIT.java b/sdk-tests/src/test/java/io/dapr/it/pubsub/http/PubSubIT.java index 7f9f28d5e..2b4f4f92e 100644 --- a/sdk-tests/src/test/java/io/dapr/it/pubsub/http/PubSubIT.java +++ b/sdk-tests/src/test/java/io/dapr/it/pubsub/http/PubSubIT.java @@ -7,18 +7,19 @@ package io.dapr.it.pubsub.http; import io.dapr.client.DaprClient; import io.dapr.client.DaprClientBuilder; -import io.dapr.client.domain.Verb; +import io.dapr.client.DaprHttp; +import io.dapr.client.HttpExtension; import io.dapr.it.BaseIT; import io.dapr.it.DaprRun; -import java.util.Arrays; -import java.util.Collection; import org.junit.Test; - -import java.util.Collections; -import java.util.List; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + import static io.dapr.it.Retry.callWithRetry; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -91,7 +92,7 @@ public class PubSubIT extends BaseIT { callWithRetry(() -> { System.out.println("Checking results for topic " + TOPIC_NAME); - final List messages = client.invokeService(Verb.GET, daprRun.getAppName(), "messages/testingtopic", null, List.class).block(); + final List messages = client.invokeService(daprRun.getAppName(), "messages/testingtopic", null, HttpExtension.GET, List.class).block(); assertEquals(11, messages.size()); for (int i = 0; i < NUM_MESSAGES; i++) { @@ -110,7 +111,7 @@ public class PubSubIT extends BaseIT { callWithRetry(() -> { System.out.println("Checking results for topic " + ANOTHER_TOPIC_NAME); - final List messages = client.invokeService(Verb.GET, daprRun.getAppName(), "messages/anothertopic", null, List.class).block(); + final List messages = client.invokeService(daprRun.getAppName(), "messages/anothertopic", null, HttpExtension.GET, List.class).block(); assertEquals(10, messages.size()); for (int i = 0; i < NUM_MESSAGES; i++) { diff --git a/sdk/src/main/java/io/dapr/client/DaprClient.java b/sdk/src/main/java/io/dapr/client/DaprClient.java index 6bd4f962d..a58c0cfec 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClient.java +++ b/sdk/src/main/java/io/dapr/client/DaprClient.java @@ -43,130 +43,144 @@ public interface DaprClient { /** * Invoke a service with all possible parameters, using serialization. * - * @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value. - * @param appId The Application ID where the service is. - * @param method The actual Method to be call in the application. - * @param request The request to be sent to invoke the service, use byte[] to skip serialization. - * @param metadata Metadata (in GRPC) or headers (in HTTP) to be send in request. - * @param type The Type needed as return for the call. - * @param The Type of the return, use byte[] to skip serialization. - * @return A Mono Plan of type type . + * @param appId The Application ID where the service is. + * @param method The actual Method to be call in the application. + * @param request The request to be sent to invoke the service, use byte[] to skip serialization. + * @param httpExtension Additional fields that are needed if the receiving app is listening on + * HTTP, {@link HttpExtension#NONE} otherwise. + * @param metadata Metadata (in GRPC) or headers (in HTTP) to be sent in request. + * @param type The Type needed as return for the call. + * @param The Type of the return, use byte[] to skip serialization. + * @return A Mono Plan of type type. */ - Mono invokeService( - Verb verb, String appId, String method, Object request, Map metadata, TypeRef type); + Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension, + Map metadata, TypeRef type); /** * Invoke a service with all possible parameters, using serialization. * - * @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value. - * @param appId The Application ID where the service is. - * @param method The actual Method to be call in the application. - * @param request The request to be sent to invoke the service, use byte[] to skip serialization. - * @param metadata Metadata (in GRPC) or headers (in HTTP) to be send in request. - * @param clazz The type needed as return for the call. - * @param The type of the return, use byte[] to skip serialization. - * @return A Mono Plan of type type . + * @param appId The Application ID where the service is. + * @param method The actual Method to be call in the application. + * @param request The request to be sent to invoke the service, use byte[] to skip serialization. + * @param httpExtension Additional fields that are needed if the receiving app is listening on + * HTTP, {@link HttpExtension#NONE} otherwise. + * @param metadata Metadata (in GRPC) or headers (in HTTP) to be sent in request. + * @param clazz The type needed as return for the call. + * @param The Type of the return, use byte[] to skip serialization. + * @return A Mono Plan of type type. */ - Mono invokeService( - Verb verb, String appId, String method, Object request, Map metadata, Class clazz); + Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension, + Map metadata, Class clazz); /** - * Invoke a service without metadata, using serialization. + * Invoke a service with all possible parameters, using serialization. * - * @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value. - * @param appId The Application ID where the service is. - * @param method The actual Method to be call in the application. - * @param request The request to be sent to invoke the service, use byte[] to skip serialization. - * @param type The type needed as return for the call. - * @param The type of the return, use byte[] to skip serialization. - * @return A Mono Plan of type type . + * @param appId The Application ID where the service is. + * @param method The actual Method to be call in the application. + * @param request The request to be sent to invoke the service, use byte[] to skip serialization. + * @param httpExtension Additional fields that are needed if the receiving app is listening on + * HTTP, {@link HttpExtension#NONE} otherwise. + * @param type The Type needed as return for the call. + * @param The Type of the return, use byte[] to skip serialization. + * @return A Mono Plan of type type. */ - Mono invokeService(Verb verb, String appId, String method, Object request, TypeRef type); + Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension, TypeRef type); /** - * Invoke a service without metadata, using serialization. + * Invoke a service with all possible parameters, using serialization. * - * @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value. - * @param appId The Application ID where the service is. - * @param method The actual Method to be call in the application. - * @param request The request to be sent to invoke the service, use byte[] to skip serialization. - * @param clazz The type needed as return for the call. - * @param The type of the return, use byte[] to skip serialization. - * @return A Mono Plan of type type . + * @param appId The Application ID where the service is. + * @param method The actual Method to be call in the application. + * @param request The request to be sent to invoke the service, use byte[] to skip serialization. + * @param httpExtension Additional fields that are needed if the receiving app is listening on + * HTTP, {@link HttpExtension#NONE} otherwise. + * @param clazz The type needed as return for the call. + * @param The Type of the return, use byte[] to skip serialization. + * @return A Mono Plan of type type. */ - Mono invokeService(Verb verb, String appId, String method, Object request, Class clazz); + Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension, Class clazz); /** - * Invoke a service without input, using serialization for response. + * Invoke a service with all possible parameters, using serialization. * - * @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value. - * @param appId The Application ID where the service is. - * @param method The actual Method to be call in the application. - * @param metadata Metadata (in GRPC) or headers (in HTTP) to be send in request. - * @param type The type needed as return for the call. - * @param The type of the return, use byte[] to skip serialization. - * @return A Mono plan of type type . + * @param appId The Application ID where the service is. + * @param method The actual Method to be call in the application. + * @param httpExtension Additional fields that are needed if the receiving app is listening on + * HTTP, {@link HttpExtension#NONE} otherwise. + * @param metadata Metadata (in GRPC) or headers (in HTTP) to be sent in request. + * @param type The Type needed as return for the call. + * @param The Type of the return, use byte[] to skip serialization. + * @return A Mono Plan of type type. */ - Mono invokeService(Verb verb, String appId, String method, Map metadata, TypeRef type); + Mono invokeService(String appId, String method, HttpExtension httpExtension, Map metadata, + TypeRef type); /** - * Invoke a service without input, using serialization for response. + * Invoke a service with all possible parameters, using serialization. * - * @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value. - * @param appId The Application ID where the service is. - * @param method The actual Method to be call in the application. - * @param metadata Metadata (in GRPC) or headers (in HTTP) to be send in request. - * @param clazz The type needed as return for the call. - * @param The type of the return, use byte[] to skip serialization. - * @return A Mono plan of type type . + * @param appId The Application ID where the service is. + * @param method The actual Method to be call in the application. + * @param httpExtension Additional fields that are needed if the receiving app is listening on + * HTTP, {@link HttpExtension#NONE} otherwise. + * @param metadata Metadata (in GRPC) or headers (in HTTP) to be sent in request. + * @param clazz The type needed as return for the call. + * @param The Type of the return, use byte[] to skip serialization. + * @return A Mono Plan of type type. */ - Mono invokeService(Verb verb, String appId, String method, Map metadata, Class clazz); + Mono invokeService(String appId, String method, HttpExtension httpExtension, Map metadata, + Class clazz); /** - * Invoke a service with void response, using serialization. + * Invoke a service with all possible parameters, using serialization. * - * @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value. - * @param appId The Application ID where the service is. - * @param method The actual Method to be call in the application. - * @param request The request to be sent to invoke the service, use byte[] to skip serialization. - * @param metadata Metadata (in GRPC) or headers (in HTTP) to be send in request. - * @return A Mono plan for Void. + * @param appId The Application ID where the service is. + * @param method The actual Method to be call in the application. + * @param request The request to be sent to invoke the service, use byte[] to skip serialization. + * @param httpExtension Additional fields that are needed if the receiving app is listening on + * HTTP, {@link HttpExtension#NONE} otherwise. + * @param metadata Metadata (in GRPC) or headers (in HTTP) to be sent in request. + * @return A Mono Plan of type type. */ - Mono invokeService(Verb verb, String appId, String method, Object request, Map metadata); + Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension, + Map metadata); /** - * Invoke a service with void response, no metadata and using serialization. + * Invoke a service with all possible parameters, using serialization. * - * @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value. - * @param appId The Application ID where the service is. - * @param method The actual Method to be call in the application. - * @param request The request to be sent to invoke the service, use byte[] to skip serialization. - * @return A Mono plan for Void. + * @param appId The Application ID where the service is. + * @param method The actual Method to be call in the application. + * @param request The request to be sent to invoke the service, use byte[] to skip serialization. + * @param httpExtension Additional fields that are needed if the receiving app is listening on + * HTTP, {@link HttpExtension#NONE} otherwise. + * @return A Mono Plan of type type. */ - Mono invokeService(Verb verb, String appId, String method, Object request); + Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension); /** - * Invoke a service without input and void response. + * Invoke a service with all possible parameters, using serialization. * - * @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value. - * @param appId The Application ID where the service is. - * @param method The actual Method to be call in the application. - * @param metadata Metadata (in GRPC) or headers (in HTTP) to be send in request. - * @return A Mono plan for Void. + * @param appId The Application ID where the service is. + * @param method The actual Method to be call in the application. + * @param httpExtension Additional fields that are needed if the receiving app is listening on + * HTTP, {@link HttpExtension#NONE} otherwise. + * @param metadata Metadata (in GRPC) or headers (in HTTP) to be sent in request. + * @return A Mono Plan of type type. */ - Mono invokeService(Verb verb, String appId, String method, Map metadata); + Mono invokeService(String appId, String method, HttpExtension httpExtension, Map metadata); /** - * Invoke a service without serialization. + * Invoke a service with all possible parameters, using serialization. * - * @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value. - * @param appId The Application ID where the service is. - * @param method The actual Method to be call in the application. - * @param request The request to be sent to invoke the service - * @param metadata Metadata (in GRPC) or headers (in HTTP) to be send in request. - * @return A Mono plan of byte[]. + * @param appId The Application ID where the service is. + * @param method The actual Method to be call in the application. + * @param request The request to be sent to invoke the service, use byte[] to skip serialization. + * @param httpExtension Additional fields that are needed if the receiving app is listening on + * HTTP, {@link HttpExtension#NONE} otherwise. + * @param metadata Metadata (in GRPC) or headers (in HTTP) to be sent in request. + * @return A Mono Plan of type type. */ - Mono invokeService(Verb verb, String appId, String method, byte[] request, Map metadata); + Mono invokeService(String appId, String method, byte[] request, HttpExtension httpExtension, + Map metadata); /** * Invokes a Binding operation. diff --git a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java index af2fc68f5..e3694b7f2 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientGrpc.java @@ -12,7 +12,6 @@ import com.google.protobuf.Duration; import com.google.protobuf.Empty; import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; -import io.dapr.client.domain.Verb; import io.dapr.serializer.DaprObjectSerializer; import io.dapr.utils.TypeRef; import io.dapr.v1.CommonProtos; @@ -130,19 +129,11 @@ public class DaprClientGrpc implements DaprClient { } } - /** - * {@inheritDoc} - */ @Override - public Mono invokeService( - Verb verb, - String appId, - String method, - Object request, - Map metadata, - TypeRef type) { + public Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension, + Map metadata, TypeRef type) { try { - DaprProtos.InvokeServiceRequest envelope = buildInvokeServiceRequest(verb.toString(), appId, method, request); + DaprProtos.InvokeServiceRequest envelope = buildInvokeServiceRequest(httpExtension, appId, method, request); return Mono.fromCallable(() -> { ListenableFuture futureResponse = client.invokeService(envelope); @@ -159,13 +150,13 @@ public class DaprClientGrpc implements DaprClient { */ @Override public Mono invokeService( - Verb verb, String appId, String method, Object request, + HttpExtension httpExtension, Map metadata, Class clazz) { - return this.invokeService(verb, appId, method, request, metadata, TypeRef.get(clazz)); + return this.invokeService(appId, method, request, httpExtension, metadata, TypeRef.get(clazz)); } /** @@ -173,8 +164,8 @@ public class DaprClientGrpc implements DaprClient { */ @Override public Mono invokeService( - Verb verb, String appId, String method, Map metadata, TypeRef type) { - return this.invokeService(verb, appId, method, null, metadata, type); + String appId, String method, HttpExtension httpExtension, Map metadata, TypeRef type) { + return this.invokeService(appId, method, null, httpExtension, metadata, type); } /** @@ -182,32 +173,34 @@ public class DaprClientGrpc implements DaprClient { */ @Override public Mono invokeService( - Verb verb, String appId, String method, Map metadata, Class clazz) { - return this.invokeService(verb, appId, method, null, metadata, TypeRef.get(clazz)); + String appId, String method, HttpExtension httpExtension, Map metadata, Class clazz) { + return this.invokeService(appId, method, null, httpExtension, metadata, TypeRef.get(clazz)); } /** * {@inheritDoc} */ @Override - public Mono invokeService(Verb verb, String appId, String method, Object request, TypeRef type) { - return this.invokeService(verb, appId, method, request, null, type); + public Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension, + TypeRef type) { + return this.invokeService(appId, method, request, httpExtension, null, type); } /** * {@inheritDoc} */ @Override - public Mono invokeService(Verb verb, String appId, String method, Object request, Class clazz) { - return this.invokeService(verb, appId, method, request, null, TypeRef.get(clazz)); + public Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension, + Class clazz) { + return this.invokeService(appId, method, request, httpExtension, null, TypeRef.get(clazz)); } /** * {@inheritDoc} */ @Override - public Mono invokeService(Verb verb, String appId, String method, Object request) { - return this.invokeService(verb, appId, method, request, null, TypeRef.BYTE_ARRAY).then(); + public Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension) { + return this.invokeService(appId, method, request, httpExtension, null, TypeRef.BYTE_ARRAY).then(); } /** @@ -215,8 +208,8 @@ public class DaprClientGrpc implements DaprClient { */ @Override public Mono invokeService( - Verb verb, String appId, String method, Object request, Map metadata) { - return this.invokeService(verb, appId, method, request, metadata, TypeRef.BYTE_ARRAY).then(); + String appId, String method, Object request, HttpExtension httpExtension, Map metadata) { + return this.invokeService(appId, method, request, httpExtension, metadata, TypeRef.BYTE_ARRAY).then(); } /** @@ -224,8 +217,8 @@ public class DaprClientGrpc implements DaprClient { */ @Override public Mono invokeService( - Verb verb, String appId, String method, Map metadata) { - return this.invokeService(verb, appId, method, null, metadata, TypeRef.BYTE_ARRAY).then(); + String appId, String method, HttpExtension httpExtension, Map metadata) { + return this.invokeService(appId, method, null, httpExtension, metadata, TypeRef.BYTE_ARRAY).then(); } /** @@ -233,8 +226,8 @@ public class DaprClientGrpc implements DaprClient { */ @Override public Mono invokeService( - Verb verb, String appId, String method, byte[] request, Map metadata) { - return this.invokeService(verb, appId, method, request, metadata, TypeRef.BYTE_ARRAY); + String appId, String method, byte[] request, HttpExtension httpExtension, Map metadata) { + return this.invokeService(appId, method, request, httpExtension, metadata, TypeRef.BYTE_ARRAY); } /** @@ -578,16 +571,19 @@ public class DaprClientGrpc implements DaprClient { /** * Builds the object io.dapr.{@link DaprProtos.InvokeServiceRequest} to be send based on the parameters. * - * @param verb String that must match HTTP Methods - * @param appId The application id to be invoked - * @param method The application method to be invoked - * @param request The body of the request to be send as part of the invokation - * @param The Type of the Body - * @return The object to be sent as part of the invokation. + * @param httpExtension Object for HttpExtension + * @param appId The application id to be invoked + * @param method The application method to be invoked + * @param request The body of the request to be send as part of the invocation + * @param The Type of the Body + * @return The object to be sent as part of the invocation. * @throws IOException If there's an issue serializing the request. */ private DaprProtos.InvokeServiceRequest buildInvokeServiceRequest( - String verb, String appId, String method, K request) throws IOException { + HttpExtension httpExtension, String appId, String method, K request) throws IOException { + if (httpExtension == null) { + throw new IllegalArgumentException("HttpExtension cannot be null. Use HttpExtension.NONE instead."); + } CommonProtos.InvokeRequest.Builder requestBuilder = CommonProtos.InvokeRequest.newBuilder(); requestBuilder.setMethod(method); if (request != null) { @@ -597,13 +593,9 @@ public class DaprClientGrpc implements DaprClient { } else { requestBuilder.setData(Any.newBuilder().build()); } - CommonProtos.HTTPExtension.Builder httpExtensionBuilder = CommonProtos.HTTPExtension.newBuilder(); - if ((verb != null) && !verb.isEmpty()) { - httpExtensionBuilder.setVerb(CommonProtos.HTTPExtension.Verb.valueOf(verb.toUpperCase())); - } else { - httpExtensionBuilder.setVerb(CommonProtos.HTTPExtension.Verb.NONE); - } + httpExtensionBuilder.setVerb(CommonProtos.HTTPExtension.Verb.valueOf(httpExtension.getMethod().toString())) + .putAllQuerystring(httpExtension.getQueryString()); requestBuilder.setHttpExtension(httpExtensionBuilder.build()); DaprProtos.InvokeServiceRequest.Builder envelopeBuilder = DaprProtos.InvokeServiceRequest.newBuilder() diff --git a/sdk/src/main/java/io/dapr/client/DaprClientHttp.java b/sdk/src/main/java/io/dapr/client/DaprClientHttp.java index 31d8e4b06..24c2502e3 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientHttp.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientHttp.java @@ -122,14 +122,19 @@ public class DaprClientHttp implements DaprClient { /** * {@inheritDoc} */ - @Override public Mono invokeService( - Verb verb, String appId, String method, Object request, Map metadata, TypeRef type) { + String appId, + String method, + Object request, + HttpExtension httpExtension, + Map metadata, + TypeRef type) { try { - if (verb == null) { - throw new IllegalArgumentException("Verb cannot be null."); + if (httpExtension == null) { + throw new IllegalArgumentException("HttpExtension cannot be null. Use HttpExtension.NONE instead."); } - String httMethod = verb.toString(); + // If the httpExtension is not null, then the method will not be null based on checks in constructor + String httMethod = httpExtension.getMethod().toString(); if (appId == null || appId.trim().isEmpty()) { throw new IllegalArgumentException("App Id cannot be null or empty."); } @@ -138,7 +143,8 @@ public class DaprClientHttp implements DaprClient { } String path = String.format("%s/%s/method/%s", Constants.INVOKE_PATH, appId, method); byte[] serializedRequestBody = objectSerializer.serialize(request); - Mono response = this.client.invokeApi(httMethod, path, metadata, serializedRequestBody, null); + Mono response = this.client.invokeApi(httMethod, path, + httpExtension.getQueryString(), serializedRequestBody, metadata); return response.flatMap(r -> { try { T object = objectSerializer.deserialize(r.getBody(), type); @@ -161,13 +167,13 @@ public class DaprClientHttp implements DaprClient { */ @Override public Mono invokeService( - Verb verb, String appId, String method, Object request, + HttpExtension httpExtension, Map metadata, Class clazz) { - return this.invokeService(verb, appId, method, request, metadata, TypeRef.get(clazz)); + return this.invokeService(appId, method, request, httpExtension, metadata, TypeRef.get(clazz)); } /** @@ -175,8 +181,8 @@ public class DaprClientHttp implements DaprClient { */ @Override public Mono invokeService( - Verb verb, String appId, String method, Map metadata, TypeRef type) { - return this.invokeService(verb, appId, method, null, metadata, type); + String appId, String method, HttpExtension httpExtension, Map metadata, TypeRef type) { + return this.invokeService(appId, method, null, httpExtension, metadata, type); } /** @@ -184,32 +190,34 @@ public class DaprClientHttp implements DaprClient { */ @Override public Mono invokeService( - Verb verb, String appId, String method, Map metadata, Class clazz) { - return this.invokeService(verb, appId, method, null, metadata, TypeRef.get(clazz)); + String appId, String method, HttpExtension httpExtension, Map metadata, Class clazz) { + return this.invokeService(appId, method, null, httpExtension, metadata, TypeRef.get(clazz)); } /** * {@inheritDoc} */ @Override - public Mono invokeService(Verb verb, String appId, String method, Object request, TypeRef type) { - return this.invokeService(verb, appId, method, request, null, type); + public Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension, + TypeRef type) { + return this.invokeService(appId, method, request, httpExtension, null, type); } /** * {@inheritDoc} */ @Override - public Mono invokeService(Verb verb, String appId, String method, Object request, Class clazz) { - return this.invokeService(verb, appId, method, request, null, TypeRef.get(clazz)); + public Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension, + Class clazz) { + return this.invokeService(appId, method, request, httpExtension,null, TypeRef.get(clazz)); } /** * {@inheritDoc} */ @Override - public Mono invokeService(Verb verb, String appId, String method, Object request) { - return this.invokeService(verb, appId, method, request, null, TypeRef.BYTE_ARRAY).then(); + public Mono invokeService(String appId, String method, Object request, HttpExtension httpExtension) { + return this.invokeService(appId, method, request, httpExtension, null, TypeRef.BYTE_ARRAY).then(); } /** @@ -217,8 +225,8 @@ public class DaprClientHttp implements DaprClient { */ @Override public Mono invokeService( - Verb verb, String appId, String method, Object request, Map metadata) { - return this.invokeService(verb, appId, method, request, metadata, TypeRef.BYTE_ARRAY).then(); + String appId, String method, Object request, HttpExtension httpExtension, Map metadata) { + return this.invokeService(appId, method, request, httpExtension, metadata, TypeRef.BYTE_ARRAY).then(); } /** @@ -226,8 +234,8 @@ public class DaprClientHttp implements DaprClient { */ @Override public Mono invokeService( - Verb verb, String appId, String method, Map metadata) { - return this.invokeService(verb, appId, method, null, metadata, TypeRef.BYTE_ARRAY).then(); + String appId, String method, HttpExtension httpExtension, Map metadata) { + return this.invokeService(appId, method, null, httpExtension, metadata, TypeRef.BYTE_ARRAY).then(); } /** @@ -235,8 +243,8 @@ public class DaprClientHttp implements DaprClient { */ @Override public Mono invokeService( - Verb verb, String appId, String method, byte[] request, Map metadata) { - return this.invokeService(verb, appId, method, request, metadata, TypeRef.BYTE_ARRAY); + String appId, String method, byte[] request, HttpExtension httpExtension, Map metadata) { + return this.invokeService(appId, method, request, httpExtension, metadata, TypeRef.BYTE_ARRAY); } /** diff --git a/sdk/src/main/java/io/dapr/client/DaprHttp.java b/sdk/src/main/java/io/dapr/client/DaprHttp.java index 29ee3485b..de46f04e5 100644 --- a/sdk/src/main/java/io/dapr/client/DaprHttp.java +++ b/sdk/src/main/java/io/dapr/client/DaprHttp.java @@ -26,15 +26,24 @@ import java.util.Optional; import java.util.UUID; public class DaprHttp { + /** + * Dapr's http default scheme. + */ + private static final String DEFAULT_HTTP_SCHEME = "http"; /** * HTTP Methods supported. */ public enum HttpMethods { + NONE, GET, PUT, POST, - DELETE + DELETE, + HEAD, + CONNECT, + OPTIONS, + TRACE } public static class Response { @@ -171,7 +180,10 @@ public class DaprHttp { body = RequestBody.Companion.create(content, mediaType); } HttpUrl.Builder urlBuilder = new HttpUrl.Builder(); - urlBuilder.scheme("http").host(Constants.DEFAULT_HOSTNAME).port(this.port).addPathSegments(urlString); + urlBuilder.scheme(DEFAULT_HTTP_SCHEME) + .host(Constants.DEFAULT_HOSTNAME) + .port(this.port) + .addPathSegments(urlString); Optional.ofNullable(urlParameters).orElse(Collections.emptyMap()).entrySet().stream() .forEach(urlParameter -> urlBuilder.addQueryParameter(urlParameter.getKey(), urlParameter.getValue())); diff --git a/sdk/src/main/java/io/dapr/client/HttpExtension.java b/sdk/src/main/java/io/dapr/client/HttpExtension.java new file mode 100644 index 000000000..c7fab55c8 --- /dev/null +++ b/sdk/src/main/java/io/dapr/client/HttpExtension.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + */ + +package io.dapr.client; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * HTTP Extension class. + * This class is only needed if the app you are calling is listening on HTTP. + * It contains properties that represent data that may be populated for an HTTP receiver. + */ + +public final class HttpExtension { + /** + * Convenience HttpExtension object for {@link DaprHttp.HttpMethods#NONE} with empty queryString. + */ + public static final HttpExtension NONE = new HttpExtension(DaprHttp.HttpMethods.NONE, new HashMap<>()); + /** + * Convenience HttpExtension object for the {@link DaprHttp.HttpMethods#GET} Verb with empty queryString. + */ + public static final HttpExtension GET = new HttpExtension(DaprHttp.HttpMethods.GET, new HashMap<>()); + /** + * Convenience HttpExtension object for the {@link DaprHttp.HttpMethods#PUT} Verb with empty queryString. + */ + public static final HttpExtension PUT = new HttpExtension(DaprHttp.HttpMethods.PUT, new HashMap<>()); + /** + * Convenience HttpExtension object for the {@link DaprHttp.HttpMethods#POST} Verb with empty queryString. + */ + public static final HttpExtension POST = new HttpExtension(DaprHttp.HttpMethods.POST, new HashMap<>()); + /** + * Convenience HttpExtension object for the {@link DaprHttp.HttpMethods#DELETE} Verb with empty queryString. + */ + public static final HttpExtension DELETE = new HttpExtension(DaprHttp.HttpMethods.DELETE, new HashMap<>()); + /** + * Convenience HttpExtension object for the {@link DaprHttp.HttpMethods#HEAD} Verb with empty queryString. + */ + public static final HttpExtension HEAD = new HttpExtension(DaprHttp.HttpMethods.HEAD, new HashMap<>()); + /** + * Convenience HttpExtension object for the {@link DaprHttp.HttpMethods#CONNECT} Verb with empty queryString. + */ + public static final HttpExtension CONNECT = new HttpExtension(DaprHttp.HttpMethods.CONNECT, new HashMap<>()); + /** + * Convenience HttpExtension object for the {@link DaprHttp.HttpMethods#OPTIONS} Verb with empty queryString. + */ + public static final HttpExtension OPTIONS = new HttpExtension(DaprHttp.HttpMethods.OPTIONS, new HashMap<>()); + /** + * Convenience HttpExtension object for the {@link DaprHttp.HttpMethods#TRACE} Verb with empty queryString. + */ + public static final HttpExtension TRACE = new HttpExtension(DaprHttp.HttpMethods.TRACE, new HashMap<>()); + + /** + * HTTP verb. + */ + private DaprHttp.HttpMethods method; + + /** + * HTTP querystring. + */ + private Map queryString; + + /** + * Construct a HttpExtension object. + * @param method Required value denoting the HttpMethod. + * @param queryString Non-null map value for the queryString for a HTTP listener. + * @see io.dapr.client.DaprHttp.HttpMethods for supported methods. + * @throws IllegalArgumentException on null method or queryString. + */ + public HttpExtension(DaprHttp.HttpMethods method, Map queryString) { + if (method == null) { + throw new IllegalArgumentException("HttpExtension method cannot be null"); + } else if (queryString == null) { + throw new IllegalArgumentException("HttpExtension queryString map cannot be null"); + } + this.method = method; + this.queryString = Collections.unmodifiableMap(queryString); + } + + public DaprHttp.HttpMethods getMethod() { + return method; + } + + public Map getQueryString() { + return queryString; + } +} diff --git a/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java b/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java index fe30496c2..4e383d0dc 100644 --- a/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java @@ -14,12 +14,11 @@ import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; import io.dapr.client.domain.Verb; import io.dapr.serializer.DefaultObjectSerializer; +import io.dapr.utils.TypeRef; import io.dapr.v1.CommonProtos; import io.dapr.v1.DaprGrpc; import io.dapr.v1.DaprProtos; -import java.util.Collections; import org.checkerframework.checker.nullness.compatqual.NullableDecl; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentMatcher; @@ -27,6 +26,7 @@ import reactor.core.publisher.Mono; import java.io.IOException; import java.time.Duration; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -206,7 +206,15 @@ public class DaprClientGrpcTest { public void invokeServiceVoidExceptionThrownTest() { when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenThrow(RuntimeException.class); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", "request"); + Mono result = adapter.invokeService("appId", "method", "request", HttpExtension.NONE); + result.block(); + } + + @Test(expected = RuntimeException.class) + public void invokeServiceEmptyRequestVoidExceptionThrownTest() { + when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) + .thenThrow(RuntimeException.class); + Mono result = adapter.invokeService("appId", "method", HttpExtension.NONE, (Map)null); result.block(); } @@ -220,7 +228,7 @@ public class DaprClientGrpcTest { settableFuture.setException(ex); when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenReturn(settableFuture); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", "request"); + Mono result = adapter.invokeService("appId", "method", "request", HttpExtension.NONE); result.block(); } @@ -234,7 +242,7 @@ public class DaprClientGrpcTest { addCallback(settableFuture, callback, directExecutor()); when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenReturn(settableFuture); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", "request"); + Mono result = adapter.invokeService("appId", "method", "request", HttpExtension.NONE); settableFuture.set(CommonProtos.InvokeResponse.newBuilder().setData(getAny("Value")).build()); result.block(); assertTrue(callback.wasCalled); @@ -251,7 +259,7 @@ public class DaprClientGrpcTest { when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenReturn(settableFuture); MyObject request = new MyObject(1, "Event"); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", request); + Mono result = adapter.invokeService("appId", "method", request, HttpExtension.NONE); settableFuture.set(CommonProtos.InvokeResponse.newBuilder().setData(getAny("Value")).build()); result.block(); assertTrue(callback.wasCalled); @@ -261,7 +269,23 @@ public class DaprClientGrpcTest { public void invokeServiceExceptionThrownTest() { when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenThrow(RuntimeException.class); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", "request", null, String.class); + Mono result = adapter.invokeService("appId", "method", "request", HttpExtension.NONE, null, String.class); + result.block(); + } + + @Test(expected = RuntimeException.class) + public void invokeServiceNoRequestClassExceptionThrownTest() { + when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) + .thenThrow(RuntimeException.class); + Mono result = adapter.invokeService("appId", "method", HttpExtension.NONE, (Map)null, String.class); + result.block(); + } + + @Test(expected = RuntimeException.class) + public void invokeServiceNoRequestTypeRefExceptionThrownTest() { + when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) + .thenThrow(RuntimeException.class); + Mono result = adapter.invokeService("appId", "method", HttpExtension.NONE, (Map)null, TypeRef.STRING); result.block(); } @@ -274,11 +298,41 @@ public class DaprClientGrpcTest { addCallback(settableFuture, callback, directExecutor()); when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenReturn(settableFuture); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", "request", null, String.class); + Mono result = adapter.invokeService("appId", "method", "request", HttpExtension.NONE, null, String.class); settableFuture.setException(ex); result.block(); } + @Test + public void invokeServiceWithHttpExtensionTest() throws IOException { + HttpExtension httpExtension = new HttpExtension(DaprHttp.HttpMethods.GET, new HashMap() {{ + put("test", "1"); + }}); + CommonProtos.InvokeRequest message = CommonProtos.InvokeRequest.newBuilder() + .setMethod("method") + .setData(getAny("request")) + .setHttpExtension(CommonProtos.HTTPExtension.newBuilder() + .setVerb(CommonProtos.HTTPExtension.Verb.GET) + .putQuerystring("test", "1").build()) + .build(); + DaprProtos.InvokeServiceRequest request = DaprProtos.InvokeServiceRequest.newBuilder() + .setId("appId") + .setMessage(message) + .build(); + String expected = "Value"; + SettableFuture settableFuture = SettableFuture.create(); + MockCallback callback = + new MockCallback(CommonProtos.InvokeResponse.newBuilder() + .setData(getAny(expected)).build()); + addCallback(settableFuture, callback, directExecutor()); + settableFuture.set(CommonProtos.InvokeResponse.newBuilder().setData(getAny(expected)).build()); + when(client.invokeService(eq(request))) + .thenReturn(settableFuture); + Mono result = adapter.invokeService("appId", "method", "request", httpExtension, null, String.class); + String strOutput = result.block(); + assertEquals(expected, strOutput); + } + @Test public void invokeServiceTest() throws Exception { String expected = "Value"; @@ -290,7 +344,7 @@ public class DaprClientGrpcTest { settableFuture.set(CommonProtos.InvokeResponse.newBuilder().setData(getAny(expected)).build()); when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenReturn(settableFuture); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", "request", null, String.class); + Mono result = adapter.invokeService("appId", "method", "request", HttpExtension.NONE, null, String.class); String strOutput = result.block(); assertEquals(expected, strOutput); } @@ -306,7 +360,7 @@ public class DaprClientGrpcTest { settableFuture.set(CommonProtos.InvokeResponse.newBuilder().setData(getAny(object)).build()); when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenReturn(settableFuture); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", "request", null, MyObject.class); + Mono result = adapter.invokeService("appId", "method", "request", HttpExtension.NONE, null, MyObject.class); MyObject resultObject = result.block(); assertEquals(object.id, resultObject.id); assertEquals(object.value, resultObject.value); @@ -316,7 +370,7 @@ public class DaprClientGrpcTest { public void invokeServiceNoRequestBodyExceptionThrownTest() { when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenThrow(RuntimeException.class); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", null, String.class); + Mono result = adapter.invokeService("appId", "method", (Object)null, HttpExtension.NONE, (Class)String.class); result.block(); } @@ -329,7 +383,7 @@ public class DaprClientGrpcTest { addCallback(settableFuture, callback, directExecutor()); when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenReturn(settableFuture); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", null, String.class); + Mono result = adapter.invokeService("appId", "method", (Object)null, HttpExtension.NONE, String.class); settableFuture.setException(ex); result.block(); } @@ -346,7 +400,7 @@ public class DaprClientGrpcTest { settableFuture.set(CommonProtos.InvokeResponse.newBuilder().setData(getAny(expected)).build()); when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenReturn(settableFuture); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", null, String.class); + Mono result = adapter.invokeService("appId", "method", (Object)null, HttpExtension.NONE, String.class); String strOutput = result.block(); assertEquals(expected, strOutput); } @@ -363,7 +417,7 @@ public class DaprClientGrpcTest { settableFuture.set(CommonProtos.InvokeResponse.newBuilder().setData(getAny(object)).build()); when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenReturn(settableFuture); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", null, MyObject.class); + Mono result = adapter.invokeService("appId", "method", (Object)null, HttpExtension.NONE, MyObject.class); MyObject resultObject = result.block(); assertEquals(object.id, resultObject.id); assertEquals(object.value, resultObject.value); @@ -375,7 +429,7 @@ public class DaprClientGrpcTest { .thenThrow(RuntimeException.class); String request = "Request"; byte[] byteRequest = serializer.serialize(request); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", byteRequest, byte[].class); + Mono result = adapter.invokeService("appId", "method", byteRequest, HttpExtension.NONE, byte[].class); result.block(); } @@ -391,7 +445,7 @@ public class DaprClientGrpcTest { String request = "Request"; byte[] byteRequest = serializer.serialize(request); Mono result = - adapter.invokeService(Verb.GET, "appId", "method", byteRequest, (HashMap) null); + adapter.invokeService("appId", "method", byteRequest, HttpExtension.NONE,(HashMap) null); settableFuture.setException(ex); result.block(); } @@ -410,7 +464,7 @@ public class DaprClientGrpcTest { String request = "Request"; byte[] byteRequest = serializer.serialize(request); Mono result = adapter.invokeService( - Verb.GET, "appId", "method", byteRequest, (HashMap) null); + "appId", "method", byteRequest, HttpExtension.NONE, (HashMap) null); byte[] byteOutput = result.block(); String strOutput = serializer.deserialize(byteOutput, String.class); assertEquals(expected, strOutput); @@ -429,7 +483,7 @@ public class DaprClientGrpcTest { .thenReturn(settableFuture); String request = "Request"; byte[] byteRequest = serializer.serialize(request); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", byteRequest, byte[].class); + Mono result = adapter.invokeService("appId", "method", byteRequest, HttpExtension.NONE, byte[].class); byte[] byteOutput = result.block(); assertEquals(resultObj, serializer.deserialize(byteOutput, MyObject.class)); } @@ -438,7 +492,7 @@ public class DaprClientGrpcTest { public void invokeServiceNoRequestNoClassBodyExceptionThrownTest() { when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenThrow(RuntimeException.class); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", null); + Mono result = adapter.invokeService("appId", "method", (Object)null, HttpExtension.NONE); result.block(); } @@ -451,7 +505,7 @@ public class DaprClientGrpcTest { addCallback(settableFuture, callback, directExecutor()); when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenReturn(settableFuture); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", null); + Mono result = adapter.invokeService("appId", "method", (Object)null, HttpExtension.NONE); settableFuture.setException(ex); result.block(); } @@ -466,7 +520,7 @@ public class DaprClientGrpcTest { addCallback(settableFuture, callback, directExecutor()); when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenReturn(settableFuture); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", null); + Mono result = adapter.invokeService("appId", "method", (Object)null, HttpExtension.NONE); settableFuture.set(CommonProtos.InvokeResponse.newBuilder().setData(getAny(expected)).build()); result.block(); assertTrue(callback.wasCalled); @@ -485,7 +539,7 @@ public class DaprClientGrpcTest { settableFuture.set(CommonProtos.InvokeResponse.newBuilder().setData(getAny(expected)).build()); return settableFuture; }); - adapter.invokeService(Verb.GET, "appId", "method", null); + adapter.invokeService("appId", "method", (Object)null, HttpExtension.NONE); // Do not call block() on mono above, so nothing should happen. assertFalse(callback.wasCalled); } @@ -502,7 +556,7 @@ public class DaprClientGrpcTest { settableFuture.set(CommonProtos.InvokeResponse.newBuilder().setData(getAny(resultObj)).build()); when(client.invokeService(any(DaprProtos.InvokeServiceRequest.class))) .thenReturn(settableFuture); - Mono result = adapter.invokeService(Verb.GET, "appId", "method", null); + Mono result = adapter.invokeService("appId", "method", (Object)null, HttpExtension.NONE); result.block(); assertTrue(callback.wasCalled); } diff --git a/sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java b/sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java index 14e093bee..04d8c483f 100644 --- a/sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprClientHttpTest.java @@ -6,7 +6,6 @@ package io.dapr.client; import io.dapr.client.domain.State; import io.dapr.client.domain.StateOptions; -import io.dapr.client.domain.Verb; import okhttp3.OkHttpClient; import okhttp3.mock.Behavior; import okhttp3.mock.MockInterceptor; @@ -112,19 +111,28 @@ public class DaprClientHttpTest { daprHttp = new DaprHttp(3000, okHttpClient); daprClientHttp = new DaprClientHttp(daprHttp); assertThrows(IllegalArgumentException.class, () -> { - daprClientHttp.invokeService(null, "", "", null, null, (Class)null).block(); + // null HttpMethod + daprClientHttp.invokeService("1", "2", "3", new HttpExtension(null, null), null, (Class)null).block(); }); assertThrows(IllegalArgumentException.class, () -> { - daprClientHttp.invokeService(Verb.POST, null, "", null, null, (Class)null).block(); + // null HttpExtension + daprClientHttp.invokeService("1", "2", "3", null, null, (Class)null).block(); }); assertThrows(IllegalArgumentException.class, () -> { - daprClientHttp.invokeService(Verb.POST, "", "", null, null, (Class)null).block(); + // empty appId + daprClientHttp.invokeService("", "1", null, HttpExtension.GET, null, (Class)null).block(); }); assertThrows(IllegalArgumentException.class, () -> { - daprClientHttp.invokeService(Verb.POST, "1", null, null, null, (Class)null).block(); + // null appId, empty method + daprClientHttp.invokeService(null, "", null, HttpExtension.POST, null, (Class)null).block(); }); assertThrows(IllegalArgumentException.class, () -> { - daprClientHttp.invokeService(Verb.POST, "1", "", null, null, (Class)null).block(); + // empty method + daprClientHttp.invokeService("1", "", null, HttpExtension.PUT, null, (Class)null).block(); + }); + assertThrows(IllegalArgumentException.class, () -> { + // null method + daprClientHttp.invokeService("1", null, null, HttpExtension.DELETE, null, (Class)null).block(); }); } @@ -137,7 +145,7 @@ public class DaprClientHttpTest { String event = "{ \"message\": \"This is a test\" }"; daprHttp = new DaprHttp(3000, okHttpClient); daprClientHttp = new DaprClientHttp(daprHttp); - Mono mono = daprClientHttp.invokeService(Verb.POST, "1", "", null, null, (Class)null); + Mono mono = daprClientHttp.invokeService("1", "", null, HttpExtension.POST, null, (Class)null); assertNull(mono.block()); } @@ -148,7 +156,7 @@ public class DaprClientHttpTest { .respond("\"hello world\""); daprHttp = new DaprHttp(3000, okHttpClient); daprClientHttp = new DaprClientHttp(daprHttp); - Mono mono = daprClientHttp.invokeService(Verb.GET, "41", "neworder", null, null, String.class); + Mono mono = daprClientHttp.invokeService("41", "neworder", null, HttpExtension.GET, null, String.class); assertEquals("hello world", mono.block()); } @@ -160,19 +168,19 @@ public class DaprClientHttpTest { .respond(EXPECTED_RESULT); daprHttp = new DaprHttp(3000, okHttpClient); daprClientHttp = new DaprClientHttp(daprHttp); - Mono mono = daprClientHttp.invokeService(Verb.GET, "41", "neworder", null, byte[].class); + Mono mono = daprClientHttp.invokeService("41", "neworder", null, HttpExtension.GET, byte[].class); assertEquals(new String(mono.block()), EXPECTED_RESULT); } @Test - public void invokeServiceWithMaps() { + public void invokeServiceWithMetadataMap() { Map map = new HashMap<>(); mockInterceptor.addRule() .get("http://127.0.0.1:3000/v1.0/invoke/41/method/neworder") .respond(EXPECTED_RESULT); daprHttp = new DaprHttp(3000, okHttpClient); daprClientHttp = new DaprClientHttp(daprHttp); - Mono mono = daprClientHttp.invokeService(Verb.GET, "41", "neworder", (byte[]) null, map); + Mono mono = daprClientHttp.invokeService("41", "neworder", (byte[]) null, HttpExtension.GET, map); String monoString = new String(mono.block()); assertEquals(monoString, EXPECTED_RESULT); } @@ -185,7 +193,7 @@ public class DaprClientHttpTest { .respond(EXPECTED_RESULT); daprHttp = new DaprHttp(3000, okHttpClient); daprClientHttp = new DaprClientHttp(daprHttp); - Mono mono = daprClientHttp.invokeService(Verb.GET, "41", "neworder", map); + Mono mono = daprClientHttp.invokeService("41", "neworder", HttpExtension.GET, map); assertNull(mono.block()); } @@ -197,7 +205,22 @@ public class DaprClientHttpTest { .respond(EXPECTED_RESULT); daprHttp = new DaprHttp(3000, okHttpClient); daprClientHttp = new DaprClientHttp(daprHttp); - Mono mono = daprClientHttp.invokeService(Verb.GET, "41", "neworder", "", map); + Mono mono = daprClientHttp.invokeService("41", "neworder", "", HttpExtension.GET, map); + assertNull(mono.block()); + } + + @Test + public void invokeServiceWithRequestAndQueryString() { + Map map = new HashMap<>(); + mockInterceptor.addRule() + .get("http://127.0.0.1:3000/v1.0/invoke/41/method/neworder?test=1") + .respond(EXPECTED_RESULT); + daprHttp = new DaprHttp(3000, okHttpClient); + daprClientHttp = new DaprClientHttp(daprHttp); + Map queryString = new HashMap<>(); + queryString.put("test", "1"); + HttpExtension httpExtension = new HttpExtension(DaprHttp.HttpMethods.GET, queryString); + Mono mono = daprClientHttp.invokeService("41", "neworder", "", httpExtension, map); assertNull(mono.block()); } @@ -209,7 +232,7 @@ public class DaprClientHttpTest { .respond(500); daprHttp = new DaprHttp(3000, okHttpClient); daprClientHttp = new DaprClientHttp(daprHttp); - daprClientHttp.invokeService(Verb.GET, "41", "neworder", "", map); + daprClientHttp.invokeService("41", "neworder", "", HttpExtension.GET, map); // No exception should be thrown because did not call block() on mono above. } diff --git a/sdk/src/test/java/io/dapr/runtime/DaprRuntimeTest.java b/sdk/src/test/java/io/dapr/runtime/DaprRuntimeTest.java index 311130c13..8c714f14e 100644 --- a/sdk/src/test/java/io/dapr/runtime/DaprRuntimeTest.java +++ b/sdk/src/test/java/io/dapr/runtime/DaprRuntimeTest.java @@ -202,15 +202,15 @@ public class DaprRuntimeTest { eq(Constants.INVOKE_PATH + "/" + APP_ID + "/method/" + METHOD_NAME), any(), eq(serializer.serialize(message.data)), - eq(null))) + any())) .thenAnswer(x -> this.daprRuntime.handleInvocation( METHOD_NAME, serializer.serialize(message.data), message.metadata) .map(r -> new DaprHttpStub.ResponseStub(r, null, 200))); - - Mono response = client.invokeService(Verb.POST, APP_ID, METHOD_NAME, message.data, message.metadata, byte[].class); + Mono response = client.invokeService(APP_ID, METHOD_NAME, message.data, HttpExtension.POST, + message.metadata, byte[].class); Assert.assertArrayEquals(expectedResponse, response.block()); verify(listener, times(1))