Setup auto validation of java examples (#464)

* Setup auto validation of java examples

* Update README.md

* Update validate.yml

Co-authored-by: Artur Souza <artursouza.ms@outlook.com>
This commit is contained in:
Mukundan Sundararajan 2021-01-30 16:12:51 -08:00 committed by GitHub
parent ba496064d1
commit 135b68c09b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 574 additions and 41 deletions

134
.github/workflows/validate.yml vendored Normal file
View File

@ -0,0 +1,134 @@
# ------------------------------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# ------------------------------------------------------------
name: Auto Validate Examples
on:
workflow_dispatch:
push:
branches:
- master
- release-*
tags:
- v*
pull_request:
branches:
- master
- release-*
jobs:
validate:
runs-on: ubuntu-latest
env:
GOVER: 1.15.0
GOOS: linux
GOARCH: amd64
GOPROXY: https://proxy.golang.org
JDK_VER: 13.0.x
DAPR_CLI_VER: 1.0.0-rc.4
DAPR_RUNTIME_VER: 1.0.0-rc.3
DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/3dacfb672d55f1436c249057aaebbe597e1066f3/install/install.sh
DAPR_CLI_REF:
DAPR_REF:
steps:
- uses: actions/checkout@v2
- name: Set up OpenJDK ${{ env.JDK_VER }}
uses: actions/setup-java@v1
with:
java-version: ${{ env.JDK_VER }}
- name: Set up Dapr CLI
run: wget -q ${{ env.DAPR_INSTALL_URL }} -O - | /bin/bash -s ${{ env.DAPR_CLI_VER }}
- name: Set up Go ${{ env.GOVER }}
if: env.DAPR_REF != '' || env.DAPR_CLI_REF != ''
uses: actions/setup-go@v2
with:
go-version: ${{ env.GOVER }}
- name: Checkout Dapr CLI repo to override dapr command.
uses: actions/checkout@v2
if: env.DAPR_CLI_REF != ''
with:
repository: dapr/cli
ref: ${{ env.DAPR_CLI_REF }}
path: cli
- name: Checkout Dapr repo to override daprd.
uses: actions/checkout@v2
if: env.DAPR_REF != ''
with:
repository: dapr/dapr
ref: ${{ env.DAPR_REF }}
path: dapr
- name: Build and override dapr cli with referenced commit.
if: env.DAPR_CLI_REF != ''
run: |
cd cli
make
sudo cp dist/linux_amd64/release/dapr /usr/local/bin/dapr
cd ..
- name: Initialize Dapr runtime ${{ env.DAPR_RUNTIME_VER }}
run: |
dapr uninstall --all
dapr init --runtime-version ${{ env.DAPR_RUNTIME_VER }}
- name: Build and override daprd with referenced commit.
if: env.DAPR_REF != ''
run: |
cd dapr
make
mkdir -p $HOME/.dapr/bin/
cp dist/linux_amd64/release/daprd $HOME/.dapr/bin/daprd
cd ..
- name: Override placement service.
if: env.DAPR_REF != ''
run: |
docker stop dapr_placement
cd dapr
./dist/linux_amd64/release/placement &
- name: Install utilities dependencies
run: |
echo "PATH=$PATH:$HOME/.local/bin" >> $GITHUB_ENV
pip3 install setuptools wheel
pip3 install mechanical-markdown
- name: Install Vault CLI
run: |
# From the installtion page of vault https://learn.hashicorp.com/tutorials/vault/getting-started-install?in=vault/getting-started
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update
sudo apt-get install vault
# Verify vault is installed
vault -h
- name: Clean up files
run: mvn clean
- name: Build sdk
run: mvn compile -q
- name: Install jars
run: mvn install -q
- name: Validate invoke http example
working-directory: ./examples
run: |
mm.py ./src/main/java/io/dapr/examples/invoke/http/README.md
- name: Validate invoke grpc example
working-directory: ./examples
run: |
mm.py ./src/main/java/io/dapr/examples/invoke/grpc/README.md
- name: Validate expection handling example
working-directory: ./examples
run: |
mm.py ./src/main/java/io/dapr/examples/exception/README.md
- name: Validate state example
working-directory: ./examples
run: |
mm.py ./src/main/java/io/dapr/examples/state/README.md
- name: Validate pubsub HTTP example
working-directory: ./examples
run: |
mm.py ./src/main/java/io/dapr/examples/pubsub/http/README.md
- name: Validate bindings HTTP example
working-directory: ./examples
run: |
mm.py ./src/main/java/io/dapr/examples/bindings/http/README.md
- name: Validate secrets example
working-directory: ./examples
run: |
mm.py ./src/main/java/io/dapr/examples/secrets/README.md

View File

@ -41,10 +41,10 @@ public class OutputBindingExample {
int count = 0;
while (!Thread.currentThread().isInterrupted()) {
String message = "Message #" + (count++);
String message = "Message #" + (count);
// Randomly decides between a class type or string type to be sent.
if (Math.random() >= 0.5) {
// On even number, send class message
if (count % 2 == 0) {
// This is an example of sending data in a user-defined object. The input binding will receive:
// {"message":"hello"}
MyClass myClass = new MyClass();
@ -56,6 +56,7 @@ public class OutputBindingExample {
System.out.println("sending a plain string: " + message);
client.invokeBinding(BINDING_NAME, BINDING_OPERATION, message).block();
}
count++;
try {
Thread.sleep((long) (10000 * Math.random()));

View File

@ -45,9 +45,23 @@ cd examples
### Setting Kafka locally
Before getting into the application code, follow these steps in order to setup a local instance of Kafka. This is needed for the local instances. Steps are:
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. Steps are:
1. To run container locally run:
<!-- STEP
name: Setup kafka container
expected_stderr_lines:
- 'Creating network "http_default" with the default driver'
sleep: 5
-->
```bash
docker-compose -f ./src/main/java/io/dapr/examples/bindings/http/docker-compose-single-kafka.yml up -d
```
<!-- END_STEP -->
1. Run `docker-compose -f ./src/main/java/io/dapr/examples/bindings/http/docker-compose-single-kafka.yml up -d` to run the container locally
2. Run `docker ps` to see the container running locally:
```bash
@ -93,10 +107,24 @@ public class InputBindingController {
```
Execute the follow script in order to run the Input Binding example:
```sh
<!-- STEP
name: Run input binding
expected_stdout_lines:
- '== APP == Received message through binding: {"message":"Message #0"}'
- '== APP == Received message through binding: "Message #1"'
- '== APP == Received message through binding: {"message":"Message #2"}'
- '== APP == Received message through binding: "Message #3"'
background: true
sleep: 5
-->
```bash
dapr run --components-path ./components/bindings --app-id inputbinding --app-port 3000 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.bindings.http.InputBindingExample -p 3000
```
<!-- END_STEP -->
### Running the Output binding sample
The output binding application is a simple java class with a main method that uses the Dapr Client to invoke binding.
@ -114,10 +142,10 @@ public class OutputBindingExample{
int count = 0;
while (!Thread.currentThread().isInterrupted()) {
String message = "Message #" + (count++);
String message = "Message #" + (count);
// Randomly decides between a class type or string type to be sent.
if (Math.random() >= 0.5) {
// On even number, send class message
if (count % 2 == 0) {
// This is an example of sending data in a user-defined object. The input binding will receive:
// {"message":"hello"}
MyClass myClass = new MyClass();
@ -129,6 +157,7 @@ public class OutputBindingExample{
System.out.println("sending a plain string: " + message);
client.invokeBinding(BINDING_NAME, BINDING_OPERATION, message).block();
}
count++;
try {
Thread.sleep((long) (10000 * Math.random()));
@ -149,10 +178,23 @@ This example binds two events: A user-defined data object (using the `myClass` o
Use the follow command to execute the Output Binding example:
```sh
<!-- STEP
name: Run output binding
expected_stdout_lines:
- '== APP == sending a class with message: Message #0'
- '== APP == sending a plain string: Message #1'
- '== APP == sending a class with message: Message #2'
- '== APP == sending a plain string: Message #3'
background: true
sleep: 30
-->
```bash
dapr run --components-path ./components/bindings --app-id outputbinding -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.bindings.http.OutputBindingExample
```
<!-- END_STEP -->
Once running, the OutputBindingExample should print the output as follows:
![publisheroutput](../../../../../../resources/img/outputbinding.png)
@ -165,9 +207,29 @@ Once running, the InputBindingExample should print the output as follows:
Events have been retrieved from the binding.
To stop both apps, press `CTRL+C` or run:
<!-- STEP
name: Cleanup apps
-->
```bash
dapr stop --app-id inputbinding
dapr stop --app-id outputbinding
```
<!-- END_STEP -->
For bringing down the kafka cluster that was started in the beginning, run
```sh
<!-- STEP
name: Cleanup Kafka containers
-->
```bash
docker-compose -f ./src/main/java/io/dapr/examples/bindings/http/docker-compose-single-kafka.yml down
```
<!-- END_STEP -->
For more details on Dapr Spring Boot integration, please refer to [Dapr Spring Boot](../../DaprApplication.java) Application implementation.

View File

@ -60,9 +60,36 @@ The Dapr client is also within a try-with-resource block to properly close the c
### Running the example
Run this example with the following command:
```sh
dapr run -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.exception.Client
<!-- STEP
name: Run exception example
expected_stdout_lines:
- '== APP == Error code: INVALID_ARGUMENT'
- '== APP == Error message: INVALID_ARGUMENT: state store Unknown state store is not found'
background: true
sleep: 5
-->
```bash
dapr run --app-id exception_example -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.exception.Client
```
<!-- END_STEP -->
Once running, the OutputBindingExample should print the output as follows:
![stateouput](../../../../../resources/img/exception.png)
### Cleanup
To stop the app run (or press `CTRL+C`):
<!-- STEP
name: Cleanup
-->
```bash
dapr stop --app-id exception_example
```
<!-- END_STEP -->

View File

@ -121,7 +121,8 @@ public class HelloWorldService {
String utcNowAsString = DATE_FORMAT.format(utcNow.getTime());
// Handles the request by printing message.
System.out.println("Server: " + request.getMessage() + " @ " + utcNowAsString);
System.out.println("Server: " + request.getMessage());
System.out.println("@ " + utcNowAsString);
// Now respond with current timestamp.
SayResponse.Builder responseBuilder = SayResponse.newBuilder();

View File

@ -73,10 +73,21 @@ In the `GrpcHelloWorldDaprService` class, the `onInvoke` method is the most impo
Now run the service code:
```sh
<!-- STEP
name: Run demo service
expected_stdout_lines:
- '== APP == Server: "Message #0"'
- '== APP == Server: "Message #1"'
background: true
sleep: 1
-->
```bash
dapr run --app-id hellogrpc --app-port 5000 --app-protocol grpc -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.invoke.grpc.HelloWorldService -p 5000
```
<!-- END_STEP -->
The `app-id` argument is used to identify this service in Dapr's runtime. The `app-port` determines which port Dapr's runtime should call into this service. The `protocol` argument informs Dapr which protocol it should use to invoke the application: `grpc` or `http`(default).
### Running the example's client
@ -117,10 +128,37 @@ Finally, it will go through in an infinite loop and invoke the `say` method ever
Finally, open a new command line terminal and run the client code to send some messages.
```sh
dapr run -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.invoke.grpc.HelloWorldClient
<!-- STEP
name: Run demo client
expected_stdout_lines:
- '== APP == Sending message: Message #0'
- '== APP == Message sent: Message #0'
- '== APP == Sending message: Message #1'
- '== APP == Message sent: Message #1'
background: true
sleep: 10
-->
```bash
dapr run --app-id invokegrpc -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.invoke.grpc.HelloWorldClient
```
Once the messages are sent, use `CTRL+C` to exit Dapr.
<!-- END_STEP -->
### Cleanup
To stop the apps run (or press CTRL+C):
<!-- STEP
name: Cleanup
-->
```bash
dapr stop --app-id hellogrpc
dapr stop --app-id invokegrpc
```
<!-- END_STEP -->
Thanks for playing.

View File

@ -54,10 +54,10 @@ public class DemoServiceController {
String metadataString = headers == null ? "" : OBJECT_MAPPER.writeValueAsString(headers);
// Handles the request by printing message.
System.out.println(
"Server: " + message + " @ " + utcNowAsString + " and metadata: " + metadataString);
System.out.println("Server: " + message);
System.out.println("@ " + utcNowAsString + " and metadata: " + metadataString);
return utcNowAsString;
return message + " received";
} catch (Exception e) {
throw new RuntimeException(e);
}

View File

@ -94,10 +94,21 @@ public class DemoServiceController {
Use the follow command to execute the demo service example:
<!-- STEP
name: Run demo service
expected_stdout_lines:
- '== APP == Server: "message one"'
- '== APP == Server: "message two"'
background: true
sleep: 5
-->
```sh
dapr run --app-id invokedemo --app-port 3000 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.invoke.http.DemoService -p 3000
```
<!-- END_STEP -->
Once running, the ExposerService is now ready to be invoked by Dapr.
@ -130,9 +141,23 @@ public static void main(String[] args) throws Exception {
The class knows the app id for the remote application. It uses the the static `Dapr.getInstance().invokeMethod` method to invoke the remote method defining the parameters: The verb, application id, method name, and proper data and metadata, as well as the type of the expected return type. The returned payload for this method invocation is plain text and not a [JSON String](https://www.w3schools.com/js/js_json_datatypes.asp), so we expect `byte[]` to get the raw response and not try to deserialize it.
Execute the follow script in order to run the InvokeClient example, passing two messages for the remote method:
<!-- STEP
name: Run demo client
expected_stdout_lines:
- '== APP == "message one" received'
- '== APP == "message two" received'
- '== APP == Done'
background: true
sleep: 5
-->
```sh
dapr run -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.invoke.http.InvokeClient "message one" "message two"
dapr run --app-id invokeclient -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.invoke.http.InvokeClient "message one" "message two"
```
<!-- END_STEP -->
Once running, the output should display the messages sent from invoker in the demo service output as follows:
![exposeroutput](../../../../../../resources/img/exposer-service.png)
@ -140,3 +165,18 @@ Once running, the output should display the messages sent from invoker in the de
Method have been remotely invoked and displaying the remote messages.
For more details on Dapr Spring Boot integration, please refer to [Dapr Spring Boot](../../DaprApplication.java) Application implementation.
### Cleanup
To stop the apps run (or press CTRL+C):
<!-- STEP
name: Cleanup
-->
```bash
dapr stop --app-id invokedemo
dapr stop --app-id invokeclient
```
<!-- END_STEP -->

View File

@ -76,10 +76,22 @@ public class SubscriberController {
}
```
Execute the follow script in order to run the Subscriber example:
```sh
<!-- STEP
name: Run Subscriber
expected_stdout_lines:
- '== APP == Subscriber got: This is message #1'
- '== APP == Subscriber got: This is message #2'
background: true
sleep: 5
-->
```bash
dapr run --components-path ./components/pubsub --app-id subscriber --app-port 3000 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.pubsub.http.Subscriber -p 3000
```
<!-- END_STEP -->
### Running the publisher
The other component is the publisher. It is a simple java application with a main method that uses the Dapr HTTP Client to publish 10 messages to an specific topic.
@ -129,10 +141,21 @@ public class Publisher {
Use the follow command to execute the Publisher example:
```sh
<!-- STEP
name: Run Publisher
expected_stdout_lines:
- '== APP == Published message: This is message #0'
- '== APP == Published message: This is message #1'
background: true
sleep: 15
-->
```bash
dapr run --components-path ./components/pubsub --app-id publisher -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.pubsub.http.Publisher
```
<!-- END_STEP -->
Once running, the Publisher should print the output as follows:
```txt
@ -167,24 +190,34 @@ Messages have been published in the topic.
Once running, the Subscriber should print the output as follows:
```txt
== APP == Subscriber got: This is message #3
== APP == Subscriber got: {"id":"1f646657-0032-4797-b59b-c57b4f40743b","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #3","expiration":"2020-12-24T05:29:12Z"}
== APP == Subscriber got: This is message #8
== APP == Subscriber got: {"id":"a22b97ce-9008-4fba-8b57-c3c3e1f031b6","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #8","expiration":"2020-12-24T05:29:15Z"}
== APP == Subscriber got: This is message #0
== APP == Subscriber got: {"id":"abb2f110-6862-49f7-8c8d-189f6dcd177d","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #0","expiration":"2020-12-24T05:29:11Z"}
== APP == Subscriber got: This is message #7
== APP == Subscriber got: {"id":"043f31d3-c13a-4a02-ac89-64ecca946598","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #7","expiration":"2020-12-24T05:29:14Z"}
== APP == Subscriber got: This is message #2
== APP == Subscriber got: {"id":"acc554f4-7109-4c31-9374-0e5936b90180","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #2","expiration":"2020-12-24T05:29:12Z"}
== APP == Subscriber got: This is message #9
== APP == Subscriber got: {"id":"8b3ad160-368d-4b0f-9925-8fa2a2fbf5ca","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #9","expiration":"2020-12-24T05:29:15Z"}
== APP == Subscriber got: This is message #1
== APP == Subscriber got: {"id":"e41d4512-511a-4a2b-80f3-a0a4d091c9a5","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #1","expiration":"2020-12-24T05:29:11Z"}
== APP == Subscriber got: This is message #4
== APP == Subscriber got: {"id":"33e21664-128e-4fc4-b5c4-ed257f758336","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #4","expiration":"2020-12-24T05:29:13Z"}
== APP == Subscriber got: This is message #6
== APP == Subscriber got: {"id":"bd14f1ee-ca6b-47f7-8130-dd1e6de5b03c","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #6","expiration":"2020-12-24T05:29:14Z"}
== APP == Subscriber got: This is message #5
== APP == Subscriber got: {"id":"acc57cd6-71da-4ba3-9a12-9c921ca49af7","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #5","expiration":"2020-12-24T05:29:13Z"}
```
@ -244,3 +277,16 @@ No message is consumed by the subscriber app and warnings messages are emitted f
```
For more details on Dapr Spring Boot integration, please refer to [Dapr Spring Boot](../../DaprApplication.java) Application implementation.
### Cleanup
<!-- STEP
name: Cleanup
-->
```bash
dapr stop --app-id publisher
dapr stop --app-id subscriber
```
<!-- END_STEP -->

View File

@ -31,6 +31,7 @@ public class SubscriberController {
public Mono<Void> handleMessage(@RequestBody(required = false) CloudEvent cloudEvent) {
return Mono.fromRunnable(() -> {
try {
System.out.println("Subscriber got: " + cloudEvent.getData());
System.out.println("Subscriber got: " + OBJECT_MAPPER.writeValueAsString(cloudEvent));
} catch (Exception e) {
throw new RuntimeException(e);

View File

@ -50,7 +50,22 @@ cd examples
Before getting into the application code, follow these steps in order to set up a local instance of Vault. This is needed for the local instances. Steps are:
1. Run `docker-compose -f ./src/main/java/io/dapr/examples/secrets/docker-compose-vault.yml up -d` to run the container locally
1. To run the vault container locally run:
<!-- Docker is writing output to stderr ... -->
<!-- STEP
name: Start vault
expected_stderr_lines:
- 'Creating network "secrets_default" with the default driver'
sleep: 10
-->
```bash
docker-compose -f ./src/main/java/io/dapr/examples/secrets/docker-compose-vault.yml up -d
```
<!-- END_STEP -->
2. Run `docker ps` to see the container running locally:
```bash
@ -68,20 +83,55 @@ export VAULT_ADDR=http://127.0.0.1:8200/
```
Login to Hashicorp's Vault:
<!-- STEP
name: Vault login
expected_stdout_lines:
- "Success! You are now authenticated. The token information displayed below"
- "token myroot"
env:
VAULT_ADDR: "http://127.0.0.1:8200/"
-->
```bash
vault login myroot
```
Create secret (replace `[my favorite movie]` with a title of our choice):
<!-- END_STEP -->
Create secret (replace `$MY_FAVORITE_MOVIE` with a title of our choice):
<!-- STEP
name: Create movie vault secret
expected_stdout_lines:
- "version 1"
env:
VAULT_ADDR: "http://127.0.0.1:8200/"
MY_FAVORITE_MOVIE: "Star Wars"
-->
```bash
vault kv put secret/dapr/movie title="[my favorite movie]"
vault kv put secret/dapr/movie title="$MY_FAVORITE_MOVIE"
```
<!-- END_STEP -->
Create random secret:
<!-- STEP
name: Create random vault secret
expected_stdout_lines:
- "version 1"
env:
VAULT_ADDR: "http://127.0.0.1:8200/"
-->
```bash
vault kv put secret/dapr/randomKey testVal="value"
```
<!-- END_STEP -->
In the command above, `secret` means the secret engine in Hashicorp's Vault.
Then, `dapr` is the prefix as defined in `< repo dir >/examples/components/hashicorp_vault.yaml`.
Finally, `movie` and `randomKey` are the secret names with the value set in the form of `key=value` pair.
@ -133,19 +183,44 @@ The secret store's name **must** match the component's name defined in `< repo d
The Dapr client is also within a try-with-resource block to properly close the client at the end.
Execute the following script in order to run the example:
```sh
dapr run --components-path ./components/secrets -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.secrets.SecretClient movie
<!-- STEP
name: Validate normal run
expected_stdout_lines:
- '== APP == {"title":"Star Wars"}'
- '== APP == {"testVal":"value"}'
env:
VAULT_ADDR: "http://127.0.0.1:8200/"
background: true
sleep: 5
-->
```bash
dapr run --components-path ./components/secrets --app-id secrets1 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.secrets.SecretClient movie
```
<!-- END_STEP -->
Once running, the program should print the output as follows:
```
== APP == {"title":"[my favorite movie]"}
== APP == {"title":"$MY_FAVORITE_MOVIE"}
== APP == {"testVal":"value"}
```
To close the app, press CTRL+c.
To close the app either press `CTRL+C` or run
<!-- STEP
name: Cleanup first app
-->
```bash
dapr stop --app-id secrets1
```
<!-- END_STEP -->
The example's `config.yaml` is as follows:
```yaml
@ -164,22 +239,55 @@ spec:
The configuration defines, that the only allowed secret is `movie` and all other secrets are denied.
Execute the following script in order to run this example with additional secret scoping:
<!-- STEP
name: Validate error on querying random secret
expected_stdout_lines:
- '== APP == {"title":"Star Wars"}'
- '== APP == PERMISSION_DENIED: access denied by policy to get "randomKey" from "vault"'
env:
VAULT_ADDR: "http://127.0.0.1:8200/"
background: true
sleep: 5
-->
```sh
dapr run --components-path ./components/secrets --config ./src/main/java/io/dapr/examples/secrets/config.yaml -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.secrets.SecretClient movie
dapr run --components-path ./components/secrets --config ./src/main/java/io/dapr/examples/secrets/config.yaml --app-id secrets2 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.secrets.SecretClient movie
```
<!-- END_STEP -->
Once running, the program should print the output as follows:
```
== APP == {"title":"[my favorite movie]"}
== APP == {"title":"$MY_FAVORITE_MOVIE"}
== APP == java.util.concurrent.ExecutionException: io.grpc.StatusRuntimeException: PERMISSION_DENIED: Access denied by policy to get randomKey from vault
== APP == PERMISSION_DENIED: access denied by policy to get "randomKey" from "vault"
```
To close the app, press CTRL+c.
To close the app either press `CTRL+C` or run
<!-- STEP
name: Cleanup second app
-->
```bash
dapr stop --app-id secrets2
```
<!-- END_STEP -->
To clean up and bring the vault container down, run
<!-- STEP
name: Cleanup vault container
-->
```sh
docker-compose -f ./src/main/java/io/dapr/examples/secrets/docker-compose-vault.yml down
```
<!-- END_STEP -->
Thanks for playing.

View File

@ -24,7 +24,7 @@ Then build the Maven project:
mvn install
```
Then get into the examples directory:
Then change into the `examples` directory:
```sh
cd examples
```
@ -133,11 +133,86 @@ Finally, the code tries to retrieve the deleted states, which should not be foun
The Dapr client is also within a try-with-resource block to properly close the client at the end.
### Running the example
<!-- STEP
name: Check state example
expected_stdout_lines:
- "== APP == Waiting for Dapr sidecar ..."
- "== APP == Dapr sidecar is ready."
- "== APP == Saving class with message: my message"
- "== APP == Retrieved class message from state: my message"
- "== APP == Updating previous state and adding another state 'test state'... "
- "== APP == Saving updated class with message: my message updated"
- "== APP == Retrieved messages using bulk get:"
- "== APP == StateKeyValue{value=my message updated, key='myKey', etag='2', metadata={'{}'}, error='null', options={'null'}}"
- "== APP == StateKeyValue{value=test message, key='myKey2', etag='1', metadata={'{}'}, error='null', options={'null'}}"
- "== APP == Deleting states..."
- "== APP == Verify delete key request is aborted if an etag different from stored is passed."
- "== APP == Expected failure. ABORTED"
- "== APP == Trying to delete again with correct etag."
- "== APP == Trying to retrieve deleted states:"
- "== APP == StateKeyValue{value=null, key='myKey', etag='null', metadata={'{}'}, error='null', options={'null'}}"
- "== APP == StateKeyValue{value=null, key='myKey2', etag='null', metadata={'{}'}, error='null', options={'null'}}"
- "== APP == Done"
background: true
sleep: 5
-->
Run this example with the following command:
```sh
dapr run --components-path ./components/state -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.state.StateClient 'my message'
```bash
dapr run --components-path ./components/state --app-id state_example -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.state.StateClient 'my message'
```
<!-- END_STEP -->
Once running, the OutputBindingExample should print the output as follows:
![stateouput](../../../../../resources/img/state.png)
```txt
== APP == Waiting for Dapr sidecar ...
== APP == Dapr sidecar is ready.
== APP == Saving class with message: my message
== APP == Retrieved class message from state: my message
== APP == Updating previous state and adding another state 'test state'...
== APP == Saving updated class with message: my message updated
== APP == Retrieved messages using bulk get:
== APP == StateKeyValue{value=my message updated, key='myKey', etag='2', metadata={'{}'}, error='null', options={'null'}}
== APP == StateKeyValue{value=test message, key='myKey2', etag='1', metadata={'{}'}, error='null', options={'null'}}
== APP == Deleting states...
== APP == Verify delete key request is aborted if an etag different from stored is passed.
== APP == Expected failure. ABORTED: failed deleting state with key myKey: possible etag mismatch. error from state store: ERR Error running script (call to f_9b5da7354cb61e2ca9faff50f6c43b81c73c0b94): @user_script:1: user_script:1: failed to delete Tailmad-Fang||myKey
== APP == Trying to delete again with correct etag.
== APP == Trying to retrieve deleted states:
== APP == StateKeyValue{value=null, key='myKey', etag='null', metadata={'{}'}, error='null', options={'null'}}
== APP == StateKeyValue{value=null, key='myKey2', etag='null', metadata={'{}'}, error='null', options={'null'}}
== APP == Done
```
### Cleanup
To close the app either press `CTRL+C` or run
<!-- STEP
name: Cleanup
-->
```bash
dapr stop --app-id state_example
```
<!-- END_STEP -->

View File

@ -93,7 +93,7 @@ public class StateClient {
} catch (DaprException ex) {
if (ex.getErrorCode().equals(Status.Code.ABORTED.toString())) {
// Expected error due to etag mismatch.
System.out.println(String.format("Expected failure. %s ", ex.getMessage()));
System.out.println(String.format("Expected failure. %s", ex.getErrorCode()));
} else {
System.out.println("Unexpected exception.");
throw ex;
@ -111,7 +111,7 @@ public class StateClient {
Mono<List<State<MyClass>>> retrievedDeletedMessageMono = client.getBulkState(STATE_STORE_NAME,
Arrays.asList(FIRST_KEY_NAME, SECOND_KEY_NAME), MyClass.class);
System.out.println("Trying to retrieve deleted states: ");
System.out.println("Trying to retrieve deleted states:");
retrievedDeletedMessageMono.block().forEach(System.out::println);
// This is an example, so for simplicity we are just exiting here.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 296 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 KiB

After

Width:  |  Height:  |  Size: 41 KiB