Merge branch 'main' into feature/pubsub-macro

Signed-off-by: Zachary K Edgell <zacharyedgell@gmail.com>
This commit is contained in:
Zachary K Edgell 2024-03-20 03:46:52 -04:00 committed by GitHub
commit 075526bbb1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 706 additions and 41 deletions

View File

@ -20,6 +20,7 @@ assignees: ''
<!-- How can this issue be reproduced (be detailed) -->
## Release Note
<!-- How should the fix for this issue be communicated in our release notes? It can be populated later. -->
<!-- Keep it as a single line. Examples: -->
@ -27,4 +28,4 @@ assignees: ''
<!-- RELEASE NOTE: **FIX** Bug in Client. -->
<!-- RELEASE NOTE: **UPDATE** Client dependencies. -->
RELEASE NOTE:
RELEASE NOTE:

View File

@ -8,6 +8,8 @@ assignees: ''
---
## Describe the feature/proposal
## Release Note
<!-- How should this new feature be announced in our release notes? It can be populated later. -->
<!-- Keep it as a single line. Examples: -->
@ -15,4 +17,4 @@ assignees: ''
<!-- RELEASE NOTE: **FIX** Bug in Client. -->
<!-- RELEASE NOTE: **UPDATE** Client dependencies. -->
RELEASE NOTE:
RELEASE NOTE:

View File

@ -8,5 +8,6 @@ assignees: ''
---
## Question
<!-- Ask your question here -->
<!-- Include as much information as possible to find an answer quicker :) -->

View File

@ -6,9 +6,9 @@
## Issue reference
<!--We strive to have all PR being opened based on an issue, where the problem or feature have been discussed prior to implementation.-->
<!--We strive to have all PR being opened based on an issue, where the problem or feature should be discussed prior to implementation.-->
<!--Please reference the issue(s) with a hash tag for example #100 -->
<!--Please reference the issue(s) with a hashtag for example #100 -->
This PR will close #number
## Checklist

View File

@ -3,13 +3,13 @@ name: dapr-rust-sdk
on:
push:
branches:
- master
- main
- release-*
tags:
- v*
pull_request:
branches:
- master
- main
- release-*
env:

212
.github/workflows/validate-examples.yml vendored Normal file
View File

@ -0,0 +1,212 @@
name: validate-examples
on:
push:
branches:
- main
- release-*
tags:
- v*
pull_request:
branches:
- main
- release-*
workflow_dispatch:
inputs:
daprdapr_commit:
description: "Dapr/Dapr commit to build custom daprd from"
required: false
default: ""
daprcli_commit:
description: "Dapr/CLI commit to build custom dapr CLI from"
required: false
default: ""
repository_dispatch:
types: [validate-examples]
merge_group:
jobs:
setup:
runs-on: ubuntu-latest
env:
GOOS: linux
GOARCH: amd64
GOPROXY: https://proxy.golang.org
DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/master/install/install.sh
DAPR_CLI_REF: ${{ github.event.inputs.daprcli_commit }}
DAPR_REF: ${{ github.event.inputs.daprdapr_commit }}
CHECKOUT_REPO: ${{ github.repository }}
CHECKOUT_REF: ${{ github.ref }}
outputs:
DAPR_INSTALL_URL: ${{ env.DAPR_INSTALL_URL }}
DAPR_CLI_VER: ${{ steps.outputs.outputs.DAPR_CLI_VER }}
DAPR_RUNTIME_VER: ${{ steps.outputs.outputs.DAPR_RUNTIME_VER }}
CHECKOUT_REPO: ${{ steps.outputs.outputs.CHECKOUT_REPO }}
CHECKOUT_REF: ${{ steps.outputs.outputs.CHECKOUT_REF }}
DAPR_REF: ${{ steps.outputs.outputs.DAPR_REF }}
steps:
- name: Parse repository_dispatch payload
if: github.event_name == 'repository_dispatch'
run: |
if [ ${{ github.event.client_payload.command }} = "ok-to-test" ]; then
echo "CHECKOUT_REPO=${{ github.event.client_payload.pull_head_repo }}" >> $GITHUB_ENV
echo "CHECKOUT_REF=${{ github.event.client_payload.pull_head_ref }}" >> $GITHUB_ENV
echo "DAPR_REF=master" >> $GITHUB_ENV
fi
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "stable"
- name: Determine latest Dapr Runtime version
run: |
RUNTIME_VERSION=$(curl -s "https://api.github.com/repos/dapr/dapr/releases/latest" | grep '"tag_name"' | cut -d ':' -f2 | tr -d '",v')
echo "DAPR_RUNTIME_VER=$RUNTIME_VERSION" >> $GITHUB_ENV
echo "Found $RUNTIME_VERSION"
- name: Determine latest Dapr Cli version
run: |
CLI_VERSION=$(curl -s "https://api.github.com/repos/dapr/cli/releases/latest" | grep '"tag_name"' | cut -d ':' -f2 | tr -d '",v')
echo "DAPR_CLI_VER=$CLI_VERSION" >> $GITHUB_ENV
echo "Found $CLI_VERSION"
- name: Set up Dapr CLI
run: wget -q ${{ env.DAPR_INSTALL_URL }} -O - | /bin/bash -s ${{ env.DAPR_CLI_VER }}
- name: Checkout Dapr CLI repo to override dapr command.
uses: actions/checkout@v4
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@v4
if: env.DAPR_REF != ''
with:
repository: dapr/dapr
ref: ${{ env.DAPR_REF }}
path: dapr_runtime
- name: Build dapr cli with referenced commit.
if: env.DAPR_CLI_REF != ''
run: |
cd cli
make
mkdir -p $HOME/artifacts/$GITHUB_SHA/
sudo cp dist/linux_amd64/release/dapr $HOME/artifacts/$GITHUB_SHA/dapr
- name: Build daprd and placement with referenced commit.
if: env.DAPR_REF != ''
run: |
cd dapr_runtime
make
mkdir -p $HOME/artifacts/$GITHUB_SHA/
cp dist/linux_amd64/release/daprd $HOME/artifacts/$GITHUB_SHA/daprd
cp dist/linux_amd64/release/placement $HOME/artifacts/$GITHUB_SHA/placement
- name: Upload dapr-artifacts
uses: actions/upload-artifact@v4
if: env.DAPR_REF != '' || env.DAPR_CLI_REF != ''
with:
name: dapr-artifacts
path: $HOME/artifacts/$GITHUB_SHA/
if-no-files-found: error
retention-days: 1
compression-level: 0
- name: Outputs
id: outputs
run: |
echo "DAPR_INSTALL_URL=$DAPR_INSTALL_URL"
echo "DAPR_CLI_VER=$DAPR_CLI_VER" >> "$GITHUB_OUTPUT"
echo "DAPR_RUNTIME_VER=$DAPR_RUNTIME_VER" >> "$GITHUB_OUTPUT"
echo "CHECKOUT_REPO=$CHECKOUT_REPO" >> "$GITHUB_OUTPUT"
echo "CHECKOUT_REF=$CHECKOUT_REF" >> "$GITHUB_OUTPUT"
echo "DAPR_REF=$DAPR_REF" >> "$GITHUB_OUTPUT"
validate-example:
needs: setup
runs-on: ubuntu-latest
env:
PYTHON_VER: 3.12
DAPR_INSTALL_URL: ${{ needs.setup.outputs.DAPR_INSTALL_URL }}
DAPR_CLI_VER: ${{ needs.setup.outputs.DAPR_CLI_VER }}
DAPR_RUNTIME_VER: ${{ needs.setup.outputs.DAPR_RUNTIME_VER }}
DAPR_CLI_REF: ${{ github.event.inputs.daprcli_commit }}
DAPR_REF: ${{ github.event.inputs.daprdapr_commit }}
CHECKOUT_REPO: ${{ needs.setup.outputs.CHECKOUT_REPO }}
CHECKOUT_REF: ${{ needs.setup.outputs.CHECKOUT_REF }}
RUST_BACKTRACE: full
strategy:
fail-fast: false
matrix:
examples:
["actors", "client", "configuration", "invoke/grpc", "invoke/grpc-proxying", "pubsub", "secrets-bulk"]
steps:
- name: Check out code
uses: actions/checkout@v4
with:
repository: ${{ env.CHECKOUT_REPO }}
ref: ${{ env.CHECKOUT_REF }}
- name: Make Artifacts destination folder
if: env.DAPR_CLI_REF != '' || env.DAPR_REF != ''
run: |
mkdir -p $HOME/artifacts/$GITHUB_SHA/
- name: Retrieve dapr-artifacts
if: env.DAPR_CLI_REF != '' || env.DAPR_REF != ''
uses: actions/download-artifact@v4
with:
name: dapr-artifacts
path: $HOME/artifacts/$GITHUB_SHA/
- name: Rust setup
run: rustup toolchain install stable --profile minimal
- name: Install Protoc
uses: arduino/setup-protoc@v3
with:
version: "25.2"
- name: Set up Dapr CLI
run: wget -q ${{ env.DAPR_INSTALL_URL }} -O - | /bin/bash -s ${{ env.DAPR_CLI_VER }}
- name: Override dapr cli with referenced commit.
if: env.DAPR_CLI_REF != ''
run: |
sudo cp $HOME/artifacts/$GITHUB_SHA/dapr /usr/local/bin/dapr
- name: Initialize Dapr runtime ${{ env.DAPR_RUNTIME_VER }}
run: |
dapr uninstall --all
dapr init --runtime-version ${{ env.DAPR_RUNTIME_VER }}
- name: Override daprd and placement service with referenced commit.
if: env.DAPR_REF != ''
run: |
mkdir -p $HOME/.dapr/bin/
cp $HOME/artifacts/$GITHUB_SHA/daprd $HOME/.dapr/bin/daprd
docker stop dapr_placement
$HOME/artifacts/$GITHUB_SHA/placement --healthz-port 9091 &
- name: Set up Python ${{ env.PYTHON_VER }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VER }}
- name: Install Mechanical Markdown
run: |
python -m pip install --upgrade pip
pip install mechanical-markdown
- name: Cargo Build Examples
run: cargo build --examples
- name: Check Example
run: |
cd examples
./validate.sh ${{ matrix.examples }}

7
.gitignore vendored
View File

@ -9,3 +9,10 @@ Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
.vscode/settings.json
# Ignore logs from dapr runs
.dapr/
# OSX cruft
.DS_Store

View File

@ -10,7 +10,7 @@ readme = "README.md"
keywords = ["microservices", "dapr"]
[dependencies]
dapr-macros = {version="0.14.0", path = "macros" }
dapr-macros = { version = "0.14.0", path = "macros" }
futures = "0.3"
tonic = "0.11.0"
prost = "0.12.3"
@ -33,25 +33,25 @@ axum-test = "14.3.0"
once_cell = "1.18.0"
tokio = { version = "1", features = ["full"] }
uuid = { version = "1.4.0", features = ["v4"] }
dapr = {path="./"}
dapr = { path = "./" }
tokio-test = "0.4.2"
tokio-stream = { version = "0.1" }
[[example]]
name = "client"
path = "examples/client/client.rs"
name = "actor-client"
path = "examples/actors/client.rs"
[[example]]
name = "actor-server"
path = "examples/actors/server.rs"
[[example]]
name = "configuration"
path = "examples/configuration/main.rs"
[[example]]
name = "publisher"
path = "examples/pubsub/publisher.rs"
[[example]]
name = "subscriber"
path = "examples/pubsub/subscriber.rs"
name = "client"
path = "examples/client/client.rs"
[[example]]
name = "invoke-grpc-client"
@ -70,9 +70,13 @@ name = "invoke-grpc-proxying-server"
path = "examples/invoke/grpc-proxying/server.rs"
[[example]]
name = "actor-client"
path = "examples/actors/client.rs"
name = "publisher"
path = "examples/pubsub/publisher.rs"
[[example]]
name = "actor-server"
path = "examples/actors/server.rs"
name = "subscriber"
path = "examples/pubsub/subscriber.rs"
[[example]]
name = "secrets-bulk"
path = "examples/secrets-bulk/app.rs"

View File

@ -88,7 +88,35 @@ Use the `DaprJson` extractor to deserialize the request from Json coming from a
> docker ps
> ```
To run this example:
To run this example (using the multi-app run):
<!-- STEP
name: Run Multi-App
output_match_mode: substring
expected_stdout_lines:
- 'dapr::server::actor::runtime] registered actor MyActor'
- 'Request for actor_type: MyActor, actor_id: a1'
- '== APP - actor-server == on_activate a1'
- '== APP - actor-server == doing stuff with test'
- '== APP - actor-server == get_actor_state GetActorStateResponse { data: []'
- '== APP - actor-client == Response: Ok('
- '== APP - actor-client == MyResponse {'
- '== APP - actor-client == available: true,'
- '== APP - actor-client == },'
- '== APP - actor-client == )'
background: true
sleep: 30
timeout_seconds: 30
-->
```bash
dapr run -f .
```
<!-- END_STEP -->
### What the multi-run app will achieve:
1. Start actor host (expose Http server receiver on port 50051):
```bash
@ -98,4 +126,5 @@ dapr run --app-id actor-host --app-protocol http --app-port 50051 cargo run -- -
2. Start actor client:
```bash
dapr run --app-id actor-client --dapr-grpc-port 3502 cargo run -- --example actor-client
```

15
examples/actors/dapr.yaml Normal file
View File

@ -0,0 +1,15 @@
version: 1
common:
daprdLogDestination: console
apps:
- appID: actor-server
appDirPath: ./
appProtocol: http
appPort: 50051
logLevel: debug
command: ["cargo", "run", "--example", "actor-server"]
- appID: actor-client
appDirPath: ./
daprGRPCPort: 3502
logLevel: debug
command: ["cargo", "run", "--example", "actor-client"]

View File

@ -11,10 +11,24 @@ cargo build --examples
2. Run the example with dapr using the following command:
```
<!-- STEP
name: Run client example
output_match_mode: substring
expected_stdout_lines:
- '== APP == Successfully saved!'
- '== APP == Value is "world"'
- '== APP == Deleted value: []'
background: true
sleep: 15
timeout_seconds: 30
-->
```bash
dapr run --app-id=rustapp --dapr-grpc-port 3500 cargo run -- --example client
```
<!-- END_STEP -->
If everything went well you should see the following output along with dapr logs:
```
Successfully saved!

View File

@ -9,24 +9,70 @@ docker ps
cargo build --examples
```
2. Run the example with dapr using the following command:
2. Insert a key with the value `hello` to redis using the following command:
```bash
dapr run --app-id=rustapp --resources-path ./examples/components --dapr-grpc-port 3500 -- cargo run --example configuration
```
3. Change the value of the key `hello` in redis using the following command:
<!-- STEP
name: Insert test configuration item
output_match_mode: substring
expected_stdout_lines:
- 'OK'
background: false
sleep: 5
timeout_seconds: 5
-->
```bash
docker exec dapr_redis redis-cli MSET hello "world"
```
<!-- END_STEP -->
3. Run the example with dapr using the following command:
<!-- STEP
name: Run configuration app
output_match_mode: substring
expected_stdout_lines:
- '== APP == Configuration value: ConfigurationItem { value: "world"'
- '== APP == App subscribed to config changes with subscription id:'
- '== APP == Configuration value: {"hello": ConfigurationItem { value: "world2"'
- '== APP == App unsubscribed from config changes'
background: true
sleep: 15
timeout_seconds: 30
-->
```bash
dapr run --app-id=rustapp --resources-path ../components --dapr-grpc-port 3500 -- cargo run --example configuration
```
<!-- END_STEP -->
4. Change the value of the key `hello` in redis using the following command:
<!-- STEP
name: Update test configuration item
output_match_mode: substring
expected_stdout_lines:
- 'OK'
background: true
sleep: 5
timeout_seconds: 5
-->
```bash
docker exec dapr_redis redis-cli MSET hello "world2"
```
<!-- END_STEP -->
If everything went well you should see the following output along with dapr logs:
```
Configuration value: ConfigurationItem { value: "world", version: "", metadata: {} }
App subscribed to config changes with subscription id: "d383169a-0893-4c64-adde-fc3145b56d07"
Configuration value: {"hello": ConfigurationItem { value: "world", version: "", metadata: {} }}
Configuration value: {"hello": ConfigurationItem { value: "world2", version: "", metadata: {} }}
App unsubscribed from config changes
```

View File

@ -18,7 +18,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let key = String::from("hello");
// save key-value pair in the state store
// get key-value pair in the state store
let response = client
.get_configuration(CONFIGSTORE_NAME, vec![(&key)], None)
.await?;
@ -49,7 +49,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Function to unsubscribe from configuration updates and exit the app
async fn unsubscribe(client: &mut DaprClient, subscription_id: &str) {
match client
.unsubscribe_configuration("CONFIGSTORE_NAME", subscription_id)
.unsubscribe_configuration(CONFIGSTORE_NAME, subscription_id)
.await
{
Ok(_) => println!("App unsubscribed from config changes"),

View File

@ -11,8 +11,34 @@ cargo build --examples
2. Run the example with dapr using the following command:
<!-- STEP
name: Run Multi-app
output_match_mode: substring
match_order: none
expected_stdout_lines:
- '== APP - invoke-grpc-server == AppCallback server listening on: [::]:50051'
- '== APP - invoke-grpc-client == Response: HelloReply {'
- '== APP - invoke-grpc-client == message: "Hello Test!",'
- '== APP - invoke-grpc-client == }'
background: true
sleep: 30
timeout_seconds: 90
-->
```bash
dapr run -f .
```
dapr run --app-id=invoke-grpc-server --app-protocol grpc --app-port 50052 -- cargo run --example invoke-grpc-proxying-server
<!-- END_STEP -->
What the multi-run step effectively runs for you:
1. Runs the invoke-grpc-server:
```bash
dapr run --app-id=invoke-grpc-server --app-protocol grpc --app-port 50051 -- cargo run --example invoke-grpc-proxying-server
```
2. Runs the invoke-grpc-client:
```bash
dapr run --app-id=invoke-grpc-client -- cargo run --example invoke-grpc-proxying-client
```

View File

@ -1,3 +1,5 @@
use std::{thread, time::Duration};
use hello_world::{greeter_client::GreeterClient, HelloRequest};
use tonic::metadata::MetadataValue;
@ -8,6 +10,9 @@ pub mod hello_world {
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Sleep to allow for the server to become available
thread::sleep(Duration::from_secs(5));
// Get the Dapr port for gRPC connection
let port: u16 = std::env::var("DAPR_GRPC_PORT").unwrap().parse().unwrap();
let address = format!("https://127.0.0.1:{}", port);

View File

@ -0,0 +1,15 @@
version: 1
common:
resourcesPath: ./resources/
daprdLogDestination: console
apps:
- appID: invoke-grpc-server
appDirPath: ./
appProtocol: grpc
appPort: 50051
logLevel: debug
command: ["cargo", "run", "--example", "invoke-grpc-proxying-server"]
- appID: invoke-grpc-client
appDirPath: ./
logLevel: debug
command: ["cargo", "run", "--example", "invoke-grpc-proxying-client"]

View File

@ -0,0 +1,11 @@
apiVersion: dapr.io/v1alpha1
kind: Resiliency
metadata:
name: myresiliency
spec:
policies:
retries:
DaprBuiltInInitializationRetries:
policy: constant
maxInterval: 5s
maxRetries: 10

View File

@ -29,7 +29,7 @@ impl Greeter for GreeterService {
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let server_address = "[::]:50052".parse().unwrap();
let server_address = "[::]:50051".parse().unwrap();
let greeter_service = GreeterService::default();

View File

@ -9,10 +9,60 @@ docker ps
cargo build --examples
```
2. Run the example with dapr using the following command:
2. Run the example with dapr using the following command to start the multi-app run:
<!-- STEP
name: Run Multi-app
output_match_mode: substring
match_order: sequential
expected_stdout_lines:
- '== APP - invoke-grpc-server == Method: say_hello'
- '== APP - invoke-grpc-server == Name: "Test"'
- '== APP - invoke-grpc-client == Message: "Hello World!"'
- '== APP - invoke-grpc-client == Response: InvokeResponse {'
- '== APP - invoke-grpc-client == data: Some('
- '== APP - invoke-grpc-client == Any {'
- '== APP - invoke-grpc-client == type_url: "",'
- '== APP - invoke-grpc-client == value: ['
- '== APP - invoke-grpc-client == 10,'
- '== APP - invoke-grpc-client == 12,'
- '== APP - invoke-grpc-client == 72,'
- '== APP - invoke-grpc-client == 101,'
- '== APP - invoke-grpc-client == 108,'
- '== APP - invoke-grpc-client == 108,'
- '== APP - invoke-grpc-client == 111,'
- '== APP - invoke-grpc-client == 32,'
- '== APP - invoke-grpc-client == 87,'
- '== APP - invoke-grpc-client == 111,'
- '== APP - invoke-grpc-client == 114,'
- '== APP - invoke-grpc-client == 108,'
- '== APP - invoke-grpc-client == 100,'
- '== APP - invoke-grpc-client == 33,'
- '== APP - invoke-grpc-client == ],'
- '== APP - invoke-grpc-client == },'
- '== APP - invoke-grpc-client == ),'
- '== APP - invoke-grpc-client == content_type: "application/json",'
- '== APP - invoke-grpc-client == }'
background: true
sleep: 30
timeout_seconds: 90
-->
== APP - invoke-grpc-server == Method: say_hello
== APP - invoke-grpc-server == Name: "Test"
```bash
dapr run -f .
```
dapr run --app-id=invoke-grpc-server --app-protocol grpc --app-port 50052 -- cargo run --example invoke-grpc-server
<!-- END_STEP -->
The multi-app run is the equivalent of running:
1. The server application with dapr
```bash
dapr run --app-id=invoke-grpc-server --app-protocol grpc --app-port 50051 -- cargo run --example invoke-grpc-server
```
2. The client application
```bash
dapr run --app-id=invoke-grpc-client -- cargo run --example invoke-grpc-client
```

View File

@ -1,3 +1,5 @@
use std::{thread, time::Duration};
use hello_world::{HelloReply, HelloRequest};
use prost::Message;
@ -9,6 +11,9 @@ type DaprClient = dapr::Client<dapr::client::TonicClient>;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Sleep to allow for the server to become available
thread::sleep(Duration::from_secs(5));
// Get the Dapr port for gRPC connection
let port: u16 = std::env::var("DAPR_GRPC_PORT").unwrap().parse().unwrap();
let address = format!("https://127.0.0.1:{}", port);

View File

@ -0,0 +1,16 @@
version: 1
common:
resourcesPath: ./resources/
daprdLogDestination: console
apps:
- appID: invoke-grpc-server
appDirPath: ./
appProtocol: grpc
appPort: 50051
logLevel: debug
command: ["cargo", "run", "--example", "invoke-grpc-server"]
- appID: invoke-grpc-client
appDirPath: ./
appProtocol: grpc
logLevel: debug
command: ["cargo", "run", "--example", "invoke-grpc-client"]

View File

@ -0,0 +1,11 @@
apiVersion: dapr.io/v1alpha1
kind: Resiliency
metadata:
name: myresiliency
spec:
policies:
retries:
DaprBuiltInInitializationRetries:
policy: constant
maxInterval: 5s
maxRetries: 10

View File

@ -92,7 +92,7 @@ impl AppCallback for AppCallbackService {
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let server_address = "[::]:50052".parse().unwrap();
let server_address = "[::]:50051".parse().unwrap();
let callback_service = AppCallbackService {};

View File

@ -16,12 +16,42 @@ This is a simple example that demonstrates Dapr's pub/sub capabilities. To imple
To run this example:
1. Start Subscriber (expose gRPC server receiver on port 50051):
1. Run the multi-app run template:
<!-- STEP
name: Run Subscriber
output_match_mode: substring
match_order: none
expected_stdout_lines:
- '== APP - rust-subscriber == Message: 0 => hello from rust!'
- '== APP - rust-subscriber == Content-Type: text/plain'
- '== APP - rust-subscriber == Message: 1 => hello from rust!'
- '== APP - rust-subscriber == Content-Type: text/plain'
- '== APP - rust-subscriber == Message: 2 => hello from rust!'
- '== APP - rust-subscriber == Content-Type: text/plain'
- '== APP - rust-publisher == messages published'
background: true
sleep: 30
timeout_seconds: 90
-->
```bash
dapr run -f .
```
<!-- END_STEP -->
2. Stop with `ctrl + c`
### Running without multi-app
1. Run the subscriber with dapr
```bash
dapr run --app-id rust-subscriber --app-protocol grpc --app-port 50051 cargo run -- --example subscriber
```
2. Start Publisher:
2. Run the publisher with dapr
```bash
dapr run --app-id rust-publisher --app-protocol grpc cargo run -- --example publisher
```

16
examples/pubsub/dapr.yaml Normal file
View File

@ -0,0 +1,16 @@
version: 1
common:
resourcesPath: ./resources/
daprdLogDestination: console
apps:
- appID: rust-subscriber
appDirPath: ./
appProtocol: grpc
appPort: 50051
logLevel: debug
command: ["cargo", "run", "--example", "subscriber"]
- appID: rust-publisher
appDirPath: ./
appProtocol: grpc
logLevel: debug
command: ["cargo", "run", "--example", "publisher"]

View File

@ -36,7 +36,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// topic to publish message to
let topic = "A".to_string();
let topic_b = "B".to_string();
for count in 0..10 {
@ -61,10 +60,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
)
.await?;
// sleep for 2 secs to simulate delay b/w two events
tokio::time::sleep(Duration::from_secs(2)).await;
// sleep for 1 second to simulate delay between each event
tokio::time::sleep(Duration::from_secs(1)).await;
}
for count in 0..10 {
let refund = Refund {
order_number: count,
@ -90,6 +88,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// sleep for 2 secs to simulate delay b/w two events
tokio::time::sleep(Duration::from_secs(2)).await;
}
println!("messages published");
Ok(())
}

View File

@ -0,0 +1,12 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: pubsub
spec:
type: pubsub.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""

View File

@ -0,0 +1,11 @@
apiVersion: dapr.io/v1alpha1
kind: Resiliency
metadata:
name: myresiliency
spec:
policies:
retries:
DaprBuiltInInitializationRetries:
policy: constant
maxInterval: 5s
maxRetries: 10

View File

@ -0,0 +1,39 @@
Before you run the example make sure local redis state store is running by executing:
```
docker ps
```
1. To run the example we need to first build the examples using the following command:
```
cargo build --examples
```
2. Run the example with dapr using the following command:
<!-- STEP
name: Run app example
output_match_mode: substring
match_order: none
expected_stdout_lines:
- '== APP == Found secret1 with value: TestSecret1'
- '== APP == Found secret2 with value: TestSecret2'
- '== APP == Found secret3 with value: TestSecret3'
background: true
sleep: 15
timeout_seconds: 30
-->
```bash
dapr run --app-id=rustapp --dapr-grpc-port 3500 --resources-path ./resources/ cargo run -- --example secrets-bulk
```
<!-- END_STEP -->
If everything went well you should see the following output along with dapr logs:
```
== APP == Found secret1 with value: TestSecret1
== APP == Found secret2 with value: TestSecret2
== APP == Found secret3 with value: TestSecret3
```
_Note: The order of the secrets returned is not ordered_

View File

@ -0,0 +1,23 @@
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Get the Dapr port and create a connection
let port: u16 = std::env::var("DAPR_GRPC_PORT")?.parse()?;
let addr = format!("https://127.0.0.1:{}", port);
// Create the client
let mut client = dapr::Client::<dapr::client::TonicClient>::connect(addr).await?;
let secret_store = "localsecretstore";
let secrets_response = client.get_bulk_secret(secret_store, None).await?;
for (secret_name, secret_content) in &secrets_response.data {
println!(
"Found {} with value: {}",
secret_name,
&secret_content.secrets.get(secret_name).unwrap()
);
}
Ok(())
}

View File

@ -0,0 +1,13 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: localsecretstore
namespace: default
spec:
type: secretstores.local.file
version: v1
metadata:
- name: secretsFile
value: secrets.json
- name: nestedSeparator
value: ":"

View File

@ -0,0 +1,5 @@
{
"secret1": "TestSecret1",
"secret2": "TestSecret2",
"secret3": "TestSecret3"
}

6
examples/validate.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/sh
set -e
echo "Home: $HOME"
cd $1
mm.py README.md

View File

@ -128,6 +128,27 @@ impl<T: DaprInterface> Client<T> {
.await
}
/// Get all secrets for a given store
///
/// # Arguments
///
/// * `store_name` - The name of the secret store.
pub async fn get_bulk_secret<S>(
&mut self,
store_name: S,
metadata: Option<HashMap<String, String>>,
) -> Result<GetBulkSecretResponse, Error>
where
S: Into<String>,
{
self.0
.get_bulk_secret(GetBulkSecretRequest {
store_name: store_name.into(),
metadata: metadata.unwrap_or_default(),
})
.await
}
/// Get the state for a specific key.
///
/// # Arguments
@ -373,6 +394,10 @@ pub trait DaprInterface: Sized {
request: InvokeBindingRequest,
) -> Result<InvokeBindingResponse, Error>;
async fn get_secret(&mut self, request: GetSecretRequest) -> Result<GetSecretResponse, Error>;
async fn get_bulk_secret(
&mut self,
request: GetBulkSecretRequest,
) -> Result<GetBulkSecretResponse, Error>;
async fn get_state(&mut self, request: GetStateRequest) -> Result<GetStateResponse, Error>;
async fn save_state(&mut self, request: SaveStateRequest) -> Result<(), Error>;
async fn delete_state(&mut self, request: DeleteStateRequest) -> Result<(), Error>;
@ -434,6 +459,16 @@ impl DaprInterface for dapr_v1::dapr_client::DaprClient<TonicChannel> {
Ok(self.get_secret(Request::new(request)).await?.into_inner())
}
async fn get_bulk_secret(
&mut self,
request: GetBulkSecretRequest,
) -> Result<GetBulkSecretResponse, Error> {
Ok(self
.get_bulk_secret(Request::new(request))
.await?
.into_inner())
}
async fn get_state(&mut self, request: GetStateRequest) -> Result<GetStateResponse, Error> {
Ok(self.get_state(Request::new(request)).await?.into_inner())
}
@ -538,6 +573,12 @@ pub type GetSecretRequest = dapr_v1::GetSecretRequest;
/// A response from getting secret
pub type GetSecretResponse = dapr_v1::GetSecretResponse;
/// A request for getting bulk secrets
pub type GetBulkSecretRequest = dapr_v1::GetBulkSecretRequest;
/// A response for getting bulk secrets
pub type GetBulkSecretResponse = dapr_v1::GetBulkSecretResponse;
/// A response from getting metadata
pub type GetMetadataResponse = dapr_v1::GetMetadataResponse;