mirror of https://github.com/dapr/java-sdk.git
Remove HTTP client and add gRPC interceptor helper. (#1051)
* Remove HTTP client and add gRPC interceptor helper. Signed-off-by: Artur Souza <asouza.pro@gmail.com> * New design for gRPC interceptor and channel proxy. Signed-off-by: Artur Souza <asouza.pro@gmail.com> --------- Signed-off-by: Artur Souza <asouza.pro@gmail.com> Signed-off-by: Artur Souza <artursouza.ms@outlook.com>
This commit is contained in:
parent
9048bc1a5e
commit
502f7c0638
|
@ -100,10 +100,6 @@ jobs:
|
|||
echo "PATH=$PATH:$HOME/.local/bin" >> $GITHUB_ENV
|
||||
pip3 install setuptools wheel
|
||||
pip3 install mechanical-markdown
|
||||
- name: Install Local mongo database using docker-compose
|
||||
run: |
|
||||
docker-compose -f ./sdk-tests/deploy/local-test.yml up -d mongo
|
||||
docker ps
|
||||
- name: Clean up files
|
||||
run: ./mvnw clean
|
||||
- name: Build sdk
|
||||
|
@ -146,14 +142,10 @@ jobs:
|
|||
working-directory: ./examples
|
||||
run: |
|
||||
mm.py ./src/main/java/io/dapr/examples/unittesting/README.md
|
||||
- name: Validate Configuration gRPC API example
|
||||
- name: Validate Configuration API example
|
||||
working-directory: ./examples
|
||||
run: |
|
||||
mm.py ./src/main/java/io/dapr/examples/configuration/grpc/README.md
|
||||
- name: Validate Configuration HTTP API example
|
||||
working-directory: ./examples
|
||||
run: |
|
||||
mm.py ./src/main/java/io/dapr/examples/configuration/http/README.md
|
||||
mm.py ./src/main/java/io/dapr/examples/configuration/README.md
|
||||
- name: Validate actors example
|
||||
working-directory: ./examples
|
||||
run: |
|
||||
|
|
|
@ -105,6 +105,7 @@ Try the following examples to learn more about Dapr's Java SDK:
|
|||
* [Binding with input over Http](./examples/src/main/java/io/dapr/examples/bindings/http)
|
||||
* [Actors](./examples/src/main/java/io/dapr/examples/actors/)
|
||||
* [Secrets management](./examples/src/main/java/io/dapr/examples/secrets)
|
||||
* [Configuration](./examples/src/main/java/io/dapr/examples/configuration)
|
||||
* [Distributed tracing with OpenTelemetry SDK](./examples/src/main/java/io/dapr/examples/tracing)
|
||||
* [Exception handling](./examples/src/main/java/io/dapr/examples/exception)
|
||||
* [Unit testing](./examples/src/main/java/io/dapr/examples/unittesting)
|
||||
|
|
|
@ -16,15 +16,15 @@ package io.dapr.examples;
|
|||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.propagation.TextMapPropagator;
|
||||
import jakarta.servlet.DispatcherType;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.servlet.DispatcherType;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.Collections;
|
||||
|
||||
@Component
|
||||
|
|
|
@ -54,7 +54,7 @@ Run `dapr init` to initialize Dapr in Self-Hosted Mode if it's not already initi
|
|||
|
||||
Before getting into the application code, follow these steps in order to set up a local instance of Kafka. This is needed for the local instances.
|
||||
|
||||
1. Run the container locally:
|
||||
1. Run the Kafka locally:
|
||||
|
||||
<!-- STEP
|
||||
name: Setup kafka container
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
version: '2'
|
||||
version: '3'
|
||||
services:
|
||||
zookeeper:
|
||||
image: confluentinc/cp-zookeeper:7.4.4
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package io.dapr.examples.configuration.grpc;
|
||||
package io.dapr.examples.configuration;
|
||||
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.DaprClientBuilder;
|
|
@ -158,7 +158,7 @@ sleep: 10
|
|||
-->
|
||||
|
||||
```bash
|
||||
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
|
||||
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.ConfigurationClient
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
* 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.http;
|
||||
|
||||
import io.dapr.client.DaprApiProtocol;
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.client.domain.ConfigurationItem;
|
||||
import io.dapr.client.domain.GetConfigurationRequest;
|
||||
import io.dapr.client.domain.SubscribeConfigurationRequest;
|
||||
import io.dapr.client.domain.SubscribeConfigurationResponse;
|
||||
import io.dapr.config.Properties;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConfigurationClient {
|
||||
|
||||
private static final String CONFIG_STORE_NAME = "configstore";
|
||||
private static String SUBSCRIPTION_ID;
|
||||
|
||||
/**
|
||||
* Executes various methods to check the different apis.
|
||||
* @param args arguments
|
||||
* @throws Exception throws Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.getProperties().setProperty(Properties.API_PROTOCOL.getName(), DaprApiProtocol.HTTP.name());
|
||||
try (DaprClient client = (new DaprClientBuilder()).build()) {
|
||||
System.out.println("Using Dapr client...");
|
||||
getConfigurations(client);
|
||||
subscribeConfigurationRequest(client);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets configurations for a list of keys.
|
||||
*
|
||||
* @param client DaprClient object
|
||||
*/
|
||||
public static void getConfigurations(DaprClient client) {
|
||||
System.out.println("*******trying to retrieve configurations for a list of keys********");
|
||||
List<String> keys = new ArrayList<>();
|
||||
keys.add("myconfig1");
|
||||
keys.add("myconfig2");
|
||||
keys.add("myconfig3");
|
||||
|
||||
Map<String, String> hmap = new HashMap<>();
|
||||
hmap.put("meta_key","meta_value");
|
||||
GetConfigurationRequest req = new GetConfigurationRequest(CONFIG_STORE_NAME, keys);
|
||||
req.setMetadata(hmap);
|
||||
|
||||
try {
|
||||
Mono<Map<String, ConfigurationItem>> items = client.getConfiguration(req);
|
||||
items.block().forEach((k,v) -> print(v, k));
|
||||
} catch (Exception ex) {
|
||||
System.out.println(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to a list of keys.
|
||||
*
|
||||
* @param client DaprClient object
|
||||
*/
|
||||
public static void subscribeConfigurationRequest(DaprClient client) throws InterruptedException {
|
||||
System.out.println("Subscribing to key: myconfig2");
|
||||
SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(
|
||||
CONFIG_STORE_NAME, Collections.singletonList("myconfig2"));
|
||||
Flux<SubscribeConfigurationResponse> outFlux = client.subscribeConfiguration(req);
|
||||
outFlux.subscribe(
|
||||
cis -> {
|
||||
SUBSCRIPTION_ID = cis.getSubscriptionId();
|
||||
});
|
||||
if (!SUBSCRIPTION_ID.isEmpty()) {
|
||||
System.out.println("subscribing to myconfig2 is successful");
|
||||
} else {
|
||||
System.out.println("error in subscribing to myconfig2");
|
||||
}
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
|
||||
private static void print(ConfigurationItem item, String key) {
|
||||
System.out.println(item.getValue() + " : key ->" + key);
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
* 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.http;
|
||||
|
||||
import io.dapr.client.domain.SubscribeConfigurationResponse;
|
||||
import io.dapr.examples.DaprApplication;
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.DefaultParser;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* A sample springboot application to register and receive for updates on configuration items sent by Dapr.
|
||||
* Users are free to write their own controllers to handle any specific route suited to the need.
|
||||
* java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.configuration.http.ConfigurationSubscriber -p 3009
|
||||
*/
|
||||
@RestController
|
||||
public class ConfigurationHandler {
|
||||
|
||||
/**
|
||||
* Receives a subscription change notification.
|
||||
* @param configStore Path variables for post call
|
||||
* @param key Key whose value has changed
|
||||
* @param response Configuration response
|
||||
*/
|
||||
@PostMapping(path = "/configuration/{configStore}/{key}", produces = MediaType.ALL_VALUE)
|
||||
public void handleConfigUpdate(@PathVariable("configStore") String configStore,
|
||||
@PathVariable("key") String key,
|
||||
@RequestBody SubscribeConfigurationResponse response) {
|
||||
System.out.println("Configuration update received for store: " + configStore);
|
||||
response.getItems().forEach((k,v) -> System.out.println("Key: " + k + " Value :" + v.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is entry point for Configuration Subscriber service.
|
||||
* @param args Arguments for main
|
||||
* @throws Exception Throws Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
Options options = new Options();
|
||||
options.addRequiredOption("p", "port", true, "The port this app will listen on");
|
||||
CommandLineParser parser = new DefaultParser();
|
||||
CommandLine cmd = parser.parse(options, args);
|
||||
// If port string is not valid, it will throw an exception.
|
||||
int port = Integer.parseInt(cmd.getOptionValue("port"));
|
||||
DaprApplication.start(port);
|
||||
}
|
||||
}
|
|
@ -1,218 +0,0 @@
|
|||
## 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/)
|
||||
|
||||
### Using the ConfigurationAPI
|
||||
|
||||
The java SDK exposes several methods for this -
|
||||
* `client.getConfiguration(...)` for getting a configuration for a single/multiple keys.
|
||||
* `client.subscribeConfiguration(...)` for subscribing to a list of keys for any change.
|
||||
* `client.unsubscribeConfiguration(...)` for unsubscribing to changes from subscribed items.
|
||||
|
||||
## Pre-requisites
|
||||
|
||||
* [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/).
|
||||
* Java JDK 11 (or greater):
|
||||
* [Microsoft JDK 11](https://docs.microsoft.com/en-us/java/openjdk/download#openjdk-11)
|
||||
* [Oracle JDK 11](https://www.oracle.com/technetwork/java/javase/downloads/index.html#JDK11)
|
||||
* [OpenJDK 11](https://jdk.java.net/11/)
|
||||
* [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
|
||||
```
|
||||
|
||||
Then get into the examples directory:
|
||||
|
||||
```sh
|
||||
cd examples
|
||||
```
|
||||
|
||||
### Initialize Dapr
|
||||
|
||||
Run `dapr init` to initialize Dapr in Self-Hosted Mode if it's not already initialized.
|
||||
|
||||
## Store few dummy configurations in configurationstore
|
||||
<!-- STEP
|
||||
name: Set configuration value
|
||||
expected_stdout_lines:
|
||||
- "OK"
|
||||
timeout_seconds: 20
|
||||
-->
|
||||
|
||||
```bash
|
||||
docker exec dapr_redis redis-cli MSET myconfig1 "val1||1" myconfig2 "val2||1" myconfig3 "val3||1"
|
||||
```
|
||||
<!-- END_STEP -->
|
||||
|
||||
### Running the example
|
||||
|
||||
This example uses the Java SDK Dapr client in order to **Get, Subscribe and Unsubscribe** from configuration items and utilizes `Redis` as configuration store.
|
||||
`ConfigurationClient.java` is the example class demonstrating all 3 features.
|
||||
Check [DaprClient.java](https://github.com/dapr/java-sdk/blob/master/sdk/src/main/java/io/dapr/client/DaprClient.java) for detailed description of the supported APIs.
|
||||
|
||||
```java
|
||||
public class ConfigurationClient {
|
||||
// ...
|
||||
/**
|
||||
* Executes various methods to check the different apis.
|
||||
* @param args arguments
|
||||
* @throws Exception throws Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.getProperties().setProperty(Properties.API_PROTOCOL.getName(), DaprApiProtocol.HTTP.name());
|
||||
try (DaprClient client = (new DaprClientBuilder()).build()) {
|
||||
System.out.println("Using Dapr client...");
|
||||
getConfigurations(client);
|
||||
subscribeConfigurationRequest(client);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets configurations for a list of keys.
|
||||
*
|
||||
* @param client DaprClient object
|
||||
*/
|
||||
public static void getConfigurations(DaprClient client) {
|
||||
System.out.println("*******trying to retrieve configurations for a list of keys********");
|
||||
GetConfigurationRequest req = new GetConfigurationRequest(CONFIG_STORE_NAME, keys);
|
||||
try {
|
||||
Mono<List<ConfigurationItem>> items = client.getConfiguration(req);
|
||||
// ...
|
||||
} catch (Exception ex) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to a list of keys.
|
||||
*
|
||||
* @param client DaprClient object
|
||||
*/
|
||||
public static void subscribeConfigurationRequest(DaprClient client) {
|
||||
// ...
|
||||
SubscribeConfigurationRequest req = new SubscribeConfigurationRequest(
|
||||
CONFIG_STORE_NAME, Collections.singletonList("myconfig2"));
|
||||
Runnable subscribeTask = () -> {
|
||||
Flux<SubscribeConfigurationResponse> outFlux = client.subscribeConfiguration(req);
|
||||
// ...
|
||||
};
|
||||
// ..
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Get into the examples' directory:
|
||||
```sh
|
||||
cd examples
|
||||
```
|
||||
|
||||
#### Running the configuration subscriber app:
|
||||
|
||||
`DaprApplication.start()` Method will run a Spring Boot application containing a `ConfigurationHandler`, a contoller
|
||||
to receive configuration change notifications.
|
||||
|
||||
```java
|
||||
@RestController
|
||||
public class ConfigurationHandler {
|
||||
//...
|
||||
@PostMapping(path = "/configuration/{configStore}/{key}", produces = MediaType.ALL_VALUE)
|
||||
public void handleConfigUpdate(@PathVariable("configStore") String configStore,
|
||||
@PathVariable("key") String key,
|
||||
@RequestBody SubscribeConfigurationResponse response) {
|
||||
System.out.println("Configuration update received for store: " + configStore);
|
||||
response.getItems().forEach((k,v) -> System.out.println("Key: " + k + " Value :" + v.getValue()));
|
||||
}
|
||||
//....
|
||||
}
|
||||
```
|
||||
Execute the following script to run the ConfigSubscriber app:
|
||||
|
||||
<!-- STEP
|
||||
name: Run ConfigurationHandler
|
||||
expected_stdout_lines:
|
||||
- '== APP == Configuration update received for store: configstore'
|
||||
- '== APP == Key: myconfig2 Value :updated_val2'
|
||||
background: true
|
||||
output_match_mode: substring
|
||||
background: true
|
||||
sleep: 5
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr run --app-id confighandler -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.configuration.http.ConfigurationHandler -p 3009
|
||||
```
|
||||
<!-- END_STEP -->
|
||||
|
||||
#### Running the ConfigurationClient app:
|
||||
|
||||
Use the following command to run this example-
|
||||
|
||||
<!-- STEP
|
||||
name: Run ConfigurationClient example
|
||||
expected_stdout_lines:
|
||||
- "== APP == Using Dapr client..."
|
||||
- "== 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 key: myconfig2"
|
||||
- "== APP == subscribing to myconfig2 is successful"
|
||||
background: true
|
||||
output_match_mode: substring
|
||||
sleep: 10
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr run --components-path ./components/configuration --app-id confighttp --log-level debug --app-port 3009 --dapr-http-port 3500 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.configuration.http.ConfigurationClient
|
||||
```
|
||||
|
||||
#### Update myconfig2 key in configurationstore
|
||||
<!-- END_STEP -->
|
||||
|
||||
<!-- STEP
|
||||
name: Update configuration value
|
||||
timeout_seconds: 20
|
||||
-->
|
||||
|
||||
```bash
|
||||
docker exec dapr_redis redis-cli MSET myconfig2 "updated_val2||1"
|
||||
```
|
||||
<!-- END_STEP -->
|
||||
|
||||
### Sample output
|
||||
```
|
||||
== APP == Using Dapr client...
|
||||
== 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 key: myconfig2
|
||||
== APP == subscribing to myconfig2 is successful
|
||||
```
|
||||
### Cleanup
|
||||
|
||||
To stop the app, run (or press CTRL+C):
|
||||
|
||||
<!-- STEP
|
||||
name: Cleanup
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr stop --app-id confighttp
|
||||
dapr stop --app-id confighandler
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
|
@ -13,17 +13,13 @@ limitations under the License.
|
|||
|
||||
package io.dapr.examples.invoke.grpc;
|
||||
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.examples.DaprExamplesProtos.HelloReply;
|
||||
import io.dapr.examples.DaprExamplesProtos.HelloRequest;
|
||||
import io.dapr.examples.HelloWorldGrpc;
|
||||
import io.grpc.Grpc;
|
||||
import io.grpc.InsecureChannelCredentials;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.StatusRuntimeException;
|
||||
import io.grpc.stub.MetadataUtils;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -45,22 +41,11 @@ public class HelloWorldClient {
|
|||
* @param args Array of messages to be sent.
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
String user = "World";
|
||||
String target = "localhost:" + System.getenv("DAPR_GRPC_PORT");
|
||||
|
||||
ManagedChannel channel = Grpc.newChannelBuilder(target, InsecureChannelCredentials.create())
|
||||
.build();
|
||||
|
||||
try {
|
||||
HelloWorldGrpc.HelloWorldBlockingStub blockingStub = HelloWorldGrpc.newBlockingStub(channel);
|
||||
|
||||
Metadata headers = new Metadata();
|
||||
headers.put(Metadata.Key.of("dapr-app-id", Metadata.ASCII_STRING_MARSHALLER),
|
||||
"hellogrpc");
|
||||
|
||||
// MetadataUtils.attachHeaders is deprecated.
|
||||
blockingStub = blockingStub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(headers));
|
||||
try (DaprClient client = new DaprClientBuilder().build()) {
|
||||
HelloWorldGrpc.HelloWorldBlockingStub blockingStub = client.newGrpcStub(
|
||||
"hellogrpc",
|
||||
channel -> HelloWorldGrpc.newBlockingStub(channel));
|
||||
|
||||
logger.info("Will try to greet " + user + " ...");
|
||||
try {
|
||||
|
@ -70,10 +55,6 @@ public class HelloWorldClient {
|
|||
} catch (StatusRuntimeException e) {
|
||||
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
|
||||
}
|
||||
} finally {
|
||||
// To prevent leaking resources like threads and TCP connections
|
||||
// the channel should be shut down when it will no longer be used.
|
||||
channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ public class HelloWorldService {
|
|||
/**
|
||||
* Handling of the 'sayHello' method.
|
||||
*
|
||||
* @param request Request to say something.
|
||||
* @param req Request to say something.
|
||||
* @return Response with when it was said.
|
||||
*/
|
||||
@Override
|
||||
|
|
|
@ -61,7 +61,7 @@ In the `HelloWorldService.java` file, you will find the `HelloWorldService` clas
|
|||
/**
|
||||
* Handling of the 'sayHello' method.
|
||||
*
|
||||
* @param request Request to say something.
|
||||
* @param req Request to say something.
|
||||
* @return Response with when it was said.
|
||||
*/
|
||||
@Override
|
||||
|
@ -93,27 +93,17 @@ The `app-id` argument is used to identify this service in Dapr's runtime. The `a
|
|||
|
||||
### Running the example's client
|
||||
|
||||
The other component is the client. It will add user name to the grpc request and send it to the server. Open the `HelloWorldClient.java` file, it creates a new grpc channel and sends request directly to the dapr side car through this channel.
|
||||
The other component is the client. It will add user name to the grpc request and send it to the server. Open the `HelloWorldClient.java` file, it uses the DaprClient's grpc channel and sends request directly to the dapr side car through it, including necessary headers.
|
||||
|
||||
```java
|
||||
private static class HelloWorldClient {
|
||||
///...
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
String user = "World";
|
||||
// Access a service running on the local machine on port 50051
|
||||
String target = "localhost:50051";
|
||||
|
||||
ManagedChannel channel = Grpc.newChannelBuilder(target, InsecureChannelCredentials.create())
|
||||
.build();
|
||||
|
||||
try {
|
||||
HelloWorldGrpc.HelloWorldBlockingStub blockingStub = HelloWorldGrpc.newBlockingStub(channel);
|
||||
|
||||
Metadata headers = new Metadata();
|
||||
headers.put(Metadata.Key.of("dapr-app-id", Metadata.ASCII_STRING_MARSHALLER),
|
||||
"hellogrpc");
|
||||
blockingStub = MetadataUtils.attachHeaders(blockingStub, headers);
|
||||
try (DaprClient client = new DaprClientBuilder().build()) {
|
||||
HelloWorldGrpc.HelloWorldBlockingStub blockingStub = HelloWorldGrpc.newBlockingStub(client.getGrpcChannel());
|
||||
// Adds Dapr interceptors to populate gRPC metadata automatically.
|
||||
blockingStub = DaprClientGrpcInterceptors.intercept("hellogrpc", blockingStub);
|
||||
|
||||
logger.info("Will try to greet " + user + " ...");
|
||||
try {
|
||||
|
@ -123,10 +113,6 @@ private static class HelloWorldClient {
|
|||
} catch (StatusRuntimeException e) {
|
||||
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
|
||||
}
|
||||
} finally {
|
||||
// To prevent leaking resources like threads and TCP connections
|
||||
// the channel should be shut down when it will no longer be used.
|
||||
channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
///...
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package io.dapr.examples.lock.grpc;
|
||||
package io.dapr.examples.lock;
|
||||
|
||||
|
||||
import io.dapr.client.DaprClientBuilder;
|
|
@ -58,7 +58,7 @@ sleep: 5
|
|||
-->
|
||||
|
||||
```bash
|
||||
dapr run --components-path ./components/lock --app-id lockgrpc --log-level debug -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.lock.grpc.DistributedLockGrpcClient
|
||||
dapr run --components-path ./components/lock --app-id lockgrpc --log-level debug -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.lock.DistributedLockGrpcClient
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
* 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.lock.http;
|
||||
|
||||
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.client.DaprPreviewClient;
|
||||
import io.dapr.client.domain.LockRequest;
|
||||
import io.dapr.client.domain.UnlockRequest;
|
||||
import io.dapr.client.domain.UnlockResponseStatus;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* DistributedLockGrpcClient.
|
||||
*/
|
||||
public class DistributedLockHttpClient {
|
||||
private static final String LOCK_STORE_NAME = "lockstore";
|
||||
|
||||
/**
|
||||
* 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 DaprClientBuilder()).buildPreviewClient()) {
|
||||
System.out.println("Using preview client...");
|
||||
tryLock(client);
|
||||
unlock(client);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trying to get lock.
|
||||
*
|
||||
* @param client DaprPreviewClient object
|
||||
*/
|
||||
public static void tryLock(DaprPreviewClient client) {
|
||||
System.out.println("*******trying to get a free distributed lock********");
|
||||
try {
|
||||
LockRequest lockRequest = new LockRequest(LOCK_STORE_NAME, "resouce1", "owner1", 5);
|
||||
Mono<Boolean> result = client.tryLock(lockRequest);
|
||||
System.out.println("Lock result -> " + (Boolean.TRUE.equals(result.block()) ? "SUCCESS" : "FAIL"));
|
||||
} catch (Exception ex) {
|
||||
System.out.println(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock a lock.
|
||||
*
|
||||
* @param client DaprPreviewClient object
|
||||
*/
|
||||
public static void unlock(DaprPreviewClient client) {
|
||||
System.out.println("*******unlock a distributed lock********");
|
||||
try {
|
||||
UnlockRequest unlockRequest = new UnlockRequest(LOCK_STORE_NAME, "resouce1", "owner1");
|
||||
Mono<UnlockResponseStatus> result = client.unlock(unlockRequest);
|
||||
System.out.println("Unlock result ->" + result.block().name());
|
||||
} catch (Exception ex) {
|
||||
System.out.println(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
## Distributed Lock API Example
|
||||
|
||||
This example provides the different capabilities provided by Dapr Java SDK for Distributed Lock. For further information about Distributed Lock APIs please refer to [this link](https://docs.dapr.io/developing-applications/building-blocks/distributed-lock/)
|
||||
**This API is available in Preview Mode**.
|
||||
|
||||
### Using the Distributed Lock API
|
||||
|
||||
The java SDK exposes several methods for this -
|
||||
* `client.tryLock(...)` for getting a free distributed lock
|
||||
* `client.unlock(...)` for unlocking a lock
|
||||
|
||||
## Pre-requisites
|
||||
|
||||
* [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/).
|
||||
* Java JDK 11 (or greater):
|
||||
* [Microsoft JDK 11](https://docs.microsoft.com/en-us/java/openjdk/download#openjdk-11)
|
||||
* [Oracle JDK 11](https://www.oracle.com/technetwork/java/javase/downloads/index.html#JDK11)
|
||||
* [OpenJDK 11](https://jdk.java.net/11/)
|
||||
* [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
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
### Running the example
|
||||
|
||||
Get into the examples' directory:
|
||||
```sh
|
||||
cd examples
|
||||
```
|
||||
|
||||
Use the following command to run this example-
|
||||
|
||||
<!-- STEP
|
||||
name: Run DistributedLockHttpClient example
|
||||
expected_stdout_lines:
|
||||
- "== APP == Using preview client..."
|
||||
- "== APP == *******trying to get a free distributed lock********"
|
||||
- "== APP == Lock result -> SUCCESS"
|
||||
- "== APP == *******unlock a distributed lock********"
|
||||
- "== APP == Unlock result -> SUCCESS"
|
||||
background: true
|
||||
sleep: 5
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr run --components-path ./components/lock --app-id lockhttp --log-level debug -- java -Ddapr.api.protocol=HTTP -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.lock.http.DistributedLockHttpClient
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
### Sample output
|
||||
```
|
||||
== APP == Using preview client...
|
||||
== APP == *******trying to get a free distributed lock********
|
||||
== APP == Lock result -> SUCCESS
|
||||
== APP == *******unlock a distributed lock********
|
||||
== APP == Unlock result -> SUCCESS
|
||||
```
|
||||
### Cleanup
|
||||
|
||||
To stop the app, run (or press CTRL+C):
|
||||
|
||||
<!-- STEP
|
||||
name: Cleanup
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr stop --app-id lockhttp
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
|
@ -36,6 +36,20 @@ cd examples
|
|||
|
||||
Run `dapr init` to initialize Dapr in Self-Hosted Mode if it's not already initialized.
|
||||
|
||||
### Run MongoDB
|
||||
|
||||
<!-- STEP
|
||||
name: Setup mongo container
|
||||
sleep: 5
|
||||
-->
|
||||
|
||||
```bash
|
||||
docker-compose -f ./src/main/java/io/dapr/examples/querystate/docker-compose-single-mongo.yml up -d
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
|
||||
### Running the State Client
|
||||
This example uses the Java SDK Dapr client in order to save bulk state and query state, in this case, an instance of a class. See the code snippets below:
|
||||
|
||||
|
@ -282,5 +296,16 @@ name: Cleanup
|
|||
```bash
|
||||
dapr stop --app-id query-state-example
|
||||
```
|
||||
<!-- END_STEP -->
|
||||
|
||||
Then, stop MongoDB container.
|
||||
|
||||
<!-- STEP
|
||||
name: Cleanup MongoDB containers
|
||||
-->
|
||||
|
||||
```bash
|
||||
docker-compose -f ./src/main/java/io/dapr/examples/querystate/docker-compose-single-mongo.yml down
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
version: '3'
|
||||
services:
|
||||
mongo:
|
||||
image: mongo
|
||||
ports:
|
||||
- "27017:27017"
|
|
@ -36,6 +36,19 @@ cd examples
|
|||
|
||||
Run `dapr init` to initialize Dapr in Self-Hosted Mode if it's not already initialized.
|
||||
|
||||
### Run MongoDB
|
||||
|
||||
<!-- STEP
|
||||
name: Setup mongo container
|
||||
sleep: 5
|
||||
-->
|
||||
|
||||
```bash
|
||||
docker-compose -f ./src/main/java/io/dapr/examples/state/docker-compose-single-mongo.yml up -d
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
### Running the StateClient
|
||||
This example uses the Java SDK Dapr client in order to save, retrieve and delete a state, in this case, an instance of a class. Multiple state stores are supported since Dapr 0.4. See the code snippet bellow:
|
||||
|
||||
|
@ -206,3 +219,15 @@ dapr stop --app-id state-example
|
|||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
Then, stop MongoDB container.
|
||||
|
||||
<!-- STEP
|
||||
name: Cleanup MongoDB container
|
||||
-->
|
||||
|
||||
```bash
|
||||
docker-compose -f ./src/main/java/io/dapr/examples/state/docker-compose-single-mongo.yml down
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
version: '3'
|
||||
services:
|
||||
mongo:
|
||||
image: mongo
|
||||
ports:
|
||||
- "27017:27017"
|
|
@ -16,7 +16,6 @@ package io.dapr.examples.workflows.chain;
|
|||
import io.dapr.workflows.client.DaprWorkflowClient;
|
||||
import io.dapr.workflows.client.WorkflowInstanceStatus;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
public class DemoChainClient {
|
||||
|
|
|
@ -14,6 +14,7 @@ limitations under the License.
|
|||
package io.dapr.examples.workflows.continueasnew;
|
||||
|
||||
import io.dapr.workflows.client.DaprWorkflowClient;
|
||||
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
public class DemoContinueAsNewClient {
|
||||
|
|
|
@ -14,6 +14,7 @@ limitations under the License.
|
|||
package io.dapr.examples.workflows.externalevent;
|
||||
|
||||
import io.dapr.workflows.client.DaprWorkflowClient;
|
||||
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
public class DemoExternalEventClient {
|
||||
|
|
|
@ -13,7 +13,6 @@ limitations under the License.
|
|||
|
||||
package io.dapr.examples.workflows.subworkflow;
|
||||
|
||||
import io.dapr.examples.workflows.chain.ToUpperCaseActivity;
|
||||
import io.dapr.workflows.runtime.WorkflowActivity;
|
||||
import io.dapr.workflows.runtime.WorkflowActivityContext;
|
||||
import org.slf4j.Logger;
|
||||
|
|
|
@ -13,8 +13,6 @@ limitations under the License.
|
|||
|
||||
package io.dapr.actors.client;
|
||||
|
||||
import io.dapr.client.DaprApiProtocol;
|
||||
import io.dapr.client.DaprHttpBuilder;
|
||||
import io.dapr.client.resiliency.ResiliencyOptions;
|
||||
import io.dapr.config.Properties;
|
||||
import io.dapr.utils.Version;
|
||||
|
@ -55,33 +53,21 @@ public class ActorClient implements AutoCloseable {
|
|||
*
|
||||
* @param resiliencyOptions Client resiliency options.
|
||||
*/
|
||||
public ActorClient(ResiliencyOptions resiliencyOptions) {
|
||||
this(Properties.API_PROTOCOL.get(), resiliencyOptions);
|
||||
private ActorClient(ResiliencyOptions resiliencyOptions) {
|
||||
this(buildManagedChannel(), resiliencyOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new channel for Dapr sidecar communication.
|
||||
*
|
||||
* @param apiProtocol Dapr's API protocol.
|
||||
* @param resiliencyOptions Client resiliency options.
|
||||
*/
|
||||
private ActorClient(DaprApiProtocol apiProtocol, ResiliencyOptions resiliencyOptions) {
|
||||
this(apiProtocol, buildManagedChannel(apiProtocol), resiliencyOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new channel for Dapr sidecar communication.
|
||||
*
|
||||
* @param apiProtocol Dapr's API protocol.
|
||||
* @param grpcManagedChannel gRPC channel.
|
||||
* @param resiliencyOptions Client resiliency options.
|
||||
*/
|
||||
private ActorClient(
|
||||
DaprApiProtocol apiProtocol,
|
||||
ManagedChannel grpcManagedChannel,
|
||||
ResiliencyOptions resiliencyOptions) {
|
||||
this.grpcManagedChannel = grpcManagedChannel;
|
||||
this.daprClient = buildDaprClient(apiProtocol, grpcManagedChannel, resiliencyOptions);
|
||||
this.daprClient = buildDaprClient(grpcManagedChannel, resiliencyOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,14 +96,9 @@ public class ActorClient implements AutoCloseable {
|
|||
/**
|
||||
* Creates a GRPC managed channel (or null, if not applicable).
|
||||
*
|
||||
* @param apiProtocol Dapr's API protocol.
|
||||
* @return GRPC managed channel or null.
|
||||
*/
|
||||
private static ManagedChannel buildManagedChannel(DaprApiProtocol apiProtocol) {
|
||||
if (apiProtocol != DaprApiProtocol.GRPC) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static ManagedChannel buildManagedChannel() {
|
||||
int port = Properties.GRPC_PORT.get();
|
||||
if (port <= 0) {
|
||||
throw new IllegalArgumentException("Invalid port.");
|
||||
|
@ -136,16 +117,8 @@ public class ActorClient implements AutoCloseable {
|
|||
* @throws java.lang.IllegalStateException if any required field is missing
|
||||
*/
|
||||
private static DaprClient buildDaprClient(
|
||||
DaprApiProtocol apiProtocol,
|
||||
Channel grpcManagedChannel,
|
||||
ResiliencyOptions resiliencyOptions) {
|
||||
switch (apiProtocol) {
|
||||
case GRPC: return new DaprGrpcClient(DaprGrpc.newStub(grpcManagedChannel), resiliencyOptions);
|
||||
case HTTP: {
|
||||
LOGGER.warn("HTTP client protocol is deprecated and will be removed in Dapr's Java SDK version 1.10.");
|
||||
return new DaprHttpClient(new DaprHttpBuilder().build());
|
||||
}
|
||||
default: throw new IllegalStateException("Unsupported protocol: " + apiProtocol.name());
|
||||
}
|
||||
return new DaprClientImpl(DaprGrpc.newStub(grpcManagedChannel), resiliencyOptions);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import com.google.protobuf.ByteString;
|
|||
import io.dapr.client.resiliency.ResiliencyOptions;
|
||||
import io.dapr.config.Properties;
|
||||
import io.dapr.exceptions.DaprException;
|
||||
import io.dapr.internal.opencensus.GrpcWrapper;
|
||||
import io.dapr.internal.grpc.DaprClientGrpcInterceptors;
|
||||
import io.dapr.internal.resiliency.RetryPolicy;
|
||||
import io.dapr.internal.resiliency.TimeoutPolicy;
|
||||
import io.dapr.v1.DaprGrpc;
|
||||
|
@ -40,7 +40,7 @@ import java.util.function.Consumer;
|
|||
/**
|
||||
* A DaprClient over GRPC for Actor.
|
||||
*/
|
||||
class DaprGrpcClient implements DaprClient {
|
||||
class DaprClientImpl implements DaprClient {
|
||||
|
||||
/**
|
||||
* Timeout policy for SDK calls to Dapr API.
|
||||
|
@ -63,7 +63,7 @@ class DaprGrpcClient implements DaprClient {
|
|||
* @param grpcClient Dapr's GRPC client.
|
||||
* @param resiliencyOptions Client resiliency options (optional)
|
||||
*/
|
||||
DaprGrpcClient(DaprGrpc.DaprStub grpcClient, ResiliencyOptions resiliencyOptions) {
|
||||
DaprClientImpl(DaprGrpc.DaprStub grpcClient, ResiliencyOptions resiliencyOptions) {
|
||||
this.client = intercept(grpcClient);
|
||||
this.timeoutPolicy = new TimeoutPolicy(
|
||||
resiliencyOptions == null ? null : resiliencyOptions.getTimeout());
|
||||
|
@ -85,7 +85,7 @@ class DaprGrpcClient implements DaprClient {
|
|||
.build();
|
||||
return Mono.deferContextual(
|
||||
context -> this.<DaprProtos.InvokeActorResponse>createMono(
|
||||
it -> intercept(context, client).invokeActor(req, it)
|
||||
it -> intercept(context, this.timeoutPolicy, client).invokeActor(req, it)
|
||||
)
|
||||
).map(r -> r.getData().toByteArray());
|
||||
}
|
||||
|
@ -124,11 +124,13 @@ class DaprGrpcClient implements DaprClient {
|
|||
* Populates GRPC client with interceptors for telemetry.
|
||||
*
|
||||
* @param context Reactor's context.
|
||||
* @param timeoutPolicy Timeout policy for gRPC call.
|
||||
* @param client GRPC client for Dapr.
|
||||
* @return Client after adding interceptors.
|
||||
*/
|
||||
private static DaprGrpc.DaprStub intercept(ContextView context, DaprGrpc.DaprStub client) {
|
||||
return GrpcWrapper.intercept(context, client);
|
||||
private static DaprGrpc.DaprStub intercept(
|
||||
ContextView context, TimeoutPolicy timeoutPolicy, DaprGrpc.DaprStub client) {
|
||||
return DaprClientGrpcInterceptors.intercept(client, timeoutPolicy, context);
|
||||
}
|
||||
|
||||
private <T> Mono<T> createMono(Consumer<StreamObserver<T>> consumer) {
|
|
@ -1,53 +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.actors.client;
|
||||
|
||||
import io.dapr.client.DaprHttp;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* DaprClient over HTTP for actor client.
|
||||
* @deprecated This class will be deleted at SDK release version 1.10.
|
||||
* @see DaprHttp
|
||||
*/
|
||||
@Deprecated
|
||||
class DaprHttpClient implements DaprClient {
|
||||
|
||||
/**
|
||||
* The HTTP client to be used.
|
||||
*
|
||||
* @see DaprHttp
|
||||
*/
|
||||
private final DaprHttp client;
|
||||
|
||||
/**
|
||||
* Instantiates a new Dapr Http Client to invoke Actors.
|
||||
*
|
||||
* @param client Dapr's http client.
|
||||
*/
|
||||
DaprHttpClient(DaprHttp client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<byte[]> invoke(String actorType, String actorId, String methodName, byte[] jsonPayload) {
|
||||
String[] pathSegments = new String[] { DaprHttp.API_VERSION, "actors", actorType, actorId, "method", methodName };
|
||||
Mono<DaprHttp.Response> responseMono =
|
||||
this.client.invokeApi(DaprHttp.HttpMethods.POST.name(), pathSegments, null, jsonPayload, null, null);
|
||||
return responseMono.map(r -> r.getBody());
|
||||
}
|
||||
}
|
|
@ -15,8 +15,6 @@ package io.dapr.actors.runtime;
|
|||
|
||||
import io.dapr.actors.ActorId;
|
||||
import io.dapr.actors.ActorTrace;
|
||||
import io.dapr.client.DaprApiProtocol;
|
||||
import io.dapr.client.DaprHttpBuilder;
|
||||
import io.dapr.config.Properties;
|
||||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
|
@ -312,16 +310,12 @@ public class ActorRuntime implements Closeable {
|
|||
/**
|
||||
* Build an instance of the Client based on the provided setup.
|
||||
*
|
||||
* @param channel GRPC managed channel (or null, if not using GRPC).
|
||||
* @param channel GRPC managed channel.
|
||||
* @return an instance of the setup Client
|
||||
* @throws java.lang.IllegalStateException if any required field is missing
|
||||
*/
|
||||
private static DaprClient buildDaprClient(ManagedChannel channel) {
|
||||
if (Properties.API_PROTOCOL.get() == DaprApiProtocol.GRPC) {
|
||||
return new DaprGrpcClient(channel);
|
||||
}
|
||||
|
||||
return new DaprHttpClient(new DaprHttpBuilder().build());
|
||||
return new DaprGrpcClient(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -330,10 +324,6 @@ public class ActorRuntime implements Closeable {
|
|||
* @return GRPC managed channel or null.
|
||||
*/
|
||||
private static ManagedChannel buildManagedChannel() {
|
||||
if (Properties.API_PROTOCOL.get() != DaprApiProtocol.GRPC) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int port = Properties.GRPC_PORT.get();
|
||||
if (port <= 0) {
|
||||
throw new IllegalStateException("Invalid port.");
|
||||
|
|
|
@ -14,9 +14,9 @@ limitations under the License.
|
|||
package io.dapr.actors;
|
||||
|
||||
import io.dapr.exceptions.DaprException;
|
||||
import org.apache.commons.validator.routines.InetAddressValidator;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.function.Executable;
|
||||
import org.apache.commons.validator.routines.InetAddressValidator;
|
||||
|
||||
public final class TestUtils {
|
||||
|
||||
|
|
|
@ -32,9 +32,10 @@ import java.io.IOException;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static io.dapr.actors.TestUtils.assertThrowsDaprException;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.AdditionalAnswers.delegatesTo;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class DaprGrpcClientTest {
|
||||
|
||||
|
@ -89,7 +90,7 @@ public class DaprGrpcClientTest {
|
|||
}
|
||||
}));
|
||||
|
||||
private DaprGrpcClient client;
|
||||
private DaprClientImpl client;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws IOException {
|
||||
|
@ -105,7 +106,7 @@ public class DaprGrpcClientTest {
|
|||
InProcessChannelBuilder.forName(serverName).directExecutor().build());
|
||||
|
||||
// Create a HelloWorldClient using the in-process channel;
|
||||
client = new DaprGrpcClient(DaprGrpc.newStub(channel), null);
|
||||
client = new DaprClientImpl(DaprGrpc.newStub(channel), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,98 +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.actors.client;
|
||||
|
||||
import io.dapr.client.DaprHttp;
|
||||
import io.dapr.client.DaprHttpProxy;
|
||||
import io.dapr.config.Properties;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.mock.Behavior;
|
||||
import okhttp3.mock.MediaTypes;
|
||||
import okhttp3.mock.MockInterceptor;
|
||||
import org.junit.Before;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import static io.dapr.actors.TestUtils.formatIpAddress;
|
||||
import static io.dapr.actors.TestUtils.assertThrowsDaprException;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class DaprHttpClientTest {
|
||||
|
||||
private DaprHttpClient DaprHttpClient;
|
||||
|
||||
private OkHttpClient okHttpClient;
|
||||
|
||||
private MockInterceptor mockInterceptor;
|
||||
|
||||
private String sidecarIp;
|
||||
|
||||
private final String EXPECTED_RESULT = "{\"data\":\"ewoJCSJwcm9wZXJ0eUEiOiAidmFsdWVBIiwKCQkicHJvcGVydHlCIjogInZhbHVlQiIKCX0=\"}";
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
sidecarIp = formatIpAddress(Properties.SIDECAR_IP.get());
|
||||
mockInterceptor = new MockInterceptor(Behavior.UNORDERED);
|
||||
okHttpClient = new OkHttpClient.Builder().addInterceptor(mockInterceptor).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeActorMethod() {
|
||||
mockInterceptor.addRule()
|
||||
.post("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/method/Payment")
|
||||
.respond(EXPECTED_RESULT);
|
||||
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
|
||||
DaprHttpClient = new DaprHttpClient(daprHttp);
|
||||
Mono<byte[]> mono =
|
||||
DaprHttpClient.invoke("DemoActor", "1", "Payment", "".getBytes());
|
||||
assertEquals(new String(mono.block()), EXPECTED_RESULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeActorMethodIPv6() {
|
||||
String prevSidecarIp = sidecarIp;
|
||||
System.setProperty(Properties.SIDECAR_IP.getName(), "2001:db8:3333:4444:5555:6666:7777:8888");
|
||||
sidecarIp = formatIpAddress(Properties.SIDECAR_IP.get());
|
||||
mockInterceptor.addRule()
|
||||
.post("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/method/Payment")
|
||||
.respond(EXPECTED_RESULT);
|
||||
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
|
||||
DaprHttpClient = new DaprHttpClient(daprHttp);
|
||||
System.setProperty(Properties.SIDECAR_IP.getName(), prevSidecarIp);
|
||||
Mono<byte[]> mono =
|
||||
DaprHttpClient.invoke("DemoActor", "1", "Payment", "".getBytes());
|
||||
assertEquals(new String(mono.block()), EXPECTED_RESULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeActorMethodError() {
|
||||
mockInterceptor.addRule()
|
||||
.post("http://" + sidecarIp + ":3000/v1.0/actors/DemoActor/1/method/Payment")
|
||||
.respond(404,
|
||||
ResponseBody.create("" +
|
||||
"{\"errorCode\":\"ERR_SOMETHING\"," +
|
||||
"\"message\":\"error message\"}", MediaTypes.MEDIATYPE_JSON));
|
||||
DaprHttp daprHttp = new DaprHttpProxy(sidecarIp, 3000, okHttpClient);
|
||||
DaprHttpClient = new DaprHttpClient(daprHttp);
|
||||
Mono<byte[]> mono =
|
||||
DaprHttpClient.invoke("DemoActor", "1", "Payment", "".getBytes());
|
||||
|
||||
assertThrowsDaprException(
|
||||
"ERR_SOMETHING",
|
||||
"ERR_SOMETHING: error message",
|
||||
() -> mono.block());
|
||||
}
|
||||
|
||||
}
|
|
@ -19,7 +19,6 @@ import io.dapr.serializer.DefaultObjectSerializer;
|
|||
import io.dapr.utils.TypeRef;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -39,8 +39,10 @@ import java.util.List;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static io.dapr.actors.TestUtils.assertThrowsDaprException;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class DaprGrpcClientTest {
|
||||
|
||||
|
|
|
@ -35,10 +35,10 @@ import java.util.Base64;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static io.dapr.actors.TestUtils.formatIpAddress;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static io.dapr.actors.TestUtils.formatIpAddress;
|
||||
|
||||
public class DaprHttpClientTest {
|
||||
|
||||
|
|
|
@ -25,8 +25,12 @@ import reactor.core.publisher.Mono;
|
|||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for the state store facade.
|
||||
|
|
|
@ -19,7 +19,6 @@ import io.dapr.actors.client.ActorProxy;
|
|||
import io.dapr.actors.client.ActorProxyImplForTests;
|
||||
import io.dapr.actors.client.DaprClientStub;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
|
|
@ -26,7 +26,3 @@ services:
|
|||
image: mongo
|
||||
ports:
|
||||
- "27017:27017"
|
||||
redis:
|
||||
image: redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
|
|
|
@ -13,7 +13,6 @@ limitations under the License.
|
|||
|
||||
package io.dapr.it;
|
||||
|
||||
import io.dapr.client.DaprApiProtocol;
|
||||
import io.dapr.config.Properties;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -28,7 +27,7 @@ import static io.dapr.it.Retry.callWithRetry;
|
|||
public class AppRun implements Stoppable {
|
||||
|
||||
private static final String APP_COMMAND =
|
||||
"mvn exec:java -B -D exec.mainClass=%s -D exec.classpathScope=test -D exec.args=\"%s\" -D %s=%s -D %s=%s";
|
||||
"mvn exec:java -B -D exec.mainClass=%s -D exec.classpathScope=test -D exec.args=\"%s\"";
|
||||
|
||||
private final DaprPorts ports;
|
||||
|
||||
|
@ -39,11 +38,10 @@ public class AppRun implements Stoppable {
|
|||
AppRun(DaprPorts ports,
|
||||
String successMessage,
|
||||
Class serviceClass,
|
||||
int maxWaitMilliseconds,
|
||||
DaprApiProtocol protocol) {
|
||||
int maxWaitMilliseconds) {
|
||||
this.command = new Command(
|
||||
successMessage,
|
||||
buildCommand(serviceClass, ports, protocol),
|
||||
buildCommand(serviceClass, ports),
|
||||
new HashMap<>() {{
|
||||
put("DAPR_HTTP_PORT", ports.getHttpPort().toString());
|
||||
put("DAPR_GRPC_PORT", ports.getGrpcPort().toString());
|
||||
|
@ -81,11 +79,9 @@ public class AppRun implements Stoppable {
|
|||
}
|
||||
}
|
||||
|
||||
private static String buildCommand(Class serviceClass, DaprPorts ports, DaprApiProtocol protocol) {
|
||||
private static String buildCommand(Class serviceClass, DaprPorts ports) {
|
||||
return String.format(APP_COMMAND, serviceClass.getCanonicalName(),
|
||||
ports.getAppPort() != null ? ports.getAppPort().toString() : "",
|
||||
Properties.API_PROTOCOL.getName(), protocol,
|
||||
Properties.API_METHOD_INVOCATION_PROTOCOL.getName(), protocol);
|
||||
ports.getAppPort() != null ? ports.getAppPort().toString() : "");
|
||||
}
|
||||
|
||||
private static void assertListeningOnPort(int port) {
|
||||
|
@ -101,4 +97,7 @@ public class AppRun implements Stoppable {
|
|||
System.out.printf("Confirmed listening on port %d.\n", port);
|
||||
}
|
||||
|
||||
public enum AppProtocol {
|
||||
HTTP, GRPC;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,18 +14,19 @@ limitations under the License.
|
|||
package io.dapr.it;
|
||||
|
||||
import io.dapr.actors.client.ActorClient;
|
||||
import io.dapr.client.DaprApiProtocol;
|
||||
import io.dapr.client.resiliency.ResiliencyOptions;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
import static io.dapr.client.DaprApiProtocol.GRPC;
|
||||
import static io.dapr.client.DaprApiProtocol.HTTP;
|
||||
import static io.dapr.it.AppRun.AppProtocol.GRPC;
|
||||
import static io.dapr.it.AppRun.AppProtocol.HTTP;
|
||||
|
||||
public abstract class BaseIT {
|
||||
|
||||
|
@ -52,7 +53,7 @@ public abstract class BaseIT {
|
|||
String testName,
|
||||
String successMessage,
|
||||
Class serviceClass,
|
||||
DaprApiProtocol appProtocol,
|
||||
AppRun.AppProtocol appProtocol,
|
||||
int maxWaitMilliseconds) throws Exception {
|
||||
return startDaprApp(testName, successMessage, serviceClass, true, maxWaitMilliseconds, GRPC, appProtocol);
|
||||
}
|
||||
|
@ -63,7 +64,7 @@ public abstract class BaseIT {
|
|||
Class serviceClass,
|
||||
Boolean useAppPort,
|
||||
int maxWaitMilliseconds,
|
||||
DaprApiProtocol protocol) throws Exception {
|
||||
AppRun.AppProtocol protocol) throws Exception {
|
||||
return startDaprApp(
|
||||
testName,
|
||||
successMessage,
|
||||
|
@ -81,8 +82,8 @@ public abstract class BaseIT {
|
|||
Class serviceClass,
|
||||
Boolean useAppPort,
|
||||
int maxWaitMilliseconds,
|
||||
DaprApiProtocol protocol,
|
||||
DaprApiProtocol appProtocol) throws Exception {
|
||||
AppRun.AppProtocol protocol,
|
||||
AppRun.AppProtocol appProtocol) throws Exception {
|
||||
return startDaprApp(
|
||||
testName,
|
||||
successMessage,
|
||||
|
@ -115,14 +116,13 @@ public abstract class BaseIT {
|
|||
Boolean useAppPort,
|
||||
Boolean useDaprPorts,
|
||||
int maxWaitMilliseconds,
|
||||
DaprApiProtocol protocol,
|
||||
DaprApiProtocol appProtocol) throws Exception {
|
||||
AppRun.AppProtocol protocol,
|
||||
AppRun.AppProtocol appProtocol) throws Exception {
|
||||
DaprRun.Builder builder = new DaprRun.Builder(
|
||||
testName,
|
||||
() -> DaprPorts.build(useAppPort, useDaprPorts, useDaprPorts),
|
||||
successMessage,
|
||||
maxWaitMilliseconds,
|
||||
protocol,
|
||||
appProtocol).withServiceClass(serviceClass);
|
||||
DaprRun run = builder.build();
|
||||
TO_BE_STOPPED.add(run);
|
||||
|
@ -139,7 +139,7 @@ public abstract class BaseIT {
|
|||
Boolean useAppPort,
|
||||
int maxWaitMilliseconds) throws Exception {
|
||||
return startSplitDaprAndApp(
|
||||
testName, successMessage, serviceClass, useAppPort, maxWaitMilliseconds, DaprApiProtocol.GRPC);
|
||||
testName, successMessage, serviceClass, useAppPort, maxWaitMilliseconds, AppRun.AppProtocol.GRPC);
|
||||
}
|
||||
|
||||
protected static ImmutablePair<AppRun, DaprRun> startSplitDaprAndApp(
|
||||
|
@ -148,7 +148,7 @@ public abstract class BaseIT {
|
|||
Class serviceClass,
|
||||
Boolean useAppPort,
|
||||
int maxWaitMilliseconds,
|
||||
DaprApiProtocol protocol) throws Exception {
|
||||
AppRun.AppProtocol protocol) throws Exception {
|
||||
return startSplitDaprAndApp(
|
||||
testName,
|
||||
successMessage,
|
||||
|
@ -165,14 +165,13 @@ public abstract class BaseIT {
|
|||
Class serviceClass,
|
||||
Boolean useAppPort,
|
||||
int maxWaitMilliseconds,
|
||||
DaprApiProtocol protocol,
|
||||
DaprApiProtocol appProtocol) throws Exception {
|
||||
AppRun.AppProtocol protocol,
|
||||
AppRun.AppProtocol appProtocol) throws Exception {
|
||||
DaprRun.Builder builder = new DaprRun.Builder(
|
||||
testName,
|
||||
() -> DaprPorts.build(useAppPort, true, true),
|
||||
successMessage,
|
||||
maxWaitMilliseconds,
|
||||
protocol,
|
||||
appProtocol).withServiceClass(serviceClass);
|
||||
ImmutablePair<AppRun, DaprRun> runs = builder.splitBuild();
|
||||
TO_BE_STOPPED.add(runs.left);
|
||||
|
@ -199,9 +198,21 @@ public abstract class BaseIT {
|
|||
return newActorClient(null);
|
||||
}
|
||||
|
||||
protected static ActorClient newActorClient(ResiliencyOptions resiliencyOptions) {
|
||||
ActorClient client = new ActorClient(resiliencyOptions);
|
||||
TO_BE_CLOSED.add(client);
|
||||
return client;
|
||||
protected static ActorClient newActorClient(ResiliencyOptions resiliencyOptions) throws RuntimeException {
|
||||
try {
|
||||
Constructor<ActorClient> constructor = ActorClient.class.getDeclaredConstructor(ResiliencyOptions.class);
|
||||
constructor.setAccessible(true);
|
||||
ActorClient client = constructor.newInstance(resiliencyOptions);
|
||||
TO_BE_CLOSED.add(client);
|
||||
return client;
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InstantiationException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ limitations under the License.
|
|||
package io.dapr.it;
|
||||
|
||||
import com.google.protobuf.Empty;
|
||||
import io.dapr.client.DaprApiProtocol;
|
||||
import io.dapr.config.Properties;
|
||||
import io.dapr.v1.AppCallbackHealthCheckGrpc;
|
||||
import io.grpc.ManagedChannel;
|
||||
|
@ -42,13 +41,13 @@ public class DaprRun implements Stoppable {
|
|||
|
||||
// the arg in -Dexec.args is the app's port
|
||||
private static final String DAPR_COMMAND =
|
||||
" -- mvn exec:java -D exec.mainClass=%s -D exec.classpathScope=test -D exec.args=\"%s\" -D %s=%s -D %s=%s";
|
||||
" -- mvn exec:java -D exec.mainClass=%s -D exec.classpathScope=test -D exec.args=\"%s\"";
|
||||
|
||||
private final DaprPorts ports;
|
||||
|
||||
private final String appName;
|
||||
|
||||
private final DaprApiProtocol appProtocol;
|
||||
private final AppRun.AppProtocol appProtocol;
|
||||
|
||||
private final int maxWaitMilliseconds;
|
||||
|
||||
|
@ -67,15 +66,14 @@ public class DaprRun implements Stoppable {
|
|||
String successMessage,
|
||||
Class serviceClass,
|
||||
int maxWaitMilliseconds,
|
||||
DaprApiProtocol protocol,
|
||||
DaprApiProtocol appProtocol) {
|
||||
AppRun.AppProtocol appProtocol) {
|
||||
// The app name needs to be deterministic since we depend on it to kill previous runs.
|
||||
this.appName = serviceClass == null ?
|
||||
testName.toLowerCase() :
|
||||
String.format("%s-%s", testName, serviceClass.getSimpleName()).toLowerCase();
|
||||
this.appProtocol = appProtocol;
|
||||
this.startCommand =
|
||||
new Command(successMessage, buildDaprCommand(this.appName, serviceClass, ports, protocol, appProtocol));
|
||||
new Command(successMessage, buildDaprCommand(this.appName, serviceClass, ports, appProtocol));
|
||||
this.listCommand = new Command(
|
||||
this.appName,
|
||||
"dapr list");
|
||||
|
@ -145,29 +143,6 @@ public class DaprRun implements Stoppable {
|
|||
|
||||
public void use() {
|
||||
this.ports.use();
|
||||
System.getProperties().setProperty(Properties.API_PROTOCOL.getName(), DaprApiProtocol.GRPC.name());
|
||||
System.getProperties().setProperty(
|
||||
Properties.API_METHOD_INVOCATION_PROTOCOL.getName(),
|
||||
DaprApiProtocol.GRPC.name());
|
||||
}
|
||||
|
||||
public void switchToGRPC() {
|
||||
System.getProperties().setProperty(Properties.API_PROTOCOL.getName(), DaprApiProtocol.GRPC.name());
|
||||
System.getProperties().setProperty(
|
||||
Properties.API_METHOD_INVOCATION_PROTOCOL.getName(),
|
||||
DaprApiProtocol.GRPC.name());
|
||||
}
|
||||
|
||||
public void switchToHTTP() {
|
||||
System.getProperties().setProperty(Properties.API_PROTOCOL.getName(), DaprApiProtocol.HTTP.name());
|
||||
System.getProperties().setProperty(
|
||||
Properties.API_METHOD_INVOCATION_PROTOCOL.getName(),
|
||||
DaprApiProtocol.HTTP.name());
|
||||
}
|
||||
|
||||
public void switchToProtocol(DaprApiProtocol protocol) {
|
||||
System.getProperties().setProperty(Properties.API_PROTOCOL.getName(), protocol.name());
|
||||
System.getProperties().setProperty(Properties.API_METHOD_INVOCATION_PROTOCOL.getName(), protocol.name());
|
||||
}
|
||||
|
||||
public void waitForAppHealth(int maxWaitMilliseconds) throws InterruptedException {
|
||||
|
@ -175,7 +150,7 @@ public class DaprRun implements Stoppable {
|
|||
return;
|
||||
}
|
||||
|
||||
if (DaprApiProtocol.GRPC.equals(this.appProtocol)) {
|
||||
if (AppRun.AppProtocol.GRPC.equals(this.appProtocol)) {
|
||||
ManagedChannel channel = ManagedChannelBuilder.forAddress("127.0.0.1", this.getAppPort())
|
||||
.usePlaintext()
|
||||
.build();
|
||||
|
@ -263,7 +238,7 @@ public class DaprRun implements Stoppable {
|
|||
}
|
||||
|
||||
private static String buildDaprCommand(
|
||||
String appName, Class serviceClass, DaprPorts ports, DaprApiProtocol protocol, DaprApiProtocol appProtocol) {
|
||||
String appName, Class serviceClass, DaprPorts ports, AppRun.AppProtocol appProtocol) {
|
||||
StringBuilder stringBuilder =
|
||||
new StringBuilder(String.format(DAPR_RUN, appName, appProtocol.toString().toLowerCase()))
|
||||
.append(ports.getAppPort() != null ? " --app-port " + ports.getAppPort() : "")
|
||||
|
@ -273,9 +248,7 @@ public class DaprRun implements Stoppable {
|
|||
" --enable-app-health-check --app-health-probe-interval=1" : "")
|
||||
.append(serviceClass == null ? "" :
|
||||
String.format(DAPR_COMMAND, serviceClass.getCanonicalName(),
|
||||
ports.getAppPort() != null ? ports.getAppPort().toString() : "",
|
||||
Properties.API_PROTOCOL.getName(), protocol,
|
||||
Properties.API_METHOD_INVOCATION_PROTOCOL.getName(), protocol));
|
||||
ports.getAppPort() != null ? ports.getAppPort().toString() : ""));
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
|
@ -315,22 +288,18 @@ public class DaprRun implements Stoppable {
|
|||
|
||||
private Class serviceClass;
|
||||
|
||||
private DaprApiProtocol protocol;
|
||||
|
||||
private DaprApiProtocol appProtocol;
|
||||
private AppRun.AppProtocol appProtocol;
|
||||
|
||||
Builder(
|
||||
String testName,
|
||||
Supplier<DaprPorts> portsSupplier,
|
||||
String successMessage,
|
||||
int maxWaitMilliseconds,
|
||||
DaprApiProtocol protocol,
|
||||
DaprApiProtocol appProtocol) {
|
||||
AppRun.AppProtocol appProtocol) {
|
||||
this.testName = testName;
|
||||
this.portsSupplier = portsSupplier;
|
||||
this.successMessage = successMessage;
|
||||
this.maxWaitMilliseconds = maxWaitMilliseconds;
|
||||
this.protocol = protocol;
|
||||
this.appProtocol = appProtocol;
|
||||
}
|
||||
|
||||
|
@ -346,7 +315,6 @@ public class DaprRun implements Stoppable {
|
|||
this.successMessage,
|
||||
this.serviceClass,
|
||||
this.maxWaitMilliseconds,
|
||||
this.protocol,
|
||||
this.appProtocol);
|
||||
}
|
||||
|
||||
|
@ -360,8 +328,7 @@ public class DaprRun implements Stoppable {
|
|||
ports,
|
||||
this.successMessage,
|
||||
this.serviceClass,
|
||||
this.maxWaitMilliseconds,
|
||||
this.protocol);
|
||||
this.maxWaitMilliseconds);
|
||||
|
||||
DaprRun daprRun = new DaprRun(
|
||||
this.testName,
|
||||
|
@ -369,7 +336,6 @@ public class DaprRun implements Stoppable {
|
|||
DAPR_SUCCESS_MESSAGE,
|
||||
null,
|
||||
this.maxWaitMilliseconds,
|
||||
this.protocol,
|
||||
this.appProtocol);
|
||||
|
||||
return new ImmutablePair<>(appRun, daprRun);
|
||||
|
|
|
@ -22,22 +22,24 @@ import io.dapr.it.DaprRun;
|
|||
import io.dapr.it.actors.app.ActorReminderDataParam;
|
||||
import io.dapr.it.actors.app.MyActorService;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.junit.Before;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static io.dapr.it.Retry.callWithRetry;
|
||||
import static io.dapr.it.actors.MyActorTestUtils.*;
|
||||
import static io.dapr.it.actors.MyActorTestUtils.countMethodCalls;
|
||||
import static io.dapr.it.actors.MyActorTestUtils.fetchMethodCallLogs;
|
||||
import static io.dapr.it.actors.MyActorTestUtils.validateMessageContent;
|
||||
import static io.dapr.it.actors.MyActorTestUtils.validateMethodCalls;
|
||||
|
||||
public class ActorReminderRecoveryIT extends BaseIT {
|
||||
|
||||
|
|
|
@ -75,10 +75,6 @@ public class ActorSdkResiliencytIT extends BaseIT {
|
|||
true,
|
||||
60000);
|
||||
|
||||
ActorId actorId = new ActorId(UUID.randomUUID().toString());
|
||||
|
||||
// HTTP client is deprecated, so SDK resiliency is for gRPC client only.
|
||||
daprRun.switchToGRPC();
|
||||
demoActor = buildDemoActorProxy(null);
|
||||
daprClient = new DaprClientBuilder().build();
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ package io.dapr.it.actors;
|
|||
import io.dapr.actors.ActorId;
|
||||
import io.dapr.actors.client.ActorProxy;
|
||||
import io.dapr.actors.client.ActorProxyBuilder;
|
||||
import io.dapr.client.DaprApiProtocol;
|
||||
import io.dapr.it.AppRun;
|
||||
import io.dapr.it.BaseIT;
|
||||
import io.dapr.it.DaprRun;
|
||||
import io.dapr.it.actors.services.springboot.StatefulActor;
|
||||
|
@ -45,16 +45,14 @@ public class ActorStateIT extends BaseIT {
|
|||
*/
|
||||
public static Stream<Arguments> data() {
|
||||
return Stream.of(
|
||||
Arguments.of(DaprApiProtocol.HTTP, DaprApiProtocol.HTTP ),
|
||||
Arguments.of(DaprApiProtocol.HTTP, DaprApiProtocol.GRPC ),
|
||||
Arguments.of(DaprApiProtocol.GRPC, DaprApiProtocol.HTTP ),
|
||||
Arguments.of(DaprApiProtocol.GRPC, DaprApiProtocol.GRPC )
|
||||
Arguments.of(AppRun.AppProtocol.HTTP ),
|
||||
Arguments.of(AppRun.AppProtocol.GRPC )
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void writeReadState(DaprApiProtocol daprClientProtocol, DaprApiProtocol serviceAppProtocol) throws Exception {
|
||||
public void writeReadState(AppRun.AppProtocol serviceAppProtocol) throws Exception {
|
||||
logger.debug("Starting actor runtime ...");
|
||||
// The call below will fail if service cannot start successfully.
|
||||
DaprRun runtime = startDaprApp(
|
||||
|
@ -65,13 +63,11 @@ public class ActorStateIT extends BaseIT {
|
|||
60000,
|
||||
serviceAppProtocol);
|
||||
|
||||
runtime.switchToProtocol(daprClientProtocol);
|
||||
|
||||
String message = "This is a message to be saved and retrieved.";
|
||||
String name = "Jon Doe";
|
||||
byte[] bytes = new byte[] { 0x1 };
|
||||
ActorId actorId = new ActorId(
|
||||
String.format("%d-%b-%b", System.currentTimeMillis(), daprClientProtocol, serviceAppProtocol));
|
||||
String.format("%d-%b", System.currentTimeMillis(), serviceAppProtocol));
|
||||
String actorType = "StatefulActorTest";
|
||||
logger.debug("Building proxy ...");
|
||||
ActorProxyBuilder<ActorProxy> proxyBuilder =
|
||||
|
@ -161,8 +157,6 @@ public class ActorStateIT extends BaseIT {
|
|||
60000,
|
||||
serviceAppProtocol);
|
||||
|
||||
runtime.switchToProtocol(daprClientProtocol);
|
||||
|
||||
// Need new proxy builder because the proxy builder holds the channel.
|
||||
proxyBuilder = new ActorProxyBuilder(actorType, ActorProxy.class, newActorClient());
|
||||
ActorProxy newProxy = proxyBuilder.build(actorId);
|
||||
|
|
|
@ -20,7 +20,9 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Utility class for tests that use MyActor class.
|
||||
|
|
|
@ -24,7 +24,13 @@ import reactor.core.publisher.Mono;
|
|||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.TimeZone;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class MyActorBase<T> extends AbstractActor implements MyActor, Remindable<T> {
|
||||
|
|
|
@ -4,34 +4,19 @@ import io.dapr.client.DaprClient;
|
|||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.it.BaseIT;
|
||||
import io.dapr.it.DaprRun;
|
||||
import io.dapr.it.actors.ActorReminderRecoveryIT;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
public class ApiIT extends BaseIT {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ApiIT.class);
|
||||
private static final int DEFAULT_TIMEOUT = 60000;
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testShutdownAPI(boolean useGrpc) throws Exception {
|
||||
@Test
|
||||
public void testShutdownAPI() throws Exception {
|
||||
DaprRun run = startDaprApp(this.getClass().getSimpleName(), DEFAULT_TIMEOUT);
|
||||
|
||||
if (useGrpc) {
|
||||
run.switchToGRPC();
|
||||
} else {
|
||||
run.switchToHTTP();
|
||||
}
|
||||
|
||||
// TODO(artursouza): change this to wait for the sidecar to be healthy (new method needed in DaprClient).
|
||||
Thread.sleep(3000);
|
||||
try (DaprClient client = new DaprClientBuilder().build()) {
|
||||
|
|
|
@ -20,8 +20,6 @@ import io.dapr.client.domain.HttpExtension;
|
|||
import io.dapr.it.BaseIT;
|
||||
import io.dapr.it.DaprRun;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -46,24 +44,14 @@ public class BindingIT extends BaseIT {
|
|||
public String message;
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void inputOutputBinding(boolean useGrpc) throws Exception {
|
||||
System.out.println("Working Directory = " + System.getProperty("user.dir"));
|
||||
String serviceNameVariant = useGrpc ? "-grpc" : "-http";
|
||||
|
||||
@Test
|
||||
public void inputOutputBinding() throws Exception {
|
||||
DaprRun daprRun = startDaprApp(
|
||||
this.getClass().getSimpleName() + serviceNameVariant,
|
||||
this.getClass().getSimpleName() + "-grpc",
|
||||
InputBindingService.SUCCESS_MESSAGE,
|
||||
InputBindingService.class,
|
||||
true,
|
||||
60000);
|
||||
// At this point, it is guaranteed that the service above is running and all ports being listened to.
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
daprRun.switchToHTTP();
|
||||
}
|
||||
|
||||
try(DaprClient client = new DaprClientBuilder().build()) {
|
||||
callWithRetry(() -> {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package io.dapr.it.configuration.grpc;
|
||||
package io.dapr.it.configuration;
|
||||
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
|
@ -20,7 +20,6 @@ import io.dapr.client.domain.SubscribeConfigurationResponse;
|
|||
import io.dapr.client.domain.UnsubscribeConfigurationResponse;
|
||||
import io.dapr.it.BaseIT;
|
||||
import io.dapr.it.DaprRun;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@ -29,10 +28,14 @@ import reactor.core.Disposable;
|
|||
import reactor.core.publisher.Flux;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class ConfigurationClientIT extends BaseIT {
|
||||
|
||||
|
@ -65,7 +68,6 @@ public class ConfigurationClientIT extends BaseIT {
|
|||
@BeforeAll
|
||||
public static void init() throws Exception {
|
||||
daprRun = startDaprApp(ConfigurationClientIT.class.getSimpleName(), 5000);
|
||||
daprRun.switchToGRPC();
|
||||
daprClient = new DaprClientBuilder().build();
|
||||
}
|
||||
|
||||
|
@ -198,6 +200,9 @@ public class ConfigurationClientIT extends BaseIT {
|
|||
try {
|
||||
process = processBuilder.start();
|
||||
process.waitFor();
|
||||
if (process.exitValue() != 0) {
|
||||
throw new RuntimeException("Not zero exit code for Redis command: " + process.exitValue());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
* 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.http;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.dapr.client.domain.ConfigurationItem;
|
||||
import io.dapr.client.domain.SubscribeConfigurationResponse;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Spring boot Controller class for api endpoints.
|
||||
*/
|
||||
@RestController
|
||||
public class ConfigSubscriberController {
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
|
||||
/**
|
||||
* Api mapping for subscribe configuration.
|
||||
* @param pathVarsMap Path variables for post call
|
||||
* @param obj request Body
|
||||
* @return Returns void
|
||||
*/
|
||||
@PostMapping(path = "/configuration/{configStore}/{key}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public Mono<Void> handleMessage(
|
||||
@PathVariable Map<String, String> pathVarsMap,
|
||||
@RequestBody SubscribeConfigurationResponse obj) {
|
||||
return Mono.fromRunnable(
|
||||
() -> {
|
||||
try {
|
||||
Map<String, ConfigurationItem> items = obj.getItems();
|
||||
for (Map.Entry<String, ConfigurationItem> entry : items.entrySet()) {
|
||||
System.out.println(entry.getValue().getValue() + " : key ->" + entry.getKey());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping(path = "/health")
|
||||
public void health() {
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
package io.dapr.it.configuration.http;
|
||||
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.client.domain.ConfigurationItem;
|
||||
import io.dapr.it.BaseIT;
|
||||
import io.dapr.it.DaprRun;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class ConfigurationIT extends BaseIT {
|
||||
private static final String CONFIG_STORE_NAME = "redisconfigstore";
|
||||
|
||||
private static DaprRun daprRun;
|
||||
|
||||
private static DaprClient daprClient;
|
||||
|
||||
private static String key = "myconfig1";
|
||||
|
||||
private static List<String> 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"
|
||||
};
|
||||
|
||||
@BeforeAll
|
||||
public static void init() throws Exception {
|
||||
daprRun = startDaprApp(ConfigurationIT.class.getSimpleName(), 5000);
|
||||
daprRun.switchToHTTP();
|
||||
daprClient = new DaprClientBuilder().build();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDown() throws Exception {
|
||||
daprClient.close();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setupConfigStore() {
|
||||
executeDockerCommand(insertCmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfiguration() {
|
||||
ConfigurationItem ci = daprClient.getConfiguration(CONFIG_STORE_NAME, "myconfigkey1").block();
|
||||
assertEquals(ci.getKey(), "myconfigkey1");
|
||||
assertEquals(ci.getValue(), "myconfigvalue1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfigurations() {
|
||||
Map<String, ConfigurationItem> cis = daprClient.getConfiguration(CONFIG_STORE_NAME, "myconfigkey1", "myconfigkey2").block();
|
||||
assertTrue(cis.size() == 2);
|
||||
assertTrue(cis.containsKey("myconfigkey1"));
|
||||
assertTrue(cis.containsKey("myconfigkey2"));
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
package io.dapr.it.configuration.http;
|
||||
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.client.domain.SubscribeConfigurationResponse;
|
||||
import io.dapr.client.domain.UnsubscribeConfigurationResponse;
|
||||
import io.dapr.it.BaseIT;
|
||||
import io.dapr.it.DaprRun;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class ConfigurationSubscribeIT extends BaseIT {
|
||||
private static final String CONFIG_STORE_NAME = "redisconfigstore";
|
||||
|
||||
private static DaprRun daprRun;
|
||||
|
||||
private static DaprClient daprClient;
|
||||
|
||||
private static String key = "myconfig1";
|
||||
|
||||
private static List<String> 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"
|
||||
};
|
||||
|
||||
@BeforeAll
|
||||
public static void init() throws Exception {
|
||||
daprRun = startDaprApp(
|
||||
ConfigurationIT.class.getSimpleName(),
|
||||
ConfigurationSubscriberService.SUCCESS_MESSAGE,
|
||||
ConfigurationSubscriberService.class,
|
||||
true,
|
||||
60000);
|
||||
daprRun.switchToHTTP();
|
||||
daprClient = new DaprClientBuilder().build();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDown() throws Exception {
|
||||
daprClient.close();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setupConfigStore() {
|
||||
executeDockerCommand(insertCmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subscribeAndUnsubscribeConfiguration() {
|
||||
AtomicReference<String> subId= new AtomicReference<>("");
|
||||
Flux<SubscribeConfigurationResponse> outFlux = daprClient
|
||||
.subscribeConfiguration(CONFIG_STORE_NAME, "myconfigkey1", "myconfigkey2");
|
||||
outFlux.subscribe(items -> {
|
||||
subId.set(items.getSubscriptionId());
|
||||
});
|
||||
assertTrue(subId.get().length() > 0);
|
||||
|
||||
UnsubscribeConfigurationResponse res = daprClient.unsubscribeConfiguration(
|
||||
subId.get(),
|
||||
CONFIG_STORE_NAME
|
||||
).block();
|
||||
assertTrue(res.getIsUnsubscribed());
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
* 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.http;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* Service for ConfigurationSubscriber.
|
||||
* dapr run --components-path ./components/configuration --app-id configsubscriber --app-port 3000 -- \
|
||||
* java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.configuration.http.ConfigurationSubscriber -p 3000
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class ConfigurationSubscriberService {
|
||||
|
||||
public static final String SUCCESS_MESSAGE = "dapr initialized. Status: Running";
|
||||
|
||||
/**
|
||||
* This is entry point for Configuration Subscriber service.
|
||||
* @param args Arguments for main
|
||||
* @throws Exception Throws Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
int port = Integer.parseInt(args[0]);
|
||||
|
||||
System.out.printf("Service starting on port %d ...\n", port);
|
||||
|
||||
// Start Dapr's callback endpoint.
|
||||
start(port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts Dapr's callback in a given port.
|
||||
*
|
||||
* @param port Port to listen to.
|
||||
*/
|
||||
private static void start(int port) {
|
||||
SpringApplication app = new SpringApplication(ConfigurationSubscriberService.class);
|
||||
app.run(String.format("--server.port=%d", port));
|
||||
}
|
||||
}
|
|
@ -1,12 +1,14 @@
|
|||
package io.dapr.it.methodinvoke.grpc;
|
||||
|
||||
import io.dapr.client.DaprApiProtocol;
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.client.domain.HttpExtension;
|
||||
import io.dapr.exceptions.DaprException;
|
||||
import io.dapr.client.resiliency.ResiliencyOptions;
|
||||
import io.dapr.it.AppRun;
|
||||
import io.dapr.it.BaseIT;
|
||||
import io.dapr.it.DaprRun;
|
||||
import io.dapr.it.MethodInvokeServiceGrpc;
|
||||
import io.grpc.Status;
|
||||
import io.grpc.StatusRuntimeException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -15,7 +17,6 @@ import java.util.Map;
|
|||
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.DeleteMessageRequest;
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.GetMessagesRequest;
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.GetMessagesResponse;
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.PostMessageRequest;
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.SleepRequest;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
@ -38,15 +39,17 @@ public class MethodInvokeIT extends BaseIT {
|
|||
MethodInvokeIT.class.getSimpleName() + "grpc",
|
||||
MethodInvokeService.SUCCESS_MESSAGE,
|
||||
MethodInvokeService.class,
|
||||
DaprApiProtocol.GRPC, // appProtocol
|
||||
AppRun.AppProtocol.GRPC, // appProtocol
|
||||
60000);
|
||||
daprRun.switchToGRPC();
|
||||
daprRun.waitForAppHealth(40000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvoke() throws Exception {
|
||||
try (DaprClient client = new DaprClientBuilder().build()) {
|
||||
MethodInvokeServiceGrpc.MethodInvokeServiceBlockingStub stub = client.newGrpcStub(
|
||||
daprRun.getAppName(),
|
||||
channel -> MethodInvokeServiceGrpc.newBlockingStub(channel));
|
||||
client.waitForSidecar(10000).block();
|
||||
daprRun.waitForAppHealth(10000);
|
||||
|
||||
|
@ -54,59 +57,43 @@ public class MethodInvokeIT extends BaseIT {
|
|||
String message = String.format("This is message #%d", i);
|
||||
|
||||
PostMessageRequest req = PostMessageRequest.newBuilder().setId(i).setMessage(message).build();
|
||||
client.invokeMethod(daprRun.getAppName(), "postMessage", req, HttpExtension.POST).block();
|
||||
stub.postMessage(req);
|
||||
|
||||
System.out.println("Invoke method messages : " + message);
|
||||
}
|
||||
|
||||
Map<Integer, String> messages = client.invokeMethod(
|
||||
daprRun.getAppName(),
|
||||
"getMessages",
|
||||
GetMessagesRequest.newBuilder().build(),
|
||||
HttpExtension.POST, GetMessagesResponse.class).block().getMessagesMap();
|
||||
Map<Integer, String> messages = stub.getMessages(GetMessagesRequest.newBuilder().build()).getMessagesMap();
|
||||
assertEquals(10, messages.size());
|
||||
|
||||
// Delete one message.
|
||||
client.invokeMethod(
|
||||
daprRun.getAppName(),
|
||||
"deleteMessage",
|
||||
DeleteMessageRequest.newBuilder().setId(1).build(),
|
||||
HttpExtension.POST).block();
|
||||
messages = client.invokeMethod(
|
||||
daprRun.getAppName(),
|
||||
"getMessages",
|
||||
GetMessagesRequest.newBuilder().build(),
|
||||
HttpExtension.POST, GetMessagesResponse.class).block().getMessagesMap();
|
||||
stub.deleteMessage(DeleteMessageRequest.newBuilder().setId(1).build());
|
||||
messages = stub.getMessages(GetMessagesRequest.newBuilder().build()).getMessagesMap();
|
||||
assertEquals(9, messages.size());
|
||||
|
||||
// Now update one message.
|
||||
client.invokeMethod(
|
||||
daprRun.getAppName(),
|
||||
"postMessage",
|
||||
PostMessageRequest.newBuilder().setId(2).setMessage("updated message").build(),
|
||||
HttpExtension.POST).block();
|
||||
messages = client.invokeMethod(
|
||||
daprRun.getAppName(),
|
||||
"getMessages",
|
||||
GetMessagesRequest.newBuilder().build(),
|
||||
HttpExtension.POST, GetMessagesResponse.class).block().getMessagesMap();
|
||||
stub.postMessage(PostMessageRequest.newBuilder().setId(2).setMessage("updated message").build());
|
||||
messages = stub.getMessages(GetMessagesRequest.newBuilder().build()).getMessagesMap();
|
||||
assertEquals("updated message", messages.get(2));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvokeTimeout() throws Exception {
|
||||
try (DaprClient client = new DaprClientBuilder().build()) {
|
||||
long timeoutMs = 100;
|
||||
ResiliencyOptions resiliencyOptions = new ResiliencyOptions().setTimeout(Duration.ofMillis(timeoutMs));
|
||||
try (DaprClient client = new DaprClientBuilder().withResiliencyOptions(resiliencyOptions).build()) {
|
||||
MethodInvokeServiceGrpc.MethodInvokeServiceBlockingStub stub = client.newGrpcStub(
|
||||
daprRun.getAppName(),
|
||||
channel -> MethodInvokeServiceGrpc.newBlockingStub(channel));
|
||||
client.waitForSidecar(10000).block();
|
||||
daprRun.waitForAppHealth(10000);
|
||||
|
||||
long started = System.currentTimeMillis();
|
||||
SleepRequest req = SleepRequest.newBuilder().setSeconds(1).build();
|
||||
String message = assertThrows(IllegalStateException.class, () ->
|
||||
client.invokeMethod(daprRun.getAppName(), "sleep", req.toByteArray(), HttpExtension.POST)
|
||||
.block(Duration.ofMillis(10))).getMessage();
|
||||
String message = assertThrows(StatusRuntimeException.class, () -> stub.sleep(req)).getMessage();
|
||||
long delay = System.currentTimeMillis() - started;
|
||||
assertTrue(delay <= 500); // 500 ms is a reasonable delay if the request timed out.
|
||||
assertEquals("Timeout on blocking read for 10000000 NANOSECONDS", message);
|
||||
assertTrue(delay >= timeoutMs);
|
||||
assertTrue(message.startsWith("DEADLINE_EXCEEDED: deadline exceeded after"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,17 +102,20 @@ public class MethodInvokeIT extends BaseIT {
|
|||
try (DaprClient client = new DaprClientBuilder().build()) {
|
||||
client.waitForSidecar(10000).block();
|
||||
daprRun.waitForAppHealth(10000);
|
||||
|
||||
|
||||
MethodInvokeServiceGrpc.MethodInvokeServiceBlockingStub stub = client.newGrpcStub(
|
||||
daprRun.getAppName(),
|
||||
channel -> MethodInvokeServiceGrpc.newBlockingStub(channel));
|
||||
|
||||
SleepRequest req = SleepRequest.newBuilder().setSeconds(-9).build();
|
||||
DaprException exception = assertThrows(DaprException.class, () ->
|
||||
client.invokeMethod(daprRun.getAppName(), "sleep", req.toByteArray(), HttpExtension.POST).block());
|
||||
StatusRuntimeException exception = assertThrows(StatusRuntimeException.class, () -> stub.sleep(req));
|
||||
|
||||
// The error messages should be improved once runtime has standardized error serialization in the API.
|
||||
// This message is not ideal but last time it was improved, there was side effects reported by users.
|
||||
// If this test fails, there might be a regression in runtime (like we had in 1.10.0).
|
||||
// The expectations below are as per 1.9 release and (later on) hotfixed in 1.10.
|
||||
assertEquals("UNKNOWN", exception.getErrorCode());
|
||||
assertEquals("UNKNOWN: ", exception.getMessage());
|
||||
assertEquals(Status.UNKNOWN.getCode(), exception.getStatus().getCode());
|
||||
assertEquals("", exception.getStatus().getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,26 +13,18 @@ limitations under the License.
|
|||
|
||||
package io.dapr.it.methodinvoke.grpc;
|
||||
|
||||
import com.google.protobuf.Any;
|
||||
import io.dapr.grpc.GrpcHealthCheckService;
|
||||
import io.dapr.it.DaprRunConfig;
|
||||
import io.dapr.v1.AppCallbackGrpc;
|
||||
import io.dapr.v1.CommonProtos;
|
||||
import io.dapr.it.MethodInvokeServiceGrpc;
|
||||
import io.grpc.Server;
|
||||
import io.grpc.ServerBuilder;
|
||||
import io.grpc.stub.StreamObserver;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.DeleteMessageRequest;
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.DeleteMessageResponse;
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.GetMessagesRequest;
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.GetMessagesResponse;
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.PostMessageRequest;
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.PostMessageResponse;
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.SleepRequest;
|
||||
import static io.dapr.it.MethodInvokeServiceProtos.SleepResponse;
|
||||
|
||||
|
@ -48,7 +40,7 @@ public class MethodInvokeService {
|
|||
/**
|
||||
* Server mode: class that encapsulates all server-side logic for Grpc.
|
||||
*/
|
||||
private static class MyDaprService extends AppCallbackGrpc.AppCallbackImplBase {
|
||||
private static class MyDaprService extends MethodInvokeServiceGrpc.MethodInvokeServiceImplBase {
|
||||
|
||||
private final Map<Integer, String> messages = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
|
@ -92,57 +84,55 @@ public class MethodInvokeService {
|
|||
}
|
||||
|
||||
/**
|
||||
* Server mode: this is the Dapr method to receive Invoke operations via Grpc.
|
||||
*
|
||||
* @param request Dapr envelope request,
|
||||
* @param responseObserver Dapr envelope response.
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void onInvoke(CommonProtos.InvokeRequest request,
|
||||
StreamObserver<CommonProtos.InvokeResponse> responseObserver) {
|
||||
System.out.println("Server: received " + request.getMethod() + " ...");
|
||||
try {
|
||||
if ("postMessage".equals(request.getMethod())) {
|
||||
PostMessageRequest req = PostMessageRequest.parseFrom(request.getData().getValue().toByteArray());
|
||||
public void postMessage(io.dapr.it.MethodInvokeServiceProtos.PostMessageRequest request,
|
||||
io.grpc.stub.StreamObserver<io.dapr.it.MethodInvokeServiceProtos.PostMessageResponse> responseObserver) {
|
||||
this.messages.put(request.getId(), request.getMessage());
|
||||
|
||||
this.messages.put(req.getId(), req.getMessage());
|
||||
io.dapr.it.MethodInvokeServiceProtos.PostMessageResponse.Builder responseBuilder =
|
||||
io.dapr.it.MethodInvokeServiceProtos.PostMessageResponse.newBuilder();
|
||||
responseObserver.onNext(responseBuilder.build());
|
||||
responseObserver.onCompleted();
|
||||
}
|
||||
|
||||
CommonProtos.InvokeResponse.Builder responseBuilder = CommonProtos.InvokeResponse.newBuilder();
|
||||
responseBuilder.setData(Any.pack(PostMessageResponse.newBuilder().build()));
|
||||
responseObserver.onNext(responseBuilder.build());
|
||||
}
|
||||
if ("deleteMessage".equals(request.getMethod())) {
|
||||
DeleteMessageRequest req = DeleteMessageRequest.parseFrom(request.getData().getValue().toByteArray());
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void deleteMessage(io.dapr.it.MethodInvokeServiceProtos.DeleteMessageRequest request,
|
||||
io.grpc.stub.StreamObserver<io.dapr.it.MethodInvokeServiceProtos.DeleteMessageResponse> responseObserver) {
|
||||
this.messages.remove(request.getId());
|
||||
|
||||
this.messages.remove(req.getId());
|
||||
io.dapr.it.MethodInvokeServiceProtos.DeleteMessageResponse.Builder responseBuilder =
|
||||
io.dapr.it.MethodInvokeServiceProtos.DeleteMessageResponse.newBuilder();
|
||||
responseObserver.onNext(responseBuilder.build());
|
||||
responseObserver.onCompleted();
|
||||
}
|
||||
|
||||
CommonProtos.InvokeResponse.Builder responseBuilder = CommonProtos.InvokeResponse.newBuilder();
|
||||
responseBuilder.setData(Any.pack(DeleteMessageResponse.newBuilder().build()));
|
||||
responseObserver.onNext(responseBuilder.build());
|
||||
}
|
||||
if ("getMessages".equals(request.getMethod())) {
|
||||
GetMessagesRequest.parseFrom(request.getData().getValue().toByteArray());
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void getMessages(io.dapr.it.MethodInvokeServiceProtos.GetMessagesRequest request,
|
||||
io.grpc.stub.StreamObserver<io.dapr.it.MethodInvokeServiceProtos.GetMessagesResponse> responseObserver) {
|
||||
GetMessagesResponse res = GetMessagesResponse.newBuilder().putAllMessages(this.messages).build();
|
||||
|
||||
GetMessagesResponse res = GetMessagesResponse.newBuilder().putAllMessages(this.messages).build();
|
||||
io.dapr.it.MethodInvokeServiceProtos.GetMessagesResponse.Builder responseBuilder
|
||||
= io.dapr.it.MethodInvokeServiceProtos.GetMessagesResponse.newBuilder();
|
||||
responseObserver.onNext(res);
|
||||
responseObserver.onCompleted();
|
||||
}
|
||||
|
||||
CommonProtos.InvokeResponse.Builder responseBuilder = CommonProtos.InvokeResponse.newBuilder();
|
||||
responseBuilder.setData(Any.pack(res));
|
||||
responseObserver.onNext(responseBuilder.build());
|
||||
}
|
||||
if ("sleep".equals(request.getMethod())) {
|
||||
SleepRequest req = SleepRequest.parseFrom(request.getData().getValue().toByteArray());
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sleep(io.dapr.it.MethodInvokeServiceProtos.SleepRequest request,
|
||||
io.grpc.stub.StreamObserver<io.dapr.it.MethodInvokeServiceProtos.SleepResponse> responseObserver) {
|
||||
SleepResponse res = this.sleep(request);
|
||||
|
||||
SleepResponse res = this.sleep(req);
|
||||
|
||||
CommonProtos.InvokeResponse.Builder responseBuilder = CommonProtos.InvokeResponse.newBuilder();
|
||||
responseBuilder.setData(Any.pack(res));
|
||||
responseObserver.onNext(responseBuilder.build());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
responseObserver.onError(e);
|
||||
} finally {
|
||||
responseObserver.onCompleted();
|
||||
}
|
||||
io.dapr.it.MethodInvokeServiceProtos.SleepResponse.Builder responseBuilder =
|
||||
io.dapr.it.MethodInvokeServiceProtos.SleepResponse.newBuilder();
|
||||
responseObserver.onNext(responseBuilder.build());
|
||||
responseObserver.onCompleted();
|
||||
}
|
||||
|
||||
public SleepResponse sleep(SleepRequest request) {
|
||||
|
|
|
@ -40,7 +40,6 @@ public class MethodInvokeIT extends BaseIT {
|
|||
MethodInvokeService.class,
|
||||
true,
|
||||
30000);
|
||||
daprRun.switchToHTTP();
|
||||
daprRun.waitForAppHealth(20000);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,7 @@ import io.dapr.serializer.DaprObjectSerializer;
|
|||
import io.dapr.utils.TypeRef;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -99,49 +98,26 @@ public class PubSubIT extends BaseIT {
|
|||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void publishPubSubNotFound(boolean useGrpc) throws Exception {
|
||||
@Test
|
||||
public void publishPubSubNotFound() throws Exception {
|
||||
DaprRun daprRun = closeLater(startDaprApp(
|
||||
this.getClass().getSimpleName(),
|
||||
60000));
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
daprRun.switchToHTTP();
|
||||
}
|
||||
|
||||
try (DaprClient client = new DaprClientBuilder().build()) {
|
||||
|
||||
if (useGrpc) {
|
||||
assertThrowsDaprExceptionWithReason(
|
||||
"INVALID_ARGUMENT",
|
||||
"INVALID_ARGUMENT: pubsub unknown pubsub is not found",
|
||||
"DAPR_PUBSUB_NOT_FOUND",
|
||||
() -> client.publishEvent("unknown pubsub", "mytopic", "payload").block());
|
||||
} else {
|
||||
assertThrowsDaprExceptionWithReason(
|
||||
"ERR_PUBSUB_NOT_FOUND",
|
||||
"ERR_PUBSUB_NOT_FOUND: pubsub unknown pubsub is not found",
|
||||
"DAPR_PUBSUB_NOT_FOUND",
|
||||
() -> client.publishEvent("unknown pubsub", "mytopic", "payload").block());
|
||||
}
|
||||
assertThrowsDaprExceptionWithReason(
|
||||
"INVALID_ARGUMENT",
|
||||
"INVALID_ARGUMENT: pubsub unknown pubsub is not found",
|
||||
"DAPR_PUBSUB_NOT_FOUND",
|
||||
() -> client.publishEvent("unknown pubsub", "mytopic", "payload").block());
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testBulkPublishPubSubNotFound(boolean useGrpc) throws Exception {
|
||||
@Test
|
||||
public void testBulkPublishPubSubNotFound() throws Exception {
|
||||
DaprRun daprRun = closeLater(startDaprApp(
|
||||
this.getClass().getSimpleName(),
|
||||
60000));
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
// No HTTP implementation for bulk publish
|
||||
System.out.println("no HTTP impl for bulkPublish");
|
||||
return;
|
||||
}
|
||||
|
||||
try (DaprPreviewClient client = new DaprClientBuilder().buildPreviewClient()) {
|
||||
assertThrowsDaprException(
|
||||
|
@ -151,22 +127,14 @@ public class PubSubIT extends BaseIT {
|
|||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testBulkPublish(boolean useGrpc) throws Exception {
|
||||
@Test
|
||||
public void testBulkPublish() throws Exception {
|
||||
final DaprRun daprRun = closeLater(startDaprApp(
|
||||
this.getClass().getSimpleName(),
|
||||
SubscriberService.SUCCESS_MESSAGE,
|
||||
SubscriberService.class,
|
||||
true,
|
||||
60000));
|
||||
// At this point, it is guaranteed that the service above is running and all ports being listened to.
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
System.out.println("HTTP BulkPublish is not implemented. So skipping tests");
|
||||
return;
|
||||
}
|
||||
DaprObjectSerializer serializer = new DaprObjectSerializer() {
|
||||
@Override
|
||||
public byte[] serialize(Object o) throws JsonProcessingException {
|
||||
|
@ -287,21 +255,14 @@ public class PubSubIT extends BaseIT {
|
|||
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testPubSub(boolean useGrpc) throws Exception {
|
||||
@Test
|
||||
public void testPubSub() throws Exception {
|
||||
final DaprRun daprRun = closeLater(startDaprApp(
|
||||
this.getClass().getSimpleName(),
|
||||
SubscriberService.SUCCESS_MESSAGE,
|
||||
SubscriberService.class,
|
||||
true,
|
||||
60000));
|
||||
// At this point, it is guaranteed that the service above is running and all ports being listened to.
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
daprRun.switchToHTTP();
|
||||
}
|
||||
|
||||
DaprObjectSerializer serializer = new DaprObjectSerializer() {
|
||||
@Override
|
||||
|
@ -508,21 +469,14 @@ public class PubSubIT extends BaseIT {
|
|||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testPubSubBinary(boolean useGrpc) throws Exception {
|
||||
@Test
|
||||
public void testPubSubBinary() throws Exception {
|
||||
final DaprRun daprRun = closeLater(startDaprApp(
|
||||
this.getClass().getSimpleName(),
|
||||
SubscriberService.SUCCESS_MESSAGE,
|
||||
SubscriberService.class,
|
||||
true,
|
||||
60000));
|
||||
// At this point, it is guaranteed that the service above is running and all ports being listened to.
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
daprRun.switchToHTTP();
|
||||
}
|
||||
|
||||
DaprObjectSerializer serializer = new DaprObjectSerializer() {
|
||||
@Override
|
||||
|
@ -565,17 +519,11 @@ public class PubSubIT extends BaseIT {
|
|||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testPubSubTTLMetadata(boolean useGrpc) throws Exception {
|
||||
@Test
|
||||
public void testPubSubTTLMetadata() throws Exception {
|
||||
DaprRun daprRun = closeLater(startDaprApp(
|
||||
this.getClass().getSimpleName(),
|
||||
60000));
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
daprRun.switchToHTTP();
|
||||
}
|
||||
|
||||
// Send a batch of messages on one topic, all to be expired in 1 second.
|
||||
try (DaprClient client = new DaprClientBuilder().build()) {
|
||||
|
@ -602,11 +550,6 @@ public class PubSubIT extends BaseIT {
|
|||
SubscriberService.class,
|
||||
true,
|
||||
60000));
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
daprRun.switchToHTTP();
|
||||
}
|
||||
|
||||
// Sleeps for five seconds to give subscriber a chance to receive messages.
|
||||
Thread.sleep(5000);
|
||||
|
@ -623,20 +566,14 @@ public class PubSubIT extends BaseIT {
|
|||
daprRun.stop();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testPubSubBulkSubscribe(boolean useGrpc) throws Exception {
|
||||
@Test
|
||||
public void testPubSubBulkSubscribe() throws Exception {
|
||||
DaprRun daprRun = closeLater(startDaprApp(
|
||||
this.getClass().getSimpleName(),
|
||||
SubscriberService.SUCCESS_MESSAGE,
|
||||
SubscriberService.class,
|
||||
true,
|
||||
60000));
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
daprRun.switchToHTTP();
|
||||
}
|
||||
|
||||
// Send a batch of messages on one topic.
|
||||
try (DaprClient client = new DaprClientBuilder().build()) {
|
||||
|
@ -686,21 +623,14 @@ public class PubSubIT extends BaseIT {
|
|||
daprRun.stop();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testLongValues(boolean useGrpc) throws Exception {
|
||||
@Test
|
||||
public void testLongValues() throws Exception {
|
||||
final DaprRun daprRun = closeLater(startDaprApp(
|
||||
this.getClass().getSimpleName(),
|
||||
SubscriberService.SUCCESS_MESSAGE,
|
||||
SubscriberService.class,
|
||||
true,
|
||||
60000));
|
||||
// At this point, it is guaranteed that the service above is running and all ports being listened to.
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
daprRun.switchToHTTP();
|
||||
}
|
||||
|
||||
Random random = new Random(590518626939830271L);
|
||||
Set<ConvertToLong> values = new HashSet<>();
|
||||
|
|
|
@ -15,7 +15,12 @@ package io.dapr.it.pubsub.http;
|
|||
|
||||
import io.dapr.Rule;
|
||||
import io.dapr.Topic;
|
||||
import io.dapr.client.domain.*;
|
||||
import io.dapr.client.domain.BulkSubscribeAppResponse;
|
||||
import io.dapr.client.domain.BulkSubscribeAppResponseEntry;
|
||||
import io.dapr.client.domain.BulkSubscribeAppResponseStatus;
|
||||
import io.dapr.client.domain.BulkSubscribeMessage;
|
||||
import io.dapr.client.domain.BulkSubscribeMessageEntry;
|
||||
import io.dapr.client.domain.CloudEvent;
|
||||
import io.dapr.springboot.annotations.BulkSubscribe;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
|
|
@ -15,7 +15,7 @@ package io.dapr.it.resiliency;
|
|||
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.client.DaprClientGrpc;
|
||||
import io.dapr.client.DaprClientImpl;
|
||||
import io.dapr.client.resiliency.ResiliencyOptions;
|
||||
import io.dapr.it.BaseIT;
|
||||
import io.dapr.it.DaprRun;
|
||||
|
@ -65,8 +65,6 @@ public class SdkResiliencytIT extends BaseIT {
|
|||
@BeforeAll
|
||||
public static void init() throws Exception {
|
||||
daprRun = startDaprApp(SdkResiliencytIT.class.getSimpleName(), 5000);
|
||||
// HTTP client is deprecated, so SDK resiliency is for gRPC client only.
|
||||
daprRun.switchToGRPC();
|
||||
daprClient = new DaprClientBuilder().build();
|
||||
daprClient.waitForSidecar(8000).block();
|
||||
|
||||
|
@ -87,10 +85,10 @@ public class SdkResiliencytIT extends BaseIT {
|
|||
new ResiliencyOptions().setTimeout(TIMEOUT).setMaxRetries(1))
|
||||
.build();
|
||||
|
||||
assertTrue(daprClient instanceof DaprClientGrpc);
|
||||
assertTrue(daprToxiClient instanceof DaprClientGrpc);
|
||||
assertTrue(daprResilientClient instanceof DaprClientGrpc);
|
||||
assertTrue(daprRetriesOnceClient instanceof DaprClientGrpc);
|
||||
assertTrue(daprClient instanceof DaprClientImpl);
|
||||
assertTrue(daprToxiClient instanceof DaprClientImpl);
|
||||
assertTrue(daprResilientClient instanceof DaprClientImpl);
|
||||
assertTrue(daprRetriesOnceClient instanceof DaprClientImpl);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
|
|
@ -19,23 +19,14 @@ import io.dapr.client.DaprClientBuilder;
|
|||
import io.dapr.it.BaseIT;
|
||||
import io.dapr.it.DaprRun;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
@ -82,13 +73,8 @@ public class SecretsClientIT extends BaseIT {
|
|||
daprRun = startDaprApp(SecretsClientIT.class.getSimpleName(), 5000);
|
||||
}
|
||||
|
||||
public void setup(boolean useGrpc) {
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
daprRun.switchToHTTP();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
this.daprClient = new DaprClientBuilder().build();
|
||||
}
|
||||
|
||||
|
@ -98,22 +84,16 @@ public class SecretsClientIT extends BaseIT {
|
|||
clearSecretFile();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void getSecret(boolean useGrpc) throws Exception {
|
||||
setup(useGrpc);
|
||||
|
||||
@Test
|
||||
public void getSecret() throws Exception {
|
||||
Map<String, String> data = daprClient.getSecret(SECRETS_STORE_NAME, KEY1).block();
|
||||
assertEquals(2, data.size());
|
||||
assertEquals("The Metrics IV", data.get("title"));
|
||||
assertEquals("2020", data.get("year"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void getBulkSecret(boolean useGrpc) throws Exception {
|
||||
setup(useGrpc);
|
||||
|
||||
@Test
|
||||
public void getBulkSecret() throws Exception {
|
||||
Map<String, Map<String, String>> data = daprClient.getBulkSecret(SECRETS_STORE_NAME).block();
|
||||
// There can be other keys from other runs or test cases, so we are good with at least two.
|
||||
assertTrue(data.size() >= 2);
|
||||
|
@ -124,19 +104,13 @@ public class SecretsClientIT extends BaseIT {
|
|||
assertEquals("Jon Doe", data.get(KYE2).get("name"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void getSecretKeyNotFound(boolean useGrpc) {
|
||||
setup(useGrpc);
|
||||
|
||||
@Test
|
||||
public void getSecretKeyNotFound() {
|
||||
assertThrows(RuntimeException.class, () -> daprClient.getSecret(SECRETS_STORE_NAME, "unknownKey").block());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void getSecretStoreNotFound(boolean useGrpc) throws Exception {
|
||||
setup(useGrpc);
|
||||
|
||||
@Test
|
||||
public void getSecretStoreNotFound() {
|
||||
assertThrows(RuntimeException.class, () -> daprClient.getSecret("unknownStore", "unknownKey").block());
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ public class GRPCStateClientIT extends AbstractStateClientIT {
|
|||
@BeforeAll
|
||||
public static void init() throws Exception {
|
||||
daprRun = startDaprApp(GRPCStateClientIT.class.getSimpleName(), 5000);
|
||||
daprRun.switchToGRPC();
|
||||
daprClient = new DaprClientBuilder().build();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@ limitations under the License.
|
|||
|
||||
package io.dapr.it.state;
|
||||
|
||||
import io.dapr.config.Properties;
|
||||
import io.dapr.it.BaseIT;
|
||||
import io.dapr.it.DaprRun;
|
||||
import io.dapr.config.Properties;
|
||||
import io.dapr.v1.DaprGrpc;
|
||||
import io.dapr.v1.DaprProtos;
|
||||
import io.grpc.ManagedChannel;
|
||||
|
|
|
@ -1,94 +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.it.state;
|
||||
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.client.DaprClientHttp;
|
||||
import io.dapr.client.domain.State;
|
||||
import io.dapr.it.DaprRun;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static io.dapr.it.TestUtils.assertThrowsDaprException;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Test State HTTP DAPR capabilities using a DAPR instance with an empty service running
|
||||
*/
|
||||
public class HttpStateClientIT extends AbstractStateClientIT {
|
||||
|
||||
private static DaprRun daprRun;
|
||||
|
||||
private static DaprClient daprClient;
|
||||
|
||||
@BeforeAll
|
||||
public static void init() throws Exception {
|
||||
daprRun = startDaprApp(HttpStateClientIT.class.getSimpleName(), 5000);
|
||||
daprRun.switchToHTTP();
|
||||
daprClient = new DaprClientBuilder().build();
|
||||
assertTrue(daprClient instanceof DaprClientHttp);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDown() throws Exception {
|
||||
daprClient.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DaprClient buildDaprClient() {
|
||||
return daprClient;
|
||||
}
|
||||
|
||||
/** Tests where HTTP and GRPC behavior differ in Dapr runtime. **/
|
||||
|
||||
@Test
|
||||
public void getStateStoreNotFound() {
|
||||
final String stateKey = "key";
|
||||
|
||||
DaprClient daprClient = buildDaprClient();
|
||||
|
||||
// DaprException is guaranteed in the Dapr SDK but getCause() is null in HTTP while present in GRPC implementation.
|
||||
assertThrowsDaprException(
|
||||
"ERR_STATE_STORE_NOT_FOUND",
|
||||
"ERR_STATE_STORE_NOT_FOUND: state store unknown state store is not found",
|
||||
() -> daprClient.getState("unknown state store", new State(stateKey), byte[].class).block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getStatesStoreNotFound() {
|
||||
final String stateKey = "key";
|
||||
|
||||
DaprClient daprClient = buildDaprClient();
|
||||
|
||||
// DaprException is guaranteed in the Dapr SDK but getCause() is null in HTTP while present in GRPC implementation.
|
||||
assertThrowsDaprException(
|
||||
"ERR_STATE_STORE_NOT_FOUND",
|
||||
"ERR_STATE_STORE_NOT_FOUND: state store unknown state store is not found",
|
||||
() -> daprClient.getBulkState(
|
||||
"unknown state store",
|
||||
Collections.singletonList(stateKey),
|
||||
byte[].class).block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publishPubSubNotFound() {
|
||||
DaprClient daprClient = buildDaprClient();
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
package io.dapr.it.tracing.grpc;
|
||||
|
||||
import io.dapr.client.DaprApiProtocol;
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.client.domain.HttpExtension;
|
||||
import io.dapr.it.AppRun;
|
||||
import io.dapr.it.BaseIT;
|
||||
import io.dapr.it.DaprRun;
|
||||
import io.dapr.it.tracing.Validation;
|
||||
|
@ -12,8 +12,8 @@ import io.opentelemetry.api.trace.Span;
|
|||
import io.opentelemetry.api.trace.Tracer;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -28,28 +28,20 @@ public class TracingIT extends BaseIT {
|
|||
*/
|
||||
private DaprRun daprRun = null;
|
||||
|
||||
public void setup(boolean useGrpc) throws Exception {
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
daprRun = startDaprApp(
|
||||
TracingIT.class.getSimpleName() + "grpc",
|
||||
Service.SUCCESS_MESSAGE,
|
||||
Service.class,
|
||||
DaprApiProtocol.GRPC, // appProtocol
|
||||
AppRun.AppProtocol.GRPC, // appProtocol
|
||||
60000);
|
||||
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
daprRun.switchToHTTP();
|
||||
}
|
||||
|
||||
daprRun.waitForAppHealth(10000);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testInvoke(boolean useGrpc) throws Exception {
|
||||
setup(useGrpc);
|
||||
|
||||
@Test
|
||||
public void testInvoke() throws Exception {
|
||||
final OpenTelemetry openTelemetry = createOpenTelemetry("service over grpc");
|
||||
final Tracer tracer = openTelemetry.getTracer("grpc integration test tracer");
|
||||
|
||||
|
|
|
@ -16,14 +16,14 @@ package io.dapr.it.tracing.http;
|
|||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.propagation.TextMapPropagator;
|
||||
import jakarta.servlet.DispatcherType;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.servlet.DispatcherType;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.Collections;
|
||||
|
||||
@Component
|
||||
|
|
|
@ -11,8 +11,8 @@ import io.opentelemetry.api.trace.Span;
|
|||
import io.opentelemetry.api.trace.Tracer;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -26,7 +26,8 @@ public class TracingIT extends BaseIT {
|
|||
*/
|
||||
private DaprRun daprRun = null;
|
||||
|
||||
public void setup(boolean useGrpc) throws Exception {
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
daprRun = startDaprApp(
|
||||
TracingIT.class.getSimpleName() + "http",
|
||||
Service.SUCCESS_MESSAGE,
|
||||
|
@ -34,21 +35,12 @@ public class TracingIT extends BaseIT {
|
|||
true,
|
||||
30000);
|
||||
|
||||
if (useGrpc) {
|
||||
daprRun.switchToGRPC();
|
||||
} else {
|
||||
daprRun.switchToHTTP();
|
||||
}
|
||||
|
||||
// Wait since service might be ready even after port is available.
|
||||
Thread.sleep(2000);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testInvoke(boolean useGrpc) throws Exception {
|
||||
setup(useGrpc);
|
||||
|
||||
@Test
|
||||
public void testInvoke() throws Exception {
|
||||
final OpenTelemetry openTelemetry = createOpenTelemetry(OpenTelemetryConfig.SERVICE_NAME);
|
||||
final Tracer tracer = openTelemetry.getTracer(OpenTelemetryConfig.TRACER_NAME);
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ import java.util.stream.Collectors;
|
|||
* Abstract class with convenient methods common between client implementations.
|
||||
*
|
||||
* @see io.dapr.client.DaprClient
|
||||
* @see io.dapr.client.DaprClientGrpc
|
||||
* @see DaprClientImpl
|
||||
* @see io.dapr.client.DaprClientHttp
|
||||
*/
|
||||
abstract class AbstractDaprClient implements DaprClient, DaprPreviewClient {
|
||||
|
|
|
@ -1,26 +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;
|
||||
|
||||
/**
|
||||
* Transport protocol for Dapr's API.
|
||||
* @deprecated This class will be deleted at SDK version 1.10.
|
||||
*/
|
||||
@Deprecated
|
||||
public enum DaprApiProtocol {
|
||||
|
||||
GRPC,
|
||||
HTTP
|
||||
|
||||
}
|
|
@ -34,11 +34,14 @@ import io.dapr.client.domain.TransactionalStateOperation;
|
|||
import io.dapr.client.domain.UnsubscribeConfigurationRequest;
|
||||
import io.dapr.client.domain.UnsubscribeConfigurationResponse;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.stub.AbstractStub;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Generic Client Adapter to be used regardless of the GRPC or the HTTP Client implementation required.
|
||||
|
@ -659,6 +662,15 @@ public interface DaprClient extends AutoCloseable {
|
|||
*/
|
||||
Mono<UnsubscribeConfigurationResponse> unsubscribeConfiguration(UnsubscribeConfigurationRequest request);
|
||||
|
||||
/**
|
||||
* Returns a newly created gRPC stub with proper interceptors and channel for gRPC proxy invocation.
|
||||
* @param appId appId to be included in all gRPC calls for service invocation.
|
||||
* @param stubBuilder user-provided callback method to construct a new stub given the channel.
|
||||
* @return the gRPC stub with proper interceptors and channel.
|
||||
* @param <T> the generic type of the service to be invoked.
|
||||
*/
|
||||
<T extends AbstractStub<T>> T newGrpcStub(String appId, Function<Channel, T> stubBuilder);
|
||||
|
||||
/**
|
||||
* Gracefully shutdown the dapr runtime.
|
||||
*
|
||||
|
|
|
@ -14,14 +14,11 @@ limitations under the License.
|
|||
package io.dapr.client;
|
||||
|
||||
import io.dapr.client.resiliency.ResiliencyOptions;
|
||||
import io.dapr.config.Properties;
|
||||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
import io.dapr.utils.NetworkUtils;
|
||||
import io.dapr.v1.DaprGrpc;
|
||||
import io.grpc.ManagedChannel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A builder for the DaprClient,
|
||||
|
@ -29,18 +26,6 @@ import org.slf4j.LoggerFactory;
|
|||
*/
|
||||
public class DaprClientBuilder {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DaprClientBuilder.class);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
@ -70,8 +55,6 @@ public class DaprClientBuilder {
|
|||
public DaprClientBuilder() {
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -129,15 +112,7 @@ public class DaprClientBuilder {
|
|||
* @throws java.lang.IllegalStateException if any required field is missing
|
||||
*/
|
||||
public DaprClient build() {
|
||||
if (this.apiProtocol == DaprApiProtocol.HTTP) {
|
||||
LOGGER.warn("HTTP client protocol is deprecated and will be removed in Dapr's Java SDK version 1.10.");
|
||||
}
|
||||
|
||||
if (this.apiProtocol != this.methodInvocationApiProtocol) {
|
||||
return new DaprClientProxy(buildDaprClient(this.apiProtocol), buildDaprClient(this.methodInvocationApiProtocol));
|
||||
}
|
||||
|
||||
return buildDaprClient(this.apiProtocol);
|
||||
return buildDaprClient();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,26 +122,7 @@ public class DaprClientBuilder {
|
|||
* @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.
|
||||
*
|
||||
* @param protocol Dapr API's protocol.
|
||||
* @return the GRPC Client.
|
||||
* @throws java.lang.IllegalStateException if either host is missing or if port is missing or a negative number.
|
||||
*/
|
||||
private DaprClient buildDaprClient(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());
|
||||
}
|
||||
return buildDaprClient();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,25 +131,17 @@ public class DaprClientBuilder {
|
|||
* @return the GRPC Client.
|
||||
* @throws java.lang.IllegalStateException if either host is missing or if port is missing or a negative number.
|
||||
*/
|
||||
private DaprClient buildDaprClientGrpc() {
|
||||
private DaprClientImpl buildDaprClient() {
|
||||
final ManagedChannel channel = NetworkUtils.buildGrpcManagedChannel();
|
||||
final GrpcChannelFacade channelFacade = new GrpcChannelFacade(channel, this.daprHttpBuilder.build());
|
||||
final DaprHttp daprHttp = this.daprHttpBuilder.build();
|
||||
final GrpcChannelFacade channelFacade = new GrpcChannelFacade(channel);
|
||||
DaprGrpc.DaprStub asyncStub = DaprGrpc.newStub(channel);
|
||||
return new DaprClientGrpc(
|
||||
return new DaprClientImpl(
|
||||
channelFacade,
|
||||
asyncStub,
|
||||
daprHttp,
|
||||
this.objectSerializer,
|
||||
this.stateSerializer,
|
||||
this.resiliencyOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and instance of DaprClient over HTTP.
|
||||
*
|
||||
* @return DaprClient over HTTP.
|
||||
*/
|
||||
private DaprClient buildDaprClientHttp() {
|
||||
return new DaprClientHttp(this.daprHttpBuilder.build(), this.objectSerializer, this.stateSerializer);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,7 +14,6 @@ limitations under the License.
|
|||
package io.dapr.client;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.protobuf.Any;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.Empty;
|
||||
import io.dapr.client.domain.BulkPublishEntry;
|
||||
|
@ -48,9 +47,8 @@ import io.dapr.client.domain.UnlockResponseStatus;
|
|||
import io.dapr.client.domain.UnsubscribeConfigurationRequest;
|
||||
import io.dapr.client.domain.UnsubscribeConfigurationResponse;
|
||||
import io.dapr.client.resiliency.ResiliencyOptions;
|
||||
import io.dapr.config.Properties;
|
||||
import io.dapr.exceptions.DaprException;
|
||||
import io.dapr.internal.opencensus.GrpcWrapper;
|
||||
import io.dapr.internal.grpc.DaprClientGrpcInterceptors;
|
||||
import io.dapr.internal.resiliency.RetryPolicy;
|
||||
import io.dapr.internal.resiliency.TimeoutPolicy;
|
||||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
|
@ -60,22 +58,20 @@ import io.dapr.utils.TypeRef;
|
|||
import io.dapr.v1.CommonProtos;
|
||||
import io.dapr.v1.DaprGrpc;
|
||||
import io.dapr.v1.DaprProtos;
|
||||
import io.grpc.CallOptions;
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.ClientCall;
|
||||
import io.grpc.ClientInterceptor;
|
||||
import io.grpc.ForwardingClientCall;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.MethodDescriptor;
|
||||
import io.grpc.stub.AbstractStub;
|
||||
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.ContextView;
|
||||
import reactor.util.retry.Retry;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
@ -83,15 +79,16 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* An adapter for the GRPC Client.
|
||||
* Implementation of the Dapr client combining gRPC and HTTP (when applicable).
|
||||
*
|
||||
* @see io.dapr.v1.DaprGrpc
|
||||
* @see io.dapr.client.DaprClient
|
||||
*/
|
||||
public class DaprClientGrpc extends AbstractDaprClient {
|
||||
public class DaprClientImpl extends AbstractDaprClient {
|
||||
|
||||
/**
|
||||
* The GRPC managed channel to be used.
|
||||
|
@ -114,21 +111,11 @@ public class DaprClientGrpc extends AbstractDaprClient {
|
|||
private final DaprGrpc.DaprStub asyncStub;
|
||||
|
||||
/**
|
||||
* Default access level constructor, in order to create an instance of this class use io.dapr.client.DaprClientBuilder
|
||||
* The HTTP client to be used for healthz and HTTP service invocation only.
|
||||
*
|
||||
* @param channel Facade for the managed GRPC channel
|
||||
* @param asyncStub async gRPC stub
|
||||
* @param objectSerializer Serializer for transient request/response objects.
|
||||
* @param stateSerializer Serializer for state objects.
|
||||
* @see DaprClientBuilder
|
||||
* @see io.dapr.client.DaprHttp
|
||||
*/
|
||||
DaprClientGrpc(
|
||||
GrpcChannelFacade channel,
|
||||
DaprGrpc.DaprStub asyncStub,
|
||||
DaprObjectSerializer objectSerializer,
|
||||
DaprObjectSerializer stateSerializer) {
|
||||
this(channel, asyncStub, objectSerializer, stateSerializer, null);
|
||||
}
|
||||
private final DaprHttp httpClient;
|
||||
|
||||
/**
|
||||
* Default access level constructor, in order to create an instance of this class use io.dapr.client.DaprClientBuilder
|
||||
|
@ -137,18 +124,39 @@ public class DaprClientGrpc extends AbstractDaprClient {
|
|||
* @param asyncStub async gRPC stub
|
||||
* @param objectSerializer Serializer for transient request/response objects.
|
||||
* @param stateSerializer Serializer for state objects.
|
||||
* @see DaprClientBuilder
|
||||
*/
|
||||
DaprClientImpl(
|
||||
GrpcChannelFacade channel,
|
||||
DaprGrpc.DaprStub asyncStub,
|
||||
DaprHttp httpClient,
|
||||
DaprObjectSerializer objectSerializer,
|
||||
DaprObjectSerializer stateSerializer) {
|
||||
this(channel, asyncStub, httpClient, objectSerializer, stateSerializer, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default access level constructor, in order to create an instance of this class use io.dapr.client.DaprClientBuilder
|
||||
*
|
||||
* @param channel Facade for the managed GRPC channel
|
||||
* @param asyncStub async gRPC stub
|
||||
* @param httpClient client for http service invocation
|
||||
* @param objectSerializer Serializer for transient request/response objects.
|
||||
* @param stateSerializer Serializer for state objects.
|
||||
* @param resiliencyOptions Client-level override for resiliency options.
|
||||
* @see DaprClientBuilder
|
||||
*/
|
||||
DaprClientGrpc(
|
||||
DaprClientImpl(
|
||||
GrpcChannelFacade channel,
|
||||
DaprGrpc.DaprStub asyncStub,
|
||||
DaprHttp httpClient,
|
||||
DaprObjectSerializer objectSerializer,
|
||||
DaprObjectSerializer stateSerializer,
|
||||
ResiliencyOptions resiliencyOptions) {
|
||||
super(objectSerializer, stateSerializer);
|
||||
this.channel = channel;
|
||||
this.asyncStub = intercept(asyncStub);
|
||||
this.asyncStub = asyncStub;
|
||||
this.httpClient = httpClient;
|
||||
this.timeoutPolicy = new TimeoutPolicy(
|
||||
resiliencyOptions == null ? null : resiliencyOptions.getTimeout());
|
||||
this.retryPolicy = new RetryPolicy(
|
||||
|
@ -177,12 +185,72 @@ public class DaprClientGrpc extends AbstractDaprClient {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public <T extends AbstractStub<T>> T newGrpcStub(String appId, Function<Channel, T> stubBuilder) {
|
||||
// Adds Dapr interceptors to populate gRPC metadata automatically.
|
||||
return DaprClientGrpcInterceptors.intercept(appId, stubBuilder.apply(this.channel.getGrpcChannel()), timeoutPolicy);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> waitForSidecar(int timeoutInMilliseconds) {
|
||||
return this.channel.waitForChannelReady(timeoutInMilliseconds);
|
||||
String[] pathSegments = new String[] { DaprHttp.API_VERSION, "healthz", "outbound"};
|
||||
int maxRetries = 5;
|
||||
|
||||
Retry retrySpec = Retry
|
||||
.fixedDelay(maxRetries, Duration.ofMillis(500))
|
||||
.doBeforeRetry(retrySignal -> {
|
||||
System.out.println("Retrying component health check...");
|
||||
});
|
||||
|
||||
/*
|
||||
NOTE: (Cassie) Uncomment this once it actually gets implemented:
|
||||
https://github.com/grpc/grpc-java/issues/4359
|
||||
|
||||
int maxChannelStateRetries = 5;
|
||||
|
||||
// Retry logic for checking the channel state
|
||||
Retry channelStateRetrySpec = Retry
|
||||
.fixedDelay(maxChannelStateRetries, Duration.ofMillis(500))
|
||||
.doBeforeRetry(retrySignal -> {
|
||||
System.out.println("Retrying channel state check...");
|
||||
});
|
||||
*/
|
||||
|
||||
// Do the Dapr Http endpoint check to have parity with Dotnet
|
||||
Mono<DaprHttp.Response> responseMono = this.httpClient.invokeApi(DaprHttp.HttpMethods.GET.name(), pathSegments,
|
||||
null, "", null, null);
|
||||
|
||||
return responseMono
|
||||
.retryWhen(retrySpec)
|
||||
/*
|
||||
NOTE: (Cassie) Uncomment this once it actually gets implemented:
|
||||
https://github.com/grpc/grpc-java/issues/4359
|
||||
.flatMap(response -> {
|
||||
// Check the status code
|
||||
int statusCode = response.getStatusCode();
|
||||
|
||||
// Check if the channel's state is READY
|
||||
return Mono.defer(() -> {
|
||||
if (this.channel.getState(true) == ConnectivityState.READY) {
|
||||
// Return true if the status code is in the 2xx range
|
||||
if (statusCode >= 200 && statusCode < 300) {
|
||||
return Mono.empty(); // Continue with the flow
|
||||
}
|
||||
}
|
||||
return Mono.error(new RuntimeException("Health check failed"));
|
||||
}).retryWhen(channelStateRetrySpec);
|
||||
})
|
||||
*/
|
||||
.timeout(Duration.ofMillis(timeoutInMilliseconds))
|
||||
.onErrorResume(DaprException.class, e ->
|
||||
Mono.error(new RuntimeException(e)))
|
||||
.switchIfEmpty(DaprException.wrapMono(new RuntimeException("Health check timed out")))
|
||||
.then();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -309,38 +377,63 @@ public class DaprClientGrpc extends AbstractDaprClient {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeMethod(InvokeMethodRequest invokeMethodRequest, TypeRef<T> type) {
|
||||
try {
|
||||
String appId = invokeMethodRequest.getAppId();
|
||||
String method = invokeMethodRequest.getMethod();
|
||||
Object body = invokeMethodRequest.getBody();
|
||||
HttpExtension httpExtension = invokeMethodRequest.getHttpExtension();
|
||||
DaprProtos.InvokeServiceRequest envelope = buildInvokeServiceRequest(
|
||||
httpExtension,
|
||||
appId,
|
||||
method,
|
||||
body);
|
||||
// Regarding missing metadata in method invocation for gRPC:
|
||||
// gRPC to gRPC does not handle metadata in Dapr runtime proto.
|
||||
// gRPC to HTTP does not map correctly in Dapr runtime as per https://github.com/dapr/dapr/issues/2342
|
||||
final String appId = invokeMethodRequest.getAppId();
|
||||
final String method = invokeMethodRequest.getMethod();
|
||||
final Object request = invokeMethodRequest.getBody();
|
||||
final HttpExtension httpExtension = invokeMethodRequest.getHttpExtension();
|
||||
final String contentType = invokeMethodRequest.getContentType();
|
||||
final Map<String, String> metadata = invokeMethodRequest.getMetadata();
|
||||
|
||||
return Mono.deferContextual(
|
||||
context -> this.<CommonProtos.InvokeResponse>createMono(
|
||||
it -> intercept(context, asyncStub).invokeService(envelope, it)
|
||||
)
|
||||
).flatMap(
|
||||
it -> {
|
||||
try {
|
||||
return Mono.justOrEmpty(objectSerializer.deserialize(it.getData().getValue().toByteArray(), type));
|
||||
} catch (IOException e) {
|
||||
throw DaprException.propagate(e);
|
||||
}
|
||||
}
|
||||
if (httpExtension == null) {
|
||||
throw new IllegalArgumentException("HttpExtension cannot be null. Use HttpExtension.NONE instead.");
|
||||
}
|
||||
// If the httpExtension is not null, then the method will not be null based on checks in constructor
|
||||
final String httpMethod = httpExtension.getMethod().toString();
|
||||
if (appId == null || appId.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("App Id cannot be null or empty.");
|
||||
}
|
||||
if (method == null || method.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("Method name cannot be null or empty.");
|
||||
}
|
||||
|
||||
|
||||
String[] methodSegments = method.split("/");
|
||||
|
||||
List<String> pathSegments = new ArrayList<>(Arrays.asList(DaprHttp.API_VERSION, "invoke", appId, "method"));
|
||||
pathSegments.addAll(Arrays.asList(methodSegments));
|
||||
|
||||
final Map<String, String> headers = new HashMap<>();
|
||||
headers.putAll(httpExtension.getHeaders());
|
||||
if (metadata != null) {
|
||||
headers.putAll(metadata);
|
||||
}
|
||||
byte[] serializedRequestBody = objectSerializer.serialize(request);
|
||||
if (contentType != null && !contentType.isEmpty()) {
|
||||
headers.put(io.dapr.client.domain.Metadata.CONTENT_TYPE, contentType);
|
||||
} else {
|
||||
headers.put(io.dapr.client.domain.Metadata.CONTENT_TYPE, objectSerializer.getContentType());
|
||||
}
|
||||
Mono<DaprHttp.Response> response = Mono.deferContextual(
|
||||
context -> this.httpClient.invokeApi(httpMethod, pathSegments.toArray(new String[0]),
|
||||
httpExtension.getQueryParams(), serializedRequestBody, headers, context)
|
||||
);
|
||||
return response.flatMap(r -> getMonoForHttpResponse(type, r));
|
||||
} catch (Exception ex) {
|
||||
return DaprException.wrapMono(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> Mono<T> getMonoForHttpResponse(TypeRef<T> type, DaprHttp.Response r) {
|
||||
try {
|
||||
T object = objectSerializer.deserialize(r.getBody(), type);
|
||||
if (object == null) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
return Mono.just(object);
|
||||
} catch (Exception ex) {
|
||||
return DaprException.wrapMono(ex);
|
||||
}
|
||||
|
@ -673,48 +766,6 @@ public class DaprClientGrpc extends AbstractDaprClient {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the object io.dapr.{@link DaprProtos.InvokeServiceRequest} to be send based on the parameters.
|
||||
*
|
||||
* @param httpExtension Object for HttpExtension
|
||||
* @param appId The application id to be invoked
|
||||
* @param method The application method to be invoked
|
||||
* @param body The body of the request to be send as part of the invocation
|
||||
* @param <K> 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 <K> DaprProtos.InvokeServiceRequest buildInvokeServiceRequest(
|
||||
HttpExtension httpExtension,
|
||||
String appId,
|
||||
String method,
|
||||
K body) 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 (body != null) {
|
||||
byte[] byteRequest = objectSerializer.serialize(body);
|
||||
Any data = Any.newBuilder().setValue(ByteString.copyFrom(byteRequest)).build();
|
||||
requestBuilder.setData(data);
|
||||
} else {
|
||||
requestBuilder.setData(Any.newBuilder().build());
|
||||
}
|
||||
CommonProtos.HTTPExtension.Builder httpExtensionBuilder = CommonProtos.HTTPExtension.newBuilder();
|
||||
|
||||
httpExtensionBuilder.setVerb(CommonProtos.HTTPExtension.Verb.valueOf(httpExtension.getMethod().toString()))
|
||||
.setQuerystring(httpExtension.encodeQueryString());
|
||||
requestBuilder.setHttpExtension(httpExtensionBuilder.build());
|
||||
|
||||
requestBuilder.setContentType(objectSerializer.getContentType());
|
||||
|
||||
DaprProtos.InvokeServiceRequest.Builder envelopeBuilder = DaprProtos.InvokeServiceRequest.newBuilder()
|
||||
.setId(appId)
|
||||
.setMessage(requestBuilder.build());
|
||||
return envelopeBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -963,12 +1014,15 @@ public class DaprClientGrpc extends AbstractDaprClient {
|
|||
*/
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
if (channel != null) {
|
||||
DaprException.wrap(() -> {
|
||||
DaprException.wrap(() -> {
|
||||
if (channel != null) {
|
||||
channel.close();
|
||||
return true;
|
||||
}).call();
|
||||
}
|
||||
}
|
||||
if (httpClient != null) {
|
||||
httpClient.close();
|
||||
}
|
||||
return true;
|
||||
}).call();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1054,7 +1108,7 @@ public class DaprClientGrpc extends AbstractDaprClient {
|
|||
|
||||
DaprProtos.SubscribeConfigurationRequest envelope = builder.build();
|
||||
return this.<DaprProtos.SubscribeConfigurationResponse>createFlux(
|
||||
it -> intercept(asyncStub).subscribeConfiguration(envelope, it)
|
||||
it -> intercept(null, asyncStub).subscribeConfiguration(envelope, it)
|
||||
).map(
|
||||
it -> {
|
||||
Map<String, ConfigurationItem> configMap = new HashMap<>();
|
||||
|
@ -1094,7 +1148,7 @@ public class DaprClientGrpc extends AbstractDaprClient {
|
|||
DaprProtos.UnsubscribeConfigurationRequest envelope = builder.build();
|
||||
|
||||
return this.<DaprProtos.UnsubscribeConfigurationResponse>createMono(
|
||||
it -> intercept(asyncStub).unsubscribeConfiguration(envelope, it)
|
||||
it -> intercept(null, asyncStub).unsubscribeConfiguration(envelope, it)
|
||||
).map(
|
||||
it -> new UnsubscribeConfigurationResponse(it.getOk(), it.getMessage())
|
||||
);
|
||||
|
@ -1119,35 +1173,6 @@ public class DaprClientGrpc extends AbstractDaprClient {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates GRPC client with interceptors.
|
||||
*
|
||||
* @param client GRPC client for Dapr.
|
||||
* @return Client after adding interceptors.
|
||||
*/
|
||||
private DaprGrpc.DaprStub intercept(DaprGrpc.DaprStub client) {
|
||||
ClientInterceptor interceptor = new ClientInterceptor() {
|
||||
@Override
|
||||
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
|
||||
MethodDescriptor<ReqT, RespT> methodDescriptor,
|
||||
CallOptions options,
|
||||
Channel channel) {
|
||||
ClientCall<ReqT, RespT> clientCall = channel.newCall(methodDescriptor, timeoutPolicy.apply(options));
|
||||
return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(clientCall) {
|
||||
@Override
|
||||
public void start(final Listener<RespT> responseListener, final Metadata metadata) {
|
||||
String daprApiToken = Properties.API_TOKEN.get();
|
||||
if (daprApiToken != null) {
|
||||
metadata.put(Metadata.Key.of(Headers.DAPR_API_TOKEN, Metadata.ASCII_STRING_MARSHALLER), daprApiToken);
|
||||
}
|
||||
super.start(responseListener, metadata);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
return client.withInterceptors(interceptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates GRPC client with interceptors for telemetry.
|
||||
*
|
||||
|
@ -1155,8 +1180,8 @@ public class DaprClientGrpc extends AbstractDaprClient {
|
|||
* @param client GRPC client for Dapr.
|
||||
* @return Client after adding interceptors.
|
||||
*/
|
||||
private static DaprGrpc.DaprStub intercept(ContextView context, DaprGrpc.DaprStub client) {
|
||||
return GrpcWrapper.intercept(context, client);
|
||||
private DaprGrpc.DaprStub intercept(ContextView context, DaprGrpc.DaprStub client) {
|
||||
return DaprClientGrpcInterceptors.intercept(client, this.timeoutPolicy, context);
|
||||
}
|
||||
|
||||
private <T> Mono<T> createMono(Consumer<StreamObserver<T>> consumer) {
|
|
@ -1,608 +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.DeleteStateRequest;
|
||||
import io.dapr.client.domain.ExecuteStateTransactionRequest;
|
||||
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;
|
||||
import io.dapr.client.domain.InvokeBindingRequest;
|
||||
import io.dapr.client.domain.InvokeMethodRequest;
|
||||
import io.dapr.client.domain.PublishEventRequest;
|
||||
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.SubscribeConfigurationResponse;
|
||||
import io.dapr.client.domain.TransactionalStateOperation;
|
||||
import io.dapr.client.domain.UnsubscribeConfigurationRequest;
|
||||
import io.dapr.client.domain.UnsubscribeConfigurationResponse;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Class that delegates to other implementations.
|
||||
* @deprecated This class will be deleted at SDK release version 1.10.
|
||||
* @see DaprClient
|
||||
* @see DaprClientGrpc
|
||||
* @see DaprClientHttp
|
||||
*/
|
||||
@Deprecated
|
||||
class DaprClientProxy implements DaprClient {
|
||||
|
||||
/**
|
||||
* Client for all API invocations.
|
||||
*/
|
||||
private final DaprClient client;
|
||||
|
||||
/**
|
||||
* Client to override Dapr's service invocation APIs.
|
||||
*/
|
||||
private final DaprClient methodInvocationOverrideClient;
|
||||
|
||||
/**
|
||||
* Constructor with delegate client.
|
||||
*
|
||||
* @param client Client for all API invocations.
|
||||
* @see DaprClientBuilder
|
||||
*/
|
||||
DaprClientProxy(DaprClient 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
|
||||
*/
|
||||
DaprClientProxy(
|
||||
DaprClient client,
|
||||
DaprClient methodInvocationOverrideClient) {
|
||||
this.client = client;
|
||||
this.methodInvocationOverrideClient = methodInvocationOverrideClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> waitForSidecar(int timeoutInMilliseconds) {
|
||||
return client.waitForSidecar(timeoutInMilliseconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> publishEvent(String pubsubName, String topicName, Object data) {
|
||||
return client.publishEvent(pubsubName, topicName, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> publishEvent(String pubsubName, String topicName, Object data, Map<String, String> metadata) {
|
||||
return client.publishEvent(pubsubName, topicName, data, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> publishEvent(PublishEventRequest request) {
|
||||
return client.publishEvent(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeMethod(String appId,
|
||||
String methodName,
|
||||
Object data,
|
||||
HttpExtension httpExtension,
|
||||
Map<String, String> metadata,
|
||||
TypeRef<T> type) {
|
||||
return methodInvocationOverrideClient.invokeMethod(appId, methodName, data, httpExtension, metadata, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeMethod(String appId,
|
||||
String methodName,
|
||||
Object request,
|
||||
HttpExtension httpExtension,
|
||||
Map<String, String> metadata,
|
||||
Class<T> clazz) {
|
||||
return methodInvocationOverrideClient.invokeMethod(appId, methodName, request, httpExtension, metadata, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeMethod(String appId,
|
||||
String methodName,
|
||||
Object request,
|
||||
HttpExtension httpExtension,
|
||||
TypeRef<T> type) {
|
||||
return methodInvocationOverrideClient.invokeMethod(appId, methodName, request, httpExtension, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeMethod(String appId,
|
||||
String methodName,
|
||||
Object request,
|
||||
HttpExtension httpExtension,
|
||||
Class<T> clazz) {
|
||||
return methodInvocationOverrideClient.invokeMethod(appId, methodName, request, httpExtension, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeMethod(String appId,
|
||||
String methodName,
|
||||
HttpExtension httpExtension,
|
||||
Map<String, String> metadata,
|
||||
TypeRef<T> type) {
|
||||
return methodInvocationOverrideClient.invokeMethod(appId, methodName, httpExtension, metadata, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeMethod(String appId,
|
||||
String methodName,
|
||||
HttpExtension httpExtension,
|
||||
Map<String, String> metadata,
|
||||
Class<T> clazz) {
|
||||
return methodInvocationOverrideClient.invokeMethod(appId, methodName, httpExtension, metadata, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> invokeMethod(String appId,
|
||||
String methodName,
|
||||
Object request,
|
||||
HttpExtension httpExtension,
|
||||
Map<String, String> metadata) {
|
||||
return methodInvocationOverrideClient.invokeMethod(appId, methodName, request, httpExtension, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> invokeMethod(String appId, String methodName, Object request, HttpExtension httpExtension) {
|
||||
return methodInvocationOverrideClient.invokeMethod(appId, methodName, request, httpExtension);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> invokeMethod(String appId,
|
||||
String methodName,
|
||||
HttpExtension httpExtension,
|
||||
Map<String, String> metadata) {
|
||||
return methodInvocationOverrideClient.invokeMethod(appId, methodName, httpExtension, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<byte[]> invokeMethod(String appId,
|
||||
String methodName,
|
||||
byte[] request,
|
||||
HttpExtension httpExtension,
|
||||
Map<String, String> metadata) {
|
||||
return methodInvocationOverrideClient.invokeMethod(appId, methodName, request, httpExtension, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeMethod(InvokeMethodRequest invokeMethodRequest, TypeRef<T> type) {
|
||||
return methodInvocationOverrideClient.invokeMethod(invokeMethodRequest, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> invokeBinding(String bindingName, String operation, Object data) {
|
||||
return client.invokeBinding(bindingName, operation, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<byte[]> invokeBinding(String bindingName, String operation, byte[] data, Map<String, String> metadata) {
|
||||
return client.invokeBinding(bindingName, operation, data, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(String bindingName, String operation, Object data, TypeRef<T> type) {
|
||||
return client.invokeBinding(bindingName, operation, data, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(String bindingName, String operation, Object data, Class<T> clazz) {
|
||||
return client.invokeBinding(bindingName, operation, data, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(String bindingName,
|
||||
String operation,
|
||||
Object data,
|
||||
Map<String, String> metadata,
|
||||
TypeRef<T> type) {
|
||||
return client.invokeBinding(bindingName, operation, data, metadata, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(String bindingName,
|
||||
String operation,
|
||||
Object data,
|
||||
Map<String, String> metadata,
|
||||
Class<T> clazz) {
|
||||
return client.invokeBinding(bindingName, operation, data, metadata, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(InvokeBindingRequest request, TypeRef<T> type) {
|
||||
return client.invokeBinding(request, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String storeName, State<T> state, TypeRef<T> type) {
|
||||
return client.getState(storeName, state, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String storeName, State<T> state, Class<T> clazz) {
|
||||
return client.getState(storeName, state, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String storeName, String key, TypeRef<T> type) {
|
||||
return client.getState(storeName, key, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String storeName, String key, Class<T> clazz) {
|
||||
return client.getState(storeName, key, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String storeName, String key, StateOptions options, TypeRef<T> type) {
|
||||
return client.getState(storeName, key, options, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String storeName, String key, StateOptions options, Class<T> clazz) {
|
||||
return client.getState(storeName, key, options, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(GetStateRequest request, TypeRef<T> type) {
|
||||
return client.getState(request, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<List<State<T>>> getBulkState(String storeName, List<String> keys, TypeRef<T> type) {
|
||||
return client.getBulkState(storeName, keys, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<List<State<T>>> getBulkState(String storeName, List<String> keys, Class<T> clazz) {
|
||||
return client.getBulkState(storeName, keys, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<List<State<T>>> getBulkState(GetBulkStateRequest request, TypeRef<T> type) {
|
||||
return client.getBulkState(request, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> executeStateTransaction(String storeName, List<TransactionalStateOperation<?>> operations) {
|
||||
return client.executeStateTransaction(storeName, operations);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> executeStateTransaction(ExecuteStateTransactionRequest request) {
|
||||
return client.executeStateTransaction(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> saveBulkState(String storeName, List<State<?>> states) {
|
||||
return client.saveBulkState(storeName, states);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> saveBulkState(SaveStateRequest request) {
|
||||
return client.saveBulkState(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> saveState(String storeName, String key, Object value) {
|
||||
return client.saveState(storeName, key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> saveState(String storeName, String key, String etag, Object value, StateOptions options) {
|
||||
return client.saveState(storeName, key, etag, value, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> deleteState(String storeName, String key) {
|
||||
return client.deleteState(storeName, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> deleteState(String storeName, String key, String etag, StateOptions options) {
|
||||
return client.deleteState(storeName, key, etag, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> deleteState(DeleteStateRequest request) {
|
||||
return client.deleteState(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Map<String, String>> getSecret(String storeName, String secretName, Map<String, String> metadata) {
|
||||
return client.getSecret(storeName, secretName, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Map<String, String>> getSecret(String storeName, String secretName) {
|
||||
return client.getSecret(storeName, secretName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Map<String, String>> getSecret(GetSecretRequest request) {
|
||||
return client.getSecret(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Map<String, Map<String, String>>> getBulkSecret(String storeName) {
|
||||
return client.getBulkSecret(storeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Map<String, Map<String, String>>> getBulkSecret(String storeName, Map<String, String> metadata) {
|
||||
return client.getBulkSecret(storeName, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Map<String, Map<String, String>>> getBulkSecret(GetBulkSecretRequest request) {
|
||||
return client.getBulkSecret(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<ConfigurationItem> getConfiguration(String storeName, String key) {
|
||||
return client.getConfiguration(storeName, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<ConfigurationItem> getConfiguration(String storeName, String key, Map<String, String> metadata) {
|
||||
return client.getConfiguration(storeName, key, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Map<String, ConfigurationItem>> getConfiguration(String storeName, String... keys) {
|
||||
return client.getConfiguration(storeName, keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Map<String, ConfigurationItem>> getConfiguration(String storeName, List<String> keys,
|
||||
Map<String, String> metadata) {
|
||||
return client.getConfiguration(storeName, keys, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Map<String, ConfigurationItem>> getConfiguration(GetConfigurationRequest request) {
|
||||
return client.getConfiguration(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Flux<SubscribeConfigurationResponse> subscribeConfiguration(String storeName, String... keys) {
|
||||
return client.subscribeConfiguration(storeName, keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Flux<SubscribeConfigurationResponse> subscribeConfiguration(String storeName, List<String> keys,
|
||||
Map<String, String> metadata) {
|
||||
return client.subscribeConfiguration(storeName, keys, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Flux<SubscribeConfigurationResponse> subscribeConfiguration(SubscribeConfigurationRequest request) {
|
||||
return client.subscribeConfiguration(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<UnsubscribeConfigurationResponse> unsubscribeConfiguration(String id, String storeName) {
|
||||
return client.unsubscribeConfiguration(id, storeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<UnsubscribeConfigurationResponse> unsubscribeConfiguration(UnsubscribeConfigurationRequest request) {
|
||||
return client.unsubscribeConfiguration(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
client.close();
|
||||
if (client != methodInvocationOverrideClient) {
|
||||
methodInvocationOverrideClient.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Mono<Void> shutdown() {
|
||||
return client.shutdown();
|
||||
}
|
||||
}
|
|
@ -23,9 +23,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
/**
|
||||
* A builder for the DaprHttp.
|
||||
* @deprecated Use {@link DaprClientBuilder} instead, this will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class DaprHttpBuilder {
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2024 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.grpc.CallOptions;
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.ClientCall;
|
||||
import io.grpc.ClientInterceptor;
|
||||
import io.grpc.MethodDescriptor;
|
||||
import reactor.util.context.ContextView;
|
||||
|
||||
/**
|
||||
* Injects tracing headers to gRPC metadata.
|
||||
*/
|
||||
public class DaprTracingInterceptor implements ClientInterceptor {
|
||||
|
||||
private final io.dapr.internal.grpc.interceptors.DaprTracingInterceptor delegate;
|
||||
|
||||
/**
|
||||
* Creates an instance of the injector for gRPC context from Reactor's context.
|
||||
* @param context Reactor's context
|
||||
*/
|
||||
public DaprTracingInterceptor(ContextView context) {
|
||||
this.delegate = new io.dapr.internal.grpc.interceptors.DaprTracingInterceptor(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
|
||||
MethodDescriptor<ReqT, RespT> methodDescriptor,
|
||||
CallOptions callOptions,
|
||||
Channel channel) {
|
||||
return this.delegate.interceptCall(methodDescriptor, callOptions, channel);
|
||||
}
|
||||
}
|
|
@ -13,18 +13,11 @@ limitations under the License.
|
|||
|
||||
package io.dapr.client;
|
||||
|
||||
import io.dapr.config.Properties;
|
||||
import io.dapr.exceptions.DaprException;
|
||||
import io.dapr.v1.DaprGrpc;
|
||||
import io.grpc.ConnectivityState;
|
||||
import io.grpc.ManagedChannel;
|
||||
import okhttp3.OkHttpClient;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.retry.Retry;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* Facade for common operations on gRPC channel.
|
||||
|
@ -39,11 +32,6 @@ class GrpcChannelFacade implements Closeable {
|
|||
*/
|
||||
private final ManagedChannel channel;
|
||||
|
||||
/**
|
||||
* The reference to the DaprHttp client.
|
||||
*/
|
||||
private final DaprHttp daprHttp;
|
||||
|
||||
|
||||
/**
|
||||
* Default access level constructor, in order to create an instance of this class use io.dapr.client.DaprClientBuilder
|
||||
|
@ -51,75 +39,23 @@ class GrpcChannelFacade implements Closeable {
|
|||
* @param channel A Managed GRPC channel
|
||||
* @see DaprClientBuilder
|
||||
*/
|
||||
GrpcChannelFacade(ManagedChannel channel, DaprHttp daprHttp) {
|
||||
GrpcChannelFacade(ManagedChannel channel) {
|
||||
this.channel = channel;
|
||||
this.daprHttp = daprHttp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gRPC channel to the sidecar.
|
||||
* @return Sidecar's gRPC channel.
|
||||
*/
|
||||
ManagedChannel getGrpcChannel() {
|
||||
return this.channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (daprHttp != null) {
|
||||
daprHttp.close();
|
||||
}
|
||||
|
||||
if (channel != null && !channel.isShutdown()) {
|
||||
channel.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public Mono<Void> waitForChannelReady(int timeoutInMilliseconds) {
|
||||
String[] pathSegments = new String[] { DaprHttp.API_VERSION, "healthz", "outbound"};
|
||||
int maxRetries = 5;
|
||||
|
||||
Retry retrySpec = Retry
|
||||
.fixedDelay(maxRetries, Duration.ofMillis(500))
|
||||
.doBeforeRetry(retrySignal -> {
|
||||
System.out.println("Retrying component health check...");
|
||||
});
|
||||
|
||||
/*
|
||||
NOTE: (Cassie) Uncomment this once it actually gets implemented:
|
||||
https://github.com/grpc/grpc-java/issues/4359
|
||||
|
||||
int maxChannelStateRetries = 5;
|
||||
|
||||
// Retry logic for checking the channel state
|
||||
Retry channelStateRetrySpec = Retry
|
||||
.fixedDelay(maxChannelStateRetries, Duration.ofMillis(500))
|
||||
.doBeforeRetry(retrySignal -> {
|
||||
System.out.println("Retrying channel state check...");
|
||||
});
|
||||
*/
|
||||
|
||||
// Do the Dapr Http endpoint check to have parity with Dotnet
|
||||
Mono<DaprHttp.Response> responseMono = this.daprHttp.invokeApi(DaprHttp.HttpMethods.GET.name(), pathSegments,
|
||||
null, "", null, null);
|
||||
|
||||
return responseMono
|
||||
.retryWhen(retrySpec)
|
||||
/*
|
||||
NOTE: (Cassie) Uncomment this once it actually gets implemented:
|
||||
https://github.com/grpc/grpc-java/issues/4359
|
||||
.flatMap(response -> {
|
||||
// Check the status code
|
||||
int statusCode = response.getStatusCode();
|
||||
|
||||
// Check if the channel's state is READY
|
||||
return Mono.defer(() -> {
|
||||
if (this.channel.getState(true) == ConnectivityState.READY) {
|
||||
// Return true if the status code is in the 2xx range
|
||||
if (statusCode >= 200 && statusCode < 300) {
|
||||
return Mono.empty(); // Continue with the flow
|
||||
}
|
||||
}
|
||||
return Mono.error(new RuntimeException("Health check failed"));
|
||||
}).retryWhen(channelStateRetrySpec);
|
||||
})
|
||||
*/
|
||||
.timeout(Duration.ofMillis(timeoutInMilliseconds))
|
||||
.onErrorResume(DaprException.class, e ->
|
||||
Mono.error(new RuntimeException(e)))
|
||||
.switchIfEmpty(DaprException.wrapMono(new RuntimeException("Health check timed out")))
|
||||
.then();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ package io.dapr.client.domain;
|
|||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ limitations under the License.
|
|||
package io.dapr.client.domain;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,7 +13,6 @@ limitations under the License.
|
|||
|
||||
package io.dapr.config;
|
||||
|
||||
import io.dapr.client.DaprApiProtocol;
|
||||
import io.dapr.utils.NetworkUtils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
@ -50,16 +49,6 @@ public class Properties {
|
|||
*/
|
||||
private static final Duration DEFAULT_API_TIMEOUT = Duration.ofMillis(0L);
|
||||
|
||||
/**
|
||||
* Dapr's default use of gRPC or HTTP.
|
||||
*/
|
||||
private static final DaprApiProtocol DEFAULT_API_PROTOCOL = DaprApiProtocol.GRPC;
|
||||
|
||||
/**
|
||||
* Dapr's default use of gRPC or HTTP for Dapr's method invocation APIs.
|
||||
*/
|
||||
private static final DaprApiProtocol DEFAULT_API_METHOD_INVOCATION_PROTOCOL = DaprApiProtocol.HTTP;
|
||||
|
||||
/**
|
||||
* Dapr's default String encoding: UTF-8.
|
||||
*/
|
||||
|
@ -143,28 +132,6 @@ public class Properties {
|
|||
"DAPR_API_TIMEOUT_MILLISECONDS",
|
||||
DEFAULT_API_TIMEOUT);
|
||||
|
||||
/**
|
||||
* Determines if Dapr client will use gRPC or HTTP to talk to Dapr's side car.
|
||||
* @deprecated This attribute will be deleted at SDK version 1.10.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final Property<DaprApiProtocol> API_PROTOCOL = new GenericProperty<>(
|
||||
"dapr.api.protocol",
|
||||
"DAPR_API_PROTOCOL",
|
||||
DEFAULT_API_PROTOCOL,
|
||||
(s) -> DaprApiProtocol.valueOf(s.toUpperCase()));
|
||||
|
||||
/**
|
||||
* Determines if Dapr client should use gRPC or HTTP for Dapr's service method invocation APIs.
|
||||
* @deprecated This attribute will be deleted at SDK version 1.10.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final Property<DaprApiProtocol> API_METHOD_INVOCATION_PROTOCOL = new GenericProperty<>(
|
||||
"dapr.api.methodInvocation.protocol",
|
||||
"DAPR_API_METHOD_INVOCATION_PROTOCOL",
|
||||
DEFAULT_API_METHOD_INVOCATION_PROTOCOL,
|
||||
(s) -> DaprApiProtocol.valueOf(s.toUpperCase()));
|
||||
|
||||
/**
|
||||
* API token for authentication between App and Dapr's side car.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright 2024 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.internal.grpc;
|
||||
|
||||
import io.dapr.internal.grpc.interceptors.DaprApiTokenInterceptor;
|
||||
import io.dapr.internal.grpc.interceptors.DaprAppIdInterceptor;
|
||||
import io.dapr.internal.grpc.interceptors.DaprTimeoutInterceptor;
|
||||
import io.dapr.internal.grpc.interceptors.DaprTracingInterceptor;
|
||||
import io.dapr.internal.resiliency.TimeoutPolicy;
|
||||
import io.grpc.stub.AbstractStub;
|
||||
import reactor.util.context.ContextView;
|
||||
|
||||
/**
|
||||
* Class to be used as part of your service's client stub interceptor.
|
||||
* Usage: myClientStub = DaprClientGrpcInterceptors.intercept(myClientStub);
|
||||
*/
|
||||
public class DaprClientGrpcInterceptors {
|
||||
|
||||
/**
|
||||
* Adds all Dapr interceptors to a gRPC async stub.
|
||||
* @param appId the appId to be invoked
|
||||
* @param client gRPC client
|
||||
* @param <T> async client type
|
||||
* @return async client instance with interceptors
|
||||
*/
|
||||
public static <T extends AbstractStub<T>> T intercept(final String appId, final T client) {
|
||||
return intercept(appId, client, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all Dapr interceptors to a gRPC async stub.
|
||||
* @param client gRPC client
|
||||
* @param <T> async client type
|
||||
* @return async client instance with interceptors
|
||||
*/
|
||||
public static <T extends AbstractStub<T>> T intercept(final T client) {
|
||||
return intercept(null, client, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all Dapr interceptors to a gRPC async stub.
|
||||
* @param appId the appId to be invoked
|
||||
* @param client gRPC client
|
||||
* @param timeoutPolicy timeout policy for gRPC call
|
||||
* @param <T> async client type
|
||||
* @return async client instance with interceptors
|
||||
*/
|
||||
public static <T extends AbstractStub<T>> T intercept(
|
||||
final String appId, final T client, final TimeoutPolicy timeoutPolicy) {
|
||||
return intercept(appId, client, timeoutPolicy, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all Dapr interceptors to a gRPC async stub.
|
||||
* @param client gRPC client
|
||||
* @param timeoutPolicy timeout policy for gRPC call
|
||||
* @param <T> async client type
|
||||
* @return async client instance with interceptors
|
||||
*/
|
||||
public static <T extends AbstractStub<T>> T intercept(final T client, final TimeoutPolicy timeoutPolicy) {
|
||||
return intercept(null, client, timeoutPolicy, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all Dapr interceptors to a gRPC async stub.
|
||||
* @param appId the appId to be invoked
|
||||
* @param client gRPC client
|
||||
* @param context Reactor context for tracing
|
||||
* @param <T> async client type
|
||||
* @return async client instance with interceptors
|
||||
*/
|
||||
public static <T extends AbstractStub<T>> T intercept(
|
||||
final String appId, final T client, final ContextView context) {
|
||||
return intercept(appId, client, null, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all Dapr interceptors to a gRPC async stub.
|
||||
* @param client gRPC client
|
||||
* @param context Reactor context for tracing
|
||||
* @param <T> async client type
|
||||
* @return async client instance with interceptors
|
||||
*/
|
||||
public static <T extends AbstractStub<T>> T intercept(final T client, final ContextView context) {
|
||||
return intercept(null, client, null, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all Dapr interceptors to a gRPC async stub.
|
||||
* @param client gRPC client
|
||||
* @param timeoutPolicy timeout policy for gRPC call
|
||||
* @param context Reactor context for tracing
|
||||
* @param <T> async client type
|
||||
* @return async client instance with interceptors
|
||||
*/
|
||||
public static <T extends AbstractStub<T>> T intercept(
|
||||
final T client,
|
||||
final TimeoutPolicy timeoutPolicy,
|
||||
final ContextView context) {
|
||||
return intercept(null, client, timeoutPolicy, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all Dapr interceptors to a gRPC async stub.
|
||||
* @param appId the appId to be invoked
|
||||
* @param client gRPC client
|
||||
* @param timeoutPolicy timeout policy for gRPC call
|
||||
* @param context Reactor context for tracing
|
||||
* @param <T> async client type
|
||||
* @return async client instance with interceptors
|
||||
*/
|
||||
public static <T extends AbstractStub<T>> T intercept(
|
||||
final String appId,
|
||||
final T client,
|
||||
final TimeoutPolicy timeoutPolicy,
|
||||
final ContextView context) {
|
||||
if (client == null) {
|
||||
throw new IllegalArgumentException("client cannot be null");
|
||||
}
|
||||
|
||||
return client.withInterceptors(
|
||||
new DaprAppIdInterceptor(appId),
|
||||
new DaprApiTokenInterceptor(),
|
||||
new DaprTimeoutInterceptor(timeoutPolicy),
|
||||
new DaprTracingInterceptor(context));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2024 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.internal.grpc.interceptors;
|
||||
|
||||
import io.dapr.client.Headers;
|
||||
import io.dapr.config.Properties;
|
||||
import io.grpc.CallOptions;
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.ClientCall;
|
||||
import io.grpc.ClientInterceptor;
|
||||
import io.grpc.ForwardingClientCall;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.MethodDescriptor;
|
||||
|
||||
/**
|
||||
* Class to be used as part of your service's client stub interceptor to include Dapr tokens.
|
||||
*/
|
||||
public class DaprApiTokenInterceptor implements ClientInterceptor {
|
||||
|
||||
@Override
|
||||
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
|
||||
MethodDescriptor<ReqT, RespT> methodDescriptor,
|
||||
CallOptions options,
|
||||
Channel channel) {
|
||||
ClientCall<ReqT, RespT> clientCall = channel.newCall(methodDescriptor, options);
|
||||
return new ForwardingClientCall.SimpleForwardingClientCall<>(clientCall) {
|
||||
@Override
|
||||
public void start(final Listener<RespT> responseListener, final Metadata metadata) {
|
||||
String daprApiToken = Properties.API_TOKEN.get();
|
||||
if (daprApiToken != null) {
|
||||
metadata.put(Metadata.Key.of(Headers.DAPR_API_TOKEN, Metadata.ASCII_STRING_MARSHALLER), daprApiToken);
|
||||
}
|
||||
super.start(responseListener, metadata);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 2024 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.internal.grpc.interceptors;
|
||||
|
||||
import io.grpc.CallOptions;
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.ClientCall;
|
||||
import io.grpc.ClientInterceptor;
|
||||
import io.grpc.ForwardingClientCall;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.MethodDescriptor;
|
||||
|
||||
/**
|
||||
* Class to be used as part of your service's client stub interceptor to include Dapr App Id metadata.
|
||||
*/
|
||||
public class DaprAppIdInterceptor implements ClientInterceptor {
|
||||
|
||||
private final Metadata extraHeaders;
|
||||
|
||||
public DaprAppIdInterceptor(String appId) {
|
||||
this.extraHeaders = buildMetadata(appId);
|
||||
}
|
||||
|
||||
private static final Metadata buildMetadata(String appId) {
|
||||
if (appId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Metadata headers = new Metadata();
|
||||
headers.put(Metadata.Key.of("dapr-app-id", Metadata.ASCII_STRING_MARSHALLER), appId);
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
|
||||
MethodDescriptor<ReqT, RespT> methodDescriptor,
|
||||
CallOptions options,
|
||||
Channel channel) {
|
||||
ClientCall<ReqT, RespT> clientCall = channel.newCall(methodDescriptor, options);
|
||||
final Metadata extraHeaders = this.extraHeaders;
|
||||
return new ForwardingClientCall.SimpleForwardingClientCall<>(clientCall) {
|
||||
@Override
|
||||
public void start(ClientCall.Listener<RespT> responseListener, Metadata headers) {
|
||||
if (extraHeaders != null) {
|
||||
headers.merge(extraHeaders);
|
||||
}
|
||||
super.start(responseListener, headers);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2024 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.internal.grpc.interceptors;
|
||||
|
||||
import io.dapr.internal.resiliency.TimeoutPolicy;
|
||||
import io.grpc.CallOptions;
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.ClientCall;
|
||||
import io.grpc.ClientInterceptor;
|
||||
import io.grpc.MethodDescriptor;
|
||||
|
||||
/**
|
||||
* Class to be used as part of your service's client stub interceptor to include timeout.
|
||||
*/
|
||||
public class DaprTimeoutInterceptor implements ClientInterceptor {
|
||||
|
||||
private final TimeoutPolicy timeoutPolicy;
|
||||
|
||||
public DaprTimeoutInterceptor(TimeoutPolicy timeoutPolicy) {
|
||||
this.timeoutPolicy = timeoutPolicy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
|
||||
MethodDescriptor<ReqT, RespT> methodDescriptor,
|
||||
CallOptions options,
|
||||
Channel channel) {
|
||||
if (timeoutPolicy == null) {
|
||||
return channel.newCall(methodDescriptor, options);
|
||||
}
|
||||
|
||||
return channel.newCall(methodDescriptor, timeoutPolicy.apply(options));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright 2024 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.internal.grpc.interceptors;
|
||||
|
||||
import io.dapr.internal.opencensus.GrpcHelper;
|
||||
import io.grpc.CallOptions;
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.ClientCall;
|
||||
import io.grpc.ClientInterceptor;
|
||||
import io.grpc.ForwardingClientCall;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.MethodDescriptor;
|
||||
import reactor.util.context.ContextView;
|
||||
|
||||
/**
|
||||
* Injects tracing headers to gRPC metadata.
|
||||
*/
|
||||
public class DaprTracingInterceptor implements ClientInterceptor {
|
||||
|
||||
private final ContextView context;
|
||||
|
||||
/**
|
||||
* Creates an instance of the injector for gRPC context from Reactor's context.
|
||||
* @param context Reactor's context
|
||||
*/
|
||||
public DaprTracingInterceptor(ContextView context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
|
||||
MethodDescriptor<ReqT, RespT> methodDescriptor,
|
||||
CallOptions callOptions,
|
||||
Channel channel) {
|
||||
ClientCall<ReqT, RespT> clientCall = channel.newCall(methodDescriptor, callOptions);
|
||||
return new ForwardingClientCall.SimpleForwardingClientCall<>(clientCall) {
|
||||
@Override
|
||||
public void start(final Listener<RespT> responseListener, final Metadata metadata) {
|
||||
if (context != null) {
|
||||
GrpcHelper.populateMetadata(context, metadata);
|
||||
}
|
||||
super.start(responseListener, metadata);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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.internal.opencensus;
|
||||
|
||||
import io.grpc.Metadata;
|
||||
import reactor.util.context.Context;
|
||||
import reactor.util.context.ContextView;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Helper to extract tracing information for gRPC calls.
|
||||
*/
|
||||
public final class GrpcHelper {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(GrpcHelper.class.getName());
|
||||
|
||||
/**
|
||||
* Binary formatter to generate grpc-trace-bin.
|
||||
*/
|
||||
private static final BinaryFormatImpl OPENCENSUS_BINARY_FORMAT = new BinaryFormatImpl();
|
||||
|
||||
private static final Metadata.Key<byte[]> GRPC_TRACE_BIN_KEY =
|
||||
Metadata.Key.of("grpc-trace-bin", Metadata.BINARY_BYTE_MARSHALLER);
|
||||
|
||||
private static final Metadata.Key<String> TRACEPARENT_KEY =
|
||||
Metadata.Key.of("traceparent", Metadata.ASCII_STRING_MARSHALLER);
|
||||
|
||||
private static final Metadata.Key<String> TRACESTATE_KEY =
|
||||
Metadata.Key.of("tracestate", Metadata.ASCII_STRING_MARSHALLER);
|
||||
|
||||
private GrpcHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates GRPC client's metadata with tracing headers.
|
||||
*
|
||||
* @param context Reactor's context.
|
||||
* @param metadata GRPC client metadata to be populated.
|
||||
*/
|
||||
public static void populateMetadata(final ContextView context, final Metadata metadata) {
|
||||
Map<String, Object> map = (context == null ? Context.empty() : context)
|
||||
.stream()
|
||||
.filter(e -> (e.getKey() != null) && (e.getValue() != null))
|
||||
.collect(Collectors.toMap(e -> e.getKey().toString(), e -> e.getValue()));
|
||||
if (map.containsKey(GRPC_TRACE_BIN_KEY.name())) {
|
||||
byte[] value = (byte[]) map.get(GRPC_TRACE_BIN_KEY.name());
|
||||
metadata.put(GRPC_TRACE_BIN_KEY, value);
|
||||
}
|
||||
if (map.containsKey(TRACEPARENT_KEY.name())) {
|
||||
String value = map.get(TRACEPARENT_KEY.name()).toString();
|
||||
metadata.put(TRACEPARENT_KEY, value);
|
||||
}
|
||||
if (map.containsKey(TRACESTATE_KEY.name())) {
|
||||
String value = map.get(TRACESTATE_KEY.name()).toString();
|
||||
metadata.put(TRACESTATE_KEY, value);
|
||||
}
|
||||
|
||||
// Dapr only supports "grpc-trace-bin" for GRPC and OpenTelemetry SDK does not support that yet:
|
||||
// https://github.com/open-telemetry/opentelemetry-specification/issues/639
|
||||
// This should be the only use of OpenCensus SDK: populate "grpc-trace-bin".
|
||||
SpanContext opencensusSpanContext = extractOpenCensusSpanContext(metadata);
|
||||
if (opencensusSpanContext != null) {
|
||||
byte[] grpcTraceBin = OPENCENSUS_BINARY_FORMAT.toByteArray(opencensusSpanContext);
|
||||
metadata.put(GRPC_TRACE_BIN_KEY, grpcTraceBin);
|
||||
}
|
||||
}
|
||||
|
||||
private static SpanContext extractOpenCensusSpanContext(Metadata metadata) {
|
||||
if (!metadata.keys().contains(TRACEPARENT_KEY.name())) {
|
||||
// Trying to extract context without this key will throw an "expected" exception, so we avoid it here.
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return TraceContextFormat.extract(metadata);
|
||||
} catch (RuntimeException e) {
|
||||
LOGGER.log(Level.FINE, "Could not extract span context.", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,122 +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.internal.opencensus;
|
||||
|
||||
import io.dapr.config.Property;
|
||||
import io.dapr.v1.DaprGrpc;
|
||||
import io.grpc.CallOptions;
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.ClientCall;
|
||||
import io.grpc.ClientInterceptor;
|
||||
import io.grpc.ForwardingClientCall;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.MethodDescriptor;
|
||||
import reactor.util.context.Context;
|
||||
import reactor.util.context.ContextView;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Wraps a Dapr gRPC stub with telemetry interceptor.
|
||||
*/
|
||||
public final class GrpcWrapper {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(Property.class.getName());
|
||||
|
||||
/**
|
||||
* Binary formatter to generate grpc-trace-bin.
|
||||
*/
|
||||
private static final BinaryFormatImpl OPENCENSUS_BINARY_FORMAT = new BinaryFormatImpl();
|
||||
|
||||
private static final Metadata.Key<byte[]> GRPC_TRACE_BIN_KEY =
|
||||
Metadata.Key.of("grpc-trace-bin", Metadata.BINARY_BYTE_MARSHALLER);
|
||||
|
||||
private static final Metadata.Key<String> TRACEPARENT_KEY =
|
||||
Metadata.Key.of("traceparent", Metadata.ASCII_STRING_MARSHALLER);
|
||||
|
||||
private static final Metadata.Key<String> TRACESTATE_KEY =
|
||||
Metadata.Key.of("tracestate", Metadata.ASCII_STRING_MARSHALLER);
|
||||
|
||||
private GrpcWrapper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates GRPC client with interceptors.
|
||||
*
|
||||
* @param context Reactor's context.
|
||||
* @param client GRPC client for Dapr.
|
||||
* @return Client after adding interceptors.
|
||||
*/
|
||||
public static DaprGrpc.DaprStub intercept(final ContextView context, DaprGrpc.DaprStub client) {
|
||||
ClientInterceptor interceptor = new ClientInterceptor() {
|
||||
@Override
|
||||
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
|
||||
MethodDescriptor<ReqT, RespT> methodDescriptor,
|
||||
CallOptions callOptions,
|
||||
Channel channel) {
|
||||
ClientCall<ReqT, RespT> clientCall = channel.newCall(methodDescriptor, callOptions);
|
||||
return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(clientCall) {
|
||||
@Override
|
||||
public void start(final Listener<RespT> responseListener, final Metadata metadata) {
|
||||
Map<String, Object> map = (context == null ? Context.empty() : context)
|
||||
.stream()
|
||||
.filter(e -> (e.getKey() != null) && (e.getValue() != null))
|
||||
.collect(Collectors.toMap(e -> e.getKey().toString(), e -> e.getValue()));
|
||||
if (map.containsKey(GRPC_TRACE_BIN_KEY.name())) {
|
||||
byte[] value = (byte[]) map.get(GRPC_TRACE_BIN_KEY.name());
|
||||
metadata.put(GRPC_TRACE_BIN_KEY, value);
|
||||
}
|
||||
if (map.containsKey(TRACEPARENT_KEY.name())) {
|
||||
String value = map.get(TRACEPARENT_KEY.name()).toString();
|
||||
metadata.put(TRACEPARENT_KEY, value);
|
||||
}
|
||||
if (map.containsKey(TRACESTATE_KEY.name())) {
|
||||
String value = map.get(TRACESTATE_KEY.name()).toString();
|
||||
metadata.put(TRACESTATE_KEY, value);
|
||||
}
|
||||
|
||||
// Dapr only supports "grpc-trace-bin" for GRPC and OpenTelemetry SDK does not support that yet:
|
||||
// https://github.com/open-telemetry/opentelemetry-specification/issues/639
|
||||
// This should be the only use of OpenCensus SDK: populate "grpc-trace-bin".
|
||||
SpanContext opencensusSpanContext = extractOpenCensusSpanContext(metadata);
|
||||
if (opencensusSpanContext != null) {
|
||||
byte[] grpcTraceBin = OPENCENSUS_BINARY_FORMAT.toByteArray(opencensusSpanContext);
|
||||
metadata.put(GRPC_TRACE_BIN_KEY, grpcTraceBin);
|
||||
}
|
||||
|
||||
super.start(responseListener, metadata);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
return client.withInterceptors(interceptor);
|
||||
}
|
||||
|
||||
private static SpanContext extractOpenCensusSpanContext(Metadata metadata) {
|
||||
if (!metadata.keys().contains(TRACEPARENT_KEY.name())) {
|
||||
// Trying to extract context without this key will throw an "expected" exception, so we avoid it here.
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return TraceContextFormat.extract(metadata);
|
||||
} catch (RuntimeException e) {
|
||||
LOGGER.log(Level.FINE, "Could not extract span context.", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,8 +13,6 @@ limitations under the License.
|
|||
|
||||
package io.dapr.utils;
|
||||
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
|
|
|
@ -15,11 +15,8 @@ package io.dapr.client;
|
|||
|
||||
import io.dapr.client.domain.CloudEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class CloudEventCustom<T> extends CloudEvent<T> {
|
||||
|
||||
|
|
|
@ -13,16 +13,15 @@ limitations under the License.
|
|||
|
||||
package io.dapr.client;
|
||||
|
||||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
import io.dapr.utils.TypeRef;
|
||||
|
||||
public class CloudEventCustomTest {
|
||||
|
||||
private DaprObjectSerializer serializer = new DefaultObjectSerializer();
|
||||
|
|
|
@ -16,7 +16,6 @@ package io.dapr.client;
|
|||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
|
|
@ -15,10 +15,10 @@ package io.dapr.client;
|
|||
|
||||
import io.dapr.client.domain.HttpExtension;
|
||||
import io.dapr.client.domain.InvokeMethodRequest;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import io.dapr.internal.grpc.DaprClientGrpcInterceptors;
|
||||
import io.dapr.v1.CommonProtos;
|
||||
import io.dapr.v1.DaprGrpc;
|
||||
import io.dapr.v1.DaprProtos;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.ServerCall;
|
||||
|
@ -28,6 +28,7 @@ import io.grpc.ServerInterceptors;
|
|||
import io.grpc.ServerServiceDefinition;
|
||||
import io.grpc.inprocess.InProcessChannelBuilder;
|
||||
import io.grpc.inprocess.InProcessServerBuilder;
|
||||
import io.grpc.stub.StreamObserver;
|
||||
import io.grpc.testing.GrpcCleanupRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
@ -36,15 +37,16 @@ import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
|||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.Mockito;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.publisher.MonoSink;
|
||||
import reactor.util.context.Context;
|
||||
import reactor.util.context.ContextView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import reactor.util.context.ContextView;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
|
@ -67,6 +69,8 @@ public class DaprClientGrpcTelemetryTest {
|
|||
@Rule
|
||||
public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule();
|
||||
|
||||
private DaprGrpc.DaprStub daprStub;
|
||||
|
||||
private DaprClient client;
|
||||
|
||||
@AfterEach
|
||||
|
@ -144,10 +148,7 @@ null,
|
|||
|
||||
// Create a client channel and register for automatic graceful shutdown.
|
||||
ManagedChannel channel = InProcessChannelBuilder.forName(serverName).directExecutor().build();
|
||||
DaprGrpc.DaprStub asyncStub = DaprGrpc.newStub(channel);
|
||||
DaprHttp daprHTTP = Mockito.mock(DaprHttp.class);
|
||||
client = new DaprClientGrpc(
|
||||
new GrpcChannelFacade(channel, daprHTTP), asyncStub, new DefaultObjectSerializer(), new DefaultObjectSerializer());
|
||||
daprStub = DaprGrpc.newStub(channel);
|
||||
}
|
||||
|
||||
public void setup() throws IOException {
|
||||
|
@ -184,11 +185,7 @@ null,
|
|||
|
||||
// Create a client channel and register for automatic graceful shutdown.
|
||||
ManagedChannel channel = InProcessChannelBuilder.forName(serverName).directExecutor().build();
|
||||
DaprGrpc.DaprStub asyncStub = DaprGrpc.newStub(channel);
|
||||
|
||||
DaprHttp daprHTTP = Mockito.mock(DaprHttp.class);
|
||||
client = new DaprClientGrpc(
|
||||
new GrpcChannelFacade(channel, daprHTTP), asyncStub, new DefaultObjectSerializer(), new DefaultObjectSerializer());
|
||||
this.daprStub = DaprGrpc.newStub(channel);
|
||||
}
|
||||
|
||||
|
||||
|
@ -214,10 +211,7 @@ null,
|
|||
}
|
||||
|
||||
final Context contextCopy = context;
|
||||
InvokeMethodRequest req = new InvokeMethodRequest("appId", "method")
|
||||
.setBody("request")
|
||||
.setHttpExtension(HttpExtension.NONE);
|
||||
Mono<Void> result = this.client.invokeMethod(req, TypeRef.get(Void.class))
|
||||
Mono<Void> result = this.invoke()
|
||||
.contextWrite(it -> it.putAll(contextCopy));
|
||||
result.block();
|
||||
}
|
||||
|
@ -233,8 +227,42 @@ null,
|
|||
InvokeMethodRequest req = new InvokeMethodRequest("appId", "method")
|
||||
.setBody("request")
|
||||
.setHttpExtension(HttpExtension.NONE);
|
||||
Mono<Void> result = this.client.invokeMethod(req, TypeRef.get(Void.class))
|
||||
Mono<Void> result = this.invoke()
|
||||
.contextWrite(it -> it.putAll(contextCopy == null ? (ContextView) Context.empty() : contextCopy));
|
||||
result.block();
|
||||
}
|
||||
|
||||
private Mono<Void> invoke() {
|
||||
DaprProtos.InvokeServiceRequest req =
|
||||
DaprProtos.InvokeServiceRequest.newBuilder()
|
||||
.build();
|
||||
return Mono.deferContextual(
|
||||
context -> this.<CommonProtos.InvokeResponse>createMono(
|
||||
it -> DaprClientGrpcInterceptors.intercept(daprStub, context).invokeService(req, it)
|
||||
)
|
||||
).then();
|
||||
}
|
||||
|
||||
private <T> Mono<T> createMono(Consumer<StreamObserver<T>> consumer) {
|
||||
return Mono.create(sink -> consumer.accept(createStreamObserver(sink)));
|
||||
}
|
||||
|
||||
private <T> StreamObserver<T> createStreamObserver(MonoSink<T> sink) {
|
||||
return new StreamObserver<T>() {
|
||||
@Override
|
||||
public void onNext(T value) {
|
||||
sink.success(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable t) {
|
||||
sink.error(new ExecutionException(t));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
sink.success();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import io.dapr.client.domain.DeleteStateRequest;
|
|||
import io.dapr.client.domain.ExecuteStateTransactionRequest;
|
||||
import io.dapr.client.domain.GetBulkStateRequest;
|
||||
import io.dapr.client.domain.GetStateRequest;
|
||||
import io.dapr.client.domain.HttpExtension;
|
||||
import io.dapr.client.domain.PublishEventRequest;
|
||||
import io.dapr.client.domain.State;
|
||||
import io.dapr.client.domain.StateOptions;
|
||||
|
@ -45,7 +44,6 @@ import org.junit.jupiter.api.Test;
|
|||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
@ -63,7 +61,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.dapr.utils.TestUtils.assertThrowsDaprException;
|
||||
import static io.dapr.utils.TestUtils.findFreePort;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
@ -72,7 +69,12 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
|||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.argThat;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class DaprClientGrpcTest {
|
||||
|
||||
|
@ -84,6 +86,7 @@ public class DaprClientGrpcTest {
|
|||
|
||||
private GrpcChannelFacade channel;
|
||||
private DaprGrpc.DaprStub daprStub;
|
||||
private DaprHttp daprHttp;
|
||||
private DaprClient client;
|
||||
private ObjectSerializer serializer;
|
||||
|
||||
|
@ -91,10 +94,10 @@ public class DaprClientGrpcTest {
|
|||
public void setup() throws IOException {
|
||||
channel = mock(GrpcChannelFacade.class);
|
||||
daprStub = mock(DaprGrpc.DaprStub.class);
|
||||
daprHttp = mock(DaprHttp.class);
|
||||
when(daprStub.withInterceptors(any())).thenReturn(daprStub);
|
||||
DaprClient grpcClient = new DaprClientGrpc(
|
||||
channel, daprStub, new DefaultObjectSerializer(), new DefaultObjectSerializer());
|
||||
client = new DaprClientProxy(grpcClient);
|
||||
client = new DaprClientImpl(
|
||||
channel, daprStub, daprHttp, new DefaultObjectSerializer(), new DefaultObjectSerializer());
|
||||
serializer = new ObjectSerializer();
|
||||
doNothing().when(channel).close();
|
||||
}
|
||||
|
@ -105,18 +108,6 @@ public class DaprClientGrpcTest {
|
|||
verify(channel).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void waitForSidecarTimeout() {
|
||||
Mockito.doReturn(Mono.error(new RuntimeException())).when(channel).waitForChannelReady(1);
|
||||
assertThrows(RuntimeException.class, () -> client.waitForSidecar(1).block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void waitForSidecarOK() {
|
||||
Mockito.doReturn(Mono.empty()).when(channel).waitForChannelReady(10000);
|
||||
client.waitForSidecar(10000).block();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publishEventExceptionThrownTest() {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
|
@ -150,7 +141,7 @@ public class DaprClientGrpcTest {
|
|||
@Test
|
||||
public void publishEventSerializeException() throws IOException {
|
||||
DaprObjectSerializer mockSerializer = mock(DaprObjectSerializer.class);
|
||||
client = new DaprClientGrpc(channel, daprStub, mockSerializer, new DefaultObjectSerializer());
|
||||
client = new DaprClientImpl(channel, daprStub, daprHttp, mockSerializer, new DefaultObjectSerializer());
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<Empty> observer = (StreamObserver<Empty>) invocation.getArguments()[1];
|
||||
observer.onNext(Empty.getDefaultInstance());
|
||||
|
@ -268,7 +259,7 @@ public class DaprClientGrpcTest {
|
|||
@Test
|
||||
public void invokeBindingSerializeException() throws IOException {
|
||||
DaprObjectSerializer mockSerializer = mock(DaprObjectSerializer.class);
|
||||
client = new DaprClientGrpc(channel, daprStub, mockSerializer, new DefaultObjectSerializer());
|
||||
client = new DaprClientImpl(channel, daprStub, daprHttp, mockSerializer, new DefaultObjectSerializer());
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<Empty> observer = (StreamObserver<Empty>) invocation.getArguments()[1];
|
||||
observer.onNext(Empty.getDefaultInstance());
|
||||
|
@ -419,440 +410,6 @@ public class DaprClientGrpcTest {
|
|||
assertFalse(called.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceVoidExceptionThrownTest() {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
throw new RuntimeException();
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<Void> result = client.invokeMethod("appId", "method", "request", HttpExtension.NONE);
|
||||
|
||||
assertThrowsDaprException(
|
||||
RuntimeException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: ",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceIllegalArgumentExceptionThrownTest() {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny("Value")).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
// HttpExtension cannot be null
|
||||
Mono<Void> result = client.invokeMethod("appId", "method", "request", null);
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceEmptyRequestVoidExceptionThrownTest() {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
throw new RuntimeException();
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<Void> result = client.invokeMethod("appId", "method", HttpExtension.NONE, (Map<String, String>)null);
|
||||
|
||||
assertThrowsDaprException(
|
||||
RuntimeException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: ",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceVoidCallbackExceptionThrownTest() {
|
||||
RuntimeException ex = new RuntimeException("An Exception");
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onError(ex);
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<Void> result = client.invokeMethod("appId", "method", "request", HttpExtension.NONE);
|
||||
|
||||
assertThrowsDaprException(
|
||||
ExecutionException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: java.lang.RuntimeException: An Exception",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceVoidTest() {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny("Value")).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<Void> result = client.invokeMethod("appId", "method", "request", HttpExtension.NONE);
|
||||
result.block();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceVoidObjectTest() {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny("Value")).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
MyObject request = new MyObject(1, "Event");
|
||||
Mono<Void> result = client.invokeMethod("appId", "method", request, HttpExtension.NONE);
|
||||
result.block();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceExceptionThrownTest() {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
throw new RuntimeException();
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<String> result = client.invokeMethod("appId", "method", "request", HttpExtension.NONE, null, String.class);
|
||||
|
||||
assertThrowsDaprException(
|
||||
RuntimeException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: ",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceNoRequestClassExceptionThrownTest() {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
throw new RuntimeException();
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<String> result = client.invokeMethod("appId", "method", HttpExtension.NONE, (Map<String, String>)null, String.class);
|
||||
|
||||
assertThrowsDaprException(
|
||||
RuntimeException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: ",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceNoRequestTypeRefExceptionThrownTest() {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
throw new RuntimeException();
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<String> result = client.invokeMethod("appId", "method", HttpExtension.NONE, (Map<String, String>)null, TypeRef.STRING);
|
||||
|
||||
assertThrowsDaprException(
|
||||
RuntimeException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: ",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceCallbackExceptionThrownTest() {
|
||||
RuntimeException ex = new RuntimeException("An Exception");
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onError(ex);
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<String> result = client.invokeMethod("appId", "method", "request", HttpExtension.NONE, null, String.class);
|
||||
|
||||
assertThrowsDaprException(
|
||||
ExecutionException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: java.lang.RuntimeException: An Exception",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceWithHttpExtensionTest() throws IOException {
|
||||
HttpExtension httpExtension = new HttpExtension(
|
||||
DaprHttp.HttpMethods.GET, Collections.singletonMap("test", Arrays.asList("1", "ab/c")), null);
|
||||
CommonProtos.InvokeRequest message = CommonProtos.InvokeRequest.newBuilder()
|
||||
.setMethod("method")
|
||||
.setData(getAny("request"))
|
||||
.setContentType("application/json")
|
||||
.setHttpExtension(CommonProtos.HTTPExtension.newBuilder()
|
||||
.setVerb(CommonProtos.HTTPExtension.Verb.GET)
|
||||
.setQuerystring("test=1&test=ab%2Fc").build())
|
||||
.build();
|
||||
DaprProtos.InvokeServiceRequest request = DaprProtos.InvokeServiceRequest.newBuilder()
|
||||
.setId("appId")
|
||||
.setMessage(message)
|
||||
.build();
|
||||
String expected = "Value";
|
||||
|
||||
doAnswer(invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny(expected)).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(eq(request), any());
|
||||
|
||||
Mono<String> result = client.invokeMethod("appId", "method", "request", httpExtension, null, String.class);
|
||||
String strOutput = result.block();
|
||||
assertEquals(expected, strOutput);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceTest() {
|
||||
String expected = "Value";
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny(expected)).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<String> result = client.invokeMethod("appId", "method", "request", HttpExtension.NONE, null, String.class);
|
||||
String strOutput = result.block();
|
||||
|
||||
assertEquals(expected, strOutput);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceObjectTest() throws Exception {
|
||||
MyObject object = new MyObject(1, "Value");
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny(object)).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<MyObject> result = client.invokeMethod("appId", "method", "request", HttpExtension.NONE, null, MyObject.class);
|
||||
MyObject resultObject = result.block();
|
||||
|
||||
assertEquals(object.id, resultObject.id);
|
||||
assertEquals(object.value, resultObject.value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceNoRequestBodyExceptionThrownTest() {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
throw new RuntimeException();
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<String> result = client.invokeMethod("appId", "method", (Object)null, HttpExtension.NONE, String.class);
|
||||
|
||||
assertThrowsDaprException(
|
||||
RuntimeException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: ",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceNoRequestCallbackExceptionThrownTest() {
|
||||
RuntimeException ex = new RuntimeException("An Exception");
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onError(ex);
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<String> result = client.invokeMethod("appId", "method", (Object)null, HttpExtension.NONE, String.class);
|
||||
|
||||
assertThrowsDaprException(
|
||||
ExecutionException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: java.lang.RuntimeException: An Exception",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceNoRequestBodyTest() throws Exception {
|
||||
String expected = "Value";
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny(expected)).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<String> result = client.invokeMethod("appId", "method", (Object)null, HttpExtension.NONE, String.class);
|
||||
String strOutput = result.block();
|
||||
|
||||
assertEquals(expected, strOutput);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceNoRequestBodyObjectTest() throws Exception {
|
||||
MyObject object = new MyObject(1, "Value");
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny(object)).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<MyObject> result = client.invokeMethod("appId", "method", (Object)null, HttpExtension.NONE, MyObject.class);
|
||||
MyObject resultObject = result.block();
|
||||
|
||||
assertEquals(object.id, resultObject.id);
|
||||
assertEquals(object.value, resultObject.value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceByteRequestExceptionThrownTest() throws IOException {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
throw new RuntimeException();
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
String request = "Request";
|
||||
byte[] byteRequest = serializer.serialize(request);
|
||||
|
||||
Mono<byte[]> result = client.invokeMethod("appId", "method", byteRequest, HttpExtension.NONE, byte[].class);
|
||||
|
||||
assertThrowsDaprException(
|
||||
RuntimeException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: ",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceByteRequestCallbackExceptionThrownTest() throws IOException {
|
||||
RuntimeException ex = new RuntimeException("An Exception");
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onError(ex);
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
String request = "Request";
|
||||
byte[] byteRequest = serializer.serialize(request);
|
||||
|
||||
Mono<byte[]> result =
|
||||
client.invokeMethod("appId", "method", byteRequest, HttpExtension.NONE,(HashMap<String, String>) null);
|
||||
|
||||
assertThrowsDaprException(
|
||||
ExecutionException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: java.lang.RuntimeException: An Exception",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeByteRequestServiceTest() throws Exception {
|
||||
String expected = "Value";
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny(expected)).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
String request = "Request";
|
||||
byte[] byteRequest = serializer.serialize(request);
|
||||
|
||||
Mono<byte[]> result = client.invokeMethod(
|
||||
"appId", "method", byteRequest, HttpExtension.NONE, (HashMap<String, String>) null);
|
||||
byte[] byteOutput = result.block();
|
||||
|
||||
String strOutput = serializer.deserialize(byteOutput, String.class);
|
||||
assertEquals(expected, strOutput);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceByteRequestObjectTest() throws Exception {
|
||||
MyObject resultObj = new MyObject(1, "Value");
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny(resultObj)).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
String request = "Request";
|
||||
byte[] byteRequest = serializer.serialize(request);
|
||||
Mono<byte[]> result = client.invokeMethod("appId", "method", byteRequest, HttpExtension.NONE, byte[].class);
|
||||
byte[] byteOutput = result.block();
|
||||
|
||||
assertEquals(resultObj, serializer.deserialize(byteOutput, MyObject.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceNoRequestNoClassBodyExceptionThrownTest() {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
throw new RuntimeException();
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
Mono<Void> result = client.invokeMethod("appId", "method", (Object)null, HttpExtension.NONE);
|
||||
|
||||
assertThrowsDaprException(
|
||||
RuntimeException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: ",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceNoRequestNoClassCallbackExceptionThrownTest() {
|
||||
RuntimeException ex = new RuntimeException("An Exception");
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onError(ex);
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<Void> result = client.invokeMethod("appId", "method", (Object)null, HttpExtension.NONE);
|
||||
|
||||
assertThrowsDaprException(
|
||||
ExecutionException.class,
|
||||
"UNKNOWN",
|
||||
"UNKNOWN: java.lang.RuntimeException: An Exception",
|
||||
() -> result.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceNoRequestNoClassBodyTest() {
|
||||
String expected = "Value";
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny(expected)).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<Void> result = client.invokeMethod("appId", "method", (Object)null, HttpExtension.NONE);
|
||||
result.block();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceNoRequestNoHotMono() {
|
||||
AtomicBoolean called = new AtomicBoolean(false);
|
||||
String expected = "Value";
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
called.set(true);
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny(expected)).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
client.invokeMethod("appId", "method", (Object)null, HttpExtension.NONE);
|
||||
// Do not call block() on mono above, so nothing should happen.
|
||||
assertFalse(called.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeServiceNoRequestNoClassBodyObjectTest() throws Exception {
|
||||
MyObject resultObj = new MyObject(1, "Value");
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<CommonProtos.InvokeResponse> observer = (StreamObserver<CommonProtos.InvokeResponse>) invocation.getArguments()[1];
|
||||
observer.onNext(CommonProtos.InvokeResponse.newBuilder().setData(getAny(resultObj)).build());
|
||||
observer.onCompleted();
|
||||
return null;
|
||||
}).when(daprStub).invokeService(any(DaprProtos.InvokeServiceRequest.class), any());
|
||||
|
||||
Mono<Void> result = client.invokeMethod("appId", "method", (Object)null, HttpExtension.NONE);
|
||||
result.block();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getStateIllegalArgumentExceptionTest() {
|
||||
State<String> key = buildStateKey(null, "Key1", "ETag1", null);
|
||||
|
@ -1429,7 +986,7 @@ public class DaprClientGrpcTest {
|
|||
@Test
|
||||
public void executeTransactionSerializerExceptionTest() throws IOException {
|
||||
DaprObjectSerializer mockSerializer = mock(DaprObjectSerializer.class);
|
||||
client = new DaprClientGrpc(channel, daprStub, mockSerializer, mockSerializer);
|
||||
client = new DaprClientImpl(channel, daprStub, daprHttp, mockSerializer, mockSerializer);
|
||||
String etag = "ETag1";
|
||||
String key = "key1";
|
||||
String data = "my data";
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,80 +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.HttpExtension;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import static org.mockito.Mockito.times;
|
||||
|
||||
public class DaprClientProxyTest {
|
||||
|
||||
@Test
|
||||
public void stateAPI() {
|
||||
DaprClient client1 = Mockito.mock(DaprClient.class);
|
||||
DaprClient client2 = Mockito.mock(DaprClient.class);
|
||||
|
||||
Mockito.when(client1.saveState("state", "key", "value")).thenReturn(Mono.empty());
|
||||
Mockito.when(client2.saveState("state", "key", "value")).thenReturn(Mono.empty());
|
||||
|
||||
DaprClient proxy = new DaprClientProxy(client1, client2);
|
||||
proxy.saveState("state", "key", "value").block();
|
||||
|
||||
Mockito.verify(client1, times(1)).saveState("state", "key", "value");
|
||||
Mockito.verify(client2, times(0)).saveState("state", "key", "value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodInvocationAPI() {
|
||||
DaprClient client1 = Mockito.mock(DaprClient.class);
|
||||
DaprClient client2 = Mockito.mock(DaprClient.class);
|
||||
|
||||
Mockito.when(client1.invokeMethod("appId", "methodName", "body", HttpExtension.POST))
|
||||
.thenReturn(Mono.empty());
|
||||
Mockito.when(client2.invokeMethod("appId", "methodName", "body", HttpExtension.POST))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
DaprClient proxy = new DaprClientProxy(client1, client2);
|
||||
proxy.invokeMethod("appId", "methodName", "body", HttpExtension.POST).block();
|
||||
|
||||
Mockito.verify(client1, times(0))
|
||||
.invokeMethod("appId", "methodName", "body", HttpExtension.POST);
|
||||
Mockito.verify(client2, times(1))
|
||||
.invokeMethod("appId", "methodName", "body", HttpExtension.POST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void closeAllClients() throws Exception {
|
||||
DaprClient client1 = Mockito.mock(DaprClient.class);
|
||||
DaprClient client2 = Mockito.mock(DaprClient.class);
|
||||
|
||||
DaprClient proxy = new DaprClientProxy(client1, client2);
|
||||
proxy.close();
|
||||
|
||||
Mockito.verify(client1, times(1)).close();
|
||||
Mockito.verify(client2, times(1)).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void closeSingleClient() throws Exception {
|
||||
DaprClient client1 = Mockito.mock(DaprClient.class);
|
||||
|
||||
DaprClient proxy = new DaprClientProxy(client1);
|
||||
proxy.close();
|
||||
|
||||
Mockito.verify(client1, times(1)).close();
|
||||
}
|
||||
|
||||
}
|
|
@ -13,17 +13,19 @@ limitations under the License.
|
|||
|
||||
package io.dapr.client;
|
||||
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
|
||||
/**
|
||||
* Builder for DaprClient used in tests only.
|
||||
*/
|
||||
public class DaprClientTestBuilder {
|
||||
|
||||
/**
|
||||
* Builds a DaprClient.
|
||||
* Builds a DaprClient only for HTTP calls.
|
||||
* @param client DaprHttp used for http calls (can be mocked or stubbed)
|
||||
* @return New instance of DaprClient.
|
||||
*/
|
||||
public static DaprClient buildHttpClient(DaprHttp client) {
|
||||
return new DaprClientHttp(client);
|
||||
public static DaprClient buildClientForHttpOnly(DaprHttp client) {
|
||||
return new DaprClientImpl(null, null, client, new DefaultObjectSerializer(), new DefaultObjectSerializer());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,16 +40,17 @@ import static org.mockito.Mockito.when;
|
|||
public class DaprExceptionTest {
|
||||
private GrpcChannelFacade channel;
|
||||
private DaprGrpc.DaprStub daprStub;
|
||||
private DaprHttp daprHttp;
|
||||
private DaprClient client;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws IOException {
|
||||
channel = mock(GrpcChannelFacade.class);
|
||||
daprStub = mock(DaprGrpc.DaprStub.class);
|
||||
daprHttp = mock(DaprHttp.class);
|
||||
when(daprStub.withInterceptors(any())).thenReturn(daprStub);
|
||||
DaprClient grpcClient = new DaprClientGrpc(
|
||||
channel, daprStub, new DefaultObjectSerializer(), new DefaultObjectSerializer());
|
||||
client = new DaprClientProxy(grpcClient);
|
||||
client = new DaprClientImpl(
|
||||
channel, daprStub, daprHttp, new DefaultObjectSerializer(), new DefaultObjectSerializer());
|
||||
doNothing().when(channel).close();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,17 +16,17 @@ import io.dapr.config.Properties;
|
|||
import io.dapr.exceptions.DaprErrorDetails;
|
||||
import io.dapr.exceptions.DaprException;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import reactor.test.StepVerifier;
|
||||
import reactor.util.context.Context;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.mock.Behavior;
|
||||
import okhttp3.mock.MockInterceptor;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
import reactor.util.context.Context;
|
||||
import uk.org.webcompere.systemstubs.environment.EnvironmentVariables;
|
||||
import uk.org.webcompere.systemstubs.jupiter.SystemStub;
|
||||
import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;
|
||||
|
|
|
@ -17,8 +17,8 @@ package io.dapr.client;
|
|||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.dapr.client.domain.BulkPublishRequest;
|
||||
import io.dapr.client.domain.BulkPublishEntry;
|
||||
import io.dapr.client.domain.BulkPublishRequest;
|
||||
import io.dapr.client.domain.BulkPublishResponse;
|
||||
import io.dapr.client.domain.QueryStateItem;
|
||||
import io.dapr.client.domain.QueryStateRequest;
|
||||
|
@ -74,15 +74,17 @@ public class DaprPreviewClientGrpcTest {
|
|||
|
||||
private GrpcChannelFacade channel;
|
||||
private DaprGrpc.DaprStub daprStub;
|
||||
private DaprHttp daprHttp;
|
||||
private DaprPreviewClient previewClient;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws IOException {
|
||||
channel = mock(GrpcChannelFacade.class);
|
||||
daprStub = mock(DaprGrpc.DaprStub.class);
|
||||
daprHttp = mock(DaprHttp.class);
|
||||
when(daprStub.withInterceptors(any())).thenReturn(daprStub);
|
||||
previewClient = new DaprClientGrpc(
|
||||
channel, daprStub, new DefaultObjectSerializer(), new DefaultObjectSerializer());
|
||||
previewClient = new DaprClientImpl(
|
||||
channel, daprStub, daprHttp, new DefaultObjectSerializer(), new DefaultObjectSerializer());
|
||||
doNothing().when(channel).close();
|
||||
}
|
||||
|
||||
|
@ -147,7 +149,7 @@ public class DaprPreviewClientGrpcTest {
|
|||
@Test
|
||||
public void publishEventsSerializeException() throws IOException {
|
||||
DaprObjectSerializer mockSerializer = mock(DaprObjectSerializer.class);
|
||||
previewClient = new DaprClientGrpc(channel, daprStub, mockSerializer, new DefaultObjectSerializer());
|
||||
previewClient = new DaprClientImpl(channel, daprStub, daprHttp, mockSerializer, new DefaultObjectSerializer());
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
StreamObserver<DaprProtos.BulkPublishResponse> observer =
|
||||
(StreamObserver<DaprProtos.BulkPublishResponse>) invocation.getArguments()[1];
|
||||
|
|
|
@ -1,131 +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.LockRequest;
|
||||
import io.dapr.client.domain.QueryStateRequest;
|
||||
import io.dapr.client.domain.QueryStateResponse;
|
||||
import io.dapr.client.domain.UnlockRequest;
|
||||
import io.dapr.client.domain.UnlockResponseStatus;
|
||||
import io.dapr.client.domain.query.Query;
|
||||
import io.dapr.config.Properties;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.mock.Behavior;
|
||||
import okhttp3.mock.MockInterceptor;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class DaprPreviewClientHttpTest {
|
||||
|
||||
private static final String LOCK_STORE_NAME = "MyLockStore";
|
||||
|
||||
private DaprPreviewClient daprPreviewClientHttp;
|
||||
|
||||
private DaprHttp daprHttp;
|
||||
|
||||
private OkHttpClient okHttpClient;
|
||||
|
||||
private MockInterceptor mockInterceptor;
|
||||
|
||||
@BeforeEach
|
||||
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 DaprClientHttp(daprHttp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryStateExceptionsTest() {
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprPreviewClientHttp.queryState("", "query", TypeRef.BOOLEAN).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprPreviewClientHttp.queryState("", "query", String.class).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprPreviewClientHttp.queryState("storeName", "", TypeRef.BOOLEAN).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprPreviewClientHttp.queryState("storeName", "", String.class).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprPreviewClientHttp.queryState("storeName", (Query) null, TypeRef.BOOLEAN).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprPreviewClientHttp.queryState("storeName", (Query) null, String.class).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprPreviewClientHttp.queryState("storeName", (String) null, TypeRef.BOOLEAN).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprPreviewClientHttp.queryState("storeName", (String) null, String.class).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprPreviewClientHttp.queryState(null, TypeRef.BOOLEAN).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprPreviewClientHttp.queryState(new QueryStateRequest("storeName"), TypeRef.BOOLEAN).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprPreviewClientHttp.queryState(null, String.class).block();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryStateTest() {
|
||||
mockInterceptor.addRule()
|
||||
.post()
|
||||
.path("/v1.0-alpha1/state/testStore/query")
|
||||
.respond("{\"results\": [{\"key\": \"1\",\"data\": \"testData\","
|
||||
+ "\"etag\": \"6f54ad94-dfb9-46f0-a371-e42d550adb7d\"}]}");
|
||||
QueryStateResponse<String> response = daprPreviewClientHttp.queryState("testStore", "query", String.class).block();
|
||||
assertNotNull(response);
|
||||
assertEquals(1, response.getResults().size(), "result size must be 1");
|
||||
assertEquals( "1", response.getResults().get(0).getKey(), "result must be same");
|
||||
assertEquals("testData", response.getResults().get(0).getValue(), "result must be same");
|
||||
assertEquals( "6f54ad94-dfb9-46f0-a371-e42d550adb7d", response.getResults().get(0).getEtag(), "result must be same");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tryLock() {
|
||||
mockInterceptor.addRule()
|
||||
.post("http://127.0.0.1:3000/v1.0-alpha1/lock/MyLockStore")
|
||||
.respond("{ \"success\": true}");
|
||||
|
||||
LockRequest lockRequest = new LockRequest(LOCK_STORE_NAME,"1","owner",10);
|
||||
|
||||
Mono<Boolean> mono = daprPreviewClientHttp.tryLock(lockRequest);
|
||||
assertEquals(Boolean.TRUE, mono.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unLock() {
|
||||
mockInterceptor.addRule()
|
||||
.post("http://127.0.0.1:3000/v1.0-alpha1/unlock/MyLockStore")
|
||||
.respond("{ \"status\": 0}");
|
||||
|
||||
UnlockRequest unLockRequest = new UnlockRequest(LOCK_STORE_NAME,"1","owner");
|
||||
|
||||
Mono<UnlockResponseStatus> mono = daprPreviewClientHttp.unlock(unLockRequest);
|
||||
assertEquals(UnlockResponseStatus.SUCCESS, mono.block());
|
||||
}
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
/*
|
||||
* Copyright 2023 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.utils.NetworkUtils;
|
||||
import io.dapr.v1.DaprGrpc;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.ManagedChannelBuilder;
|
||||
import io.grpc.Server;
|
||||
import io.grpc.ServerBuilder;
|
||||
import io.grpc.inprocess.InProcessChannelBuilder;
|
||||
import io.grpc.inprocess.InProcessServerBuilder;
|
||||
import io.grpc.testing.GrpcCleanupRule;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.mock.Behavior;
|
||||
import okhttp3.mock.MockInterceptor;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.test.StepVerifier;
|
||||
import reactor.test.scheduler.VirtualTimeScheduler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import static io.dapr.utils.TestUtils.findFreePort;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class GrpcChannelFacadeTest {
|
||||
|
||||
private static int port;
|
||||
|
||||
public static Server server;
|
||||
|
||||
private MockInterceptor mockInterceptor;
|
||||
|
||||
private OkHttpClient okHttpClient;
|
||||
|
||||
private static DaprHttp daprHttp;
|
||||
|
||||
@Rule
|
||||
public static final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule();
|
||||
|
||||
/**
|
||||
* Enable the waitForSidecar to allow the gRPC to check the http endpoint for the health check
|
||||
*/
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
mockInterceptor = new MockInterceptor(Behavior.UNORDERED);
|
||||
okHttpClient = new OkHttpClient.Builder().addInterceptor(mockInterceptor).build();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public static void setup() throws IOException {
|
||||
port = findFreePort();
|
||||
|
||||
// Create a server, add service, start, and register for automatic graceful shutdown.
|
||||
grpcCleanup.register(ServerBuilder.forPort(port)
|
||||
.addService(new DaprGrpc.DaprImplBase() {
|
||||
})
|
||||
.build().start());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void teardown() throws InterruptedException {
|
||||
if (daprHttp != null) {
|
||||
daprHttp.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void waitForSidecarTimeoutHealthCheck() throws Exception {
|
||||
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(mockInterceptor).build();
|
||||
DaprHttp daprHttp = new DaprHttp(Properties.SIDECAR_IP.get(), 3500, okHttpClient);
|
||||
|
||||
ManagedChannel channel = InProcessChannelBuilder.forName("waitForSidecarTimeoutHealthCheck").build();
|
||||
grpcCleanup.register(channel);
|
||||
final GrpcChannelFacade channelFacade = new GrpcChannelFacade(channel, daprHttp);
|
||||
|
||||
mockInterceptor.addRule()
|
||||
.get()
|
||||
.path("/v1.0/healthz/outbound")
|
||||
.times(6)
|
||||
.respond(404, ResponseBody.create("Not Found", MediaType.get("application/json")));
|
||||
|
||||
StepVerifier.create(channelFacade.waitForChannelReady(1000))
|
||||
.expectSubscription()
|
||||
.expectError(TimeoutException.class)
|
||||
.verify(Duration.ofSeconds(20));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void waitForSidecarOK() {
|
||||
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(mockInterceptor).build();
|
||||
|
||||
DaprHttp daprHttp = new DaprHttp(Properties.SIDECAR_IP.get(), 3500, okHttpClient);
|
||||
|
||||
ManagedChannel channel = ManagedChannelBuilder.forAddress("127.0.0.1", port)
|
||||
.usePlaintext().build();
|
||||
|
||||
grpcCleanup.register(channel);
|
||||
|
||||
final GrpcChannelFacade channelFacade = new GrpcChannelFacade(channel, daprHttp);
|
||||
|
||||
// added since this is doing a check against the http health check endpoint
|
||||
// for parity with dotnet
|
||||
mockInterceptor.addRule()
|
||||
.get()
|
||||
.path("/v1.0/healthz/outbound")
|
||||
.respond(204);
|
||||
|
||||
StepVerifier.create(channelFacade.waitForChannelReady(10000))
|
||||
.expectSubscription()
|
||||
.expectComplete()
|
||||
.verify();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue