mirror of https://github.com/dapr/java-sdk.git
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:
parent
ba496064d1
commit
135b68c09b
|
|
@ -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
|
||||
|
|
@ -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()));
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||

|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||

|
||||
|
||||
### Cleanup
|
||||
|
||||
To stop the app run (or press `CTRL+C`):
|
||||
|
||||
<!-- STEP
|
||||
name: Cleanup
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr stop --app-id exception_example
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||

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

|
||||
```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 -->
|
||||
|
|
|
|||
|
|
@ -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 |
Loading…
Reference in New Issue