mirror of https://github.com/dapr/rust-sdk.git
Merge branch 'main' into feature/pubsub-macro
Signed-off-by: Zachary K Edgell <zacharyedgell@gmail.com>
This commit is contained in:
commit
075526bbb1
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -8,5 +8,6 @@ assignees: ''
|
|||
---
|
||||
## Question
|
||||
|
||||
|
||||
<!-- Ask your question here -->
|
||||
<!-- Include as much information as possible to find an answer quicker :) -->
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3,13 +3,13 @@ name: dapr-rust-sdk
|
|||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
- release-*
|
||||
tags:
|
||||
- v*
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
- release-*
|
||||
|
||||
env:
|
||||
|
|
|
@ -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 }}
|
|
@ -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
|
||||
|
|
32
Cargo.toml
32
Cargo.toml
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
```
|
||||
|
|
|
@ -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"]
|
|
@ -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!
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"]
|
|
@ -0,0 +1,11 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Resiliency
|
||||
metadata:
|
||||
name: myresiliency
|
||||
spec:
|
||||
policies:
|
||||
retries:
|
||||
DaprBuiltInInitializationRetries:
|
||||
policy: constant
|
||||
maxInterval: 5s
|
||||
maxRetries: 10
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"]
|
|
@ -0,0 +1,11 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Resiliency
|
||||
metadata:
|
||||
name: myresiliency
|
||||
spec:
|
||||
policies:
|
||||
retries:
|
||||
DaprBuiltInInitializationRetries:
|
||||
policy: constant
|
||||
maxInterval: 5s
|
||||
maxRetries: 10
|
|
@ -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 {};
|
||||
|
||||
|
|
|
@ -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
|
||||
```
|
|
@ -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"]
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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: ""
|
|
@ -0,0 +1,11 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Resiliency
|
||||
metadata:
|
||||
name: myresiliency
|
||||
spec:
|
||||
policies:
|
||||
retries:
|
||||
DaprBuiltInInitializationRetries:
|
||||
policy: constant
|
||||
maxInterval: 5s
|
||||
maxRetries: 10
|
|
@ -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_
|
|
@ -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(())
|
||||
}
|
|
@ -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: ":"
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"secret1": "TestSecret1",
|
||||
"secret2": "TestSecret2",
|
||||
"secret3": "TestSecret3"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
echo "Home: $HOME"
|
||||
|
||||
cd $1
|
||||
mm.py README.md
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue