Skip to content

Commit 68e3238

Browse files
authored
Merge branch 'main' into resiliency-implementation
2 parents a0b506d + 396f571 commit 68e3238

File tree

10 files changed

+411
-7
lines changed

10 files changed

+411
-7
lines changed

.github/holopin.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
organization: dapr
2-
defaultSticker: clmjkxscc122740fl0mkmb7egi
2+
defaultSticker: clrqfdv4x24910fl5n4iwu5oa
33
stickers:
4-
-
5-
id: clmjkxscc122740fl0mkmb7egi
6-
alias: ghc2023
4+
- id: clrqfdv4x24910fl5n4iwu5oa
5+
alias: sdk-badge

.github/workflows/validate-examples.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ jobs:
144144
fail-fast: false
145145
matrix:
146146
examples:
147-
[ "actors", "client", "configuration", "crypto", "invoke/grpc", "invoke/grpc-proxying", "pubsub", "secrets-bulk" ]
147+
[ "actors", "client", "configuration", "crypto", "invoke/grpc", "invoke/grpc-proxying", "pubsub", "query_state", "secrets-bulk" ]
148148
steps:
149149
- name: Check out code
150150
uses: actions/checkout@v4

Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ path = "examples/pubsub/publisher.rs"
8282
name = "subscriber"
8383
path = "examples/pubsub/subscriber.rs"
8484

85+
[[example]]
86+
name = "query_state_q1"
87+
path = "examples/query_state/query1.rs"
88+
89+
[[example]]
90+
name = "query_state_q2"
91+
path = "examples/query_state/query2.rs"
92+
8593
[[example]]
8694
name = "secrets-bulk"
8795
path = "examples/secrets-bulk/app.rs"

examples/pubsub/subscriber.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
3535

3636
let mut callback_service = AppCallbackService::new();
3737

38-
callback_service.add_handler(HandleAEvent::default().get_handler());
38+
callback_service.add_handler(HandleAEvent.get_handler());
3939

40-
callback_service.add_handler(HandleBEvent::default().get_handler());
40+
callback_service.add_handler(HandleBEvent.get_handler());
4141

4242
println!("AppCallback server listening on: {}", addr);
4343

examples/query_state/README.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Query state Example
2+
To run this example, the default local redis state store will not work as it does not support redis-json server. You will encounter the following error
3+
```
4+
GrpcError(GrpcError { _status: Status { code: Internal, message: "failed query in state store statestore: redis-json server support is required for query capability", metadata: MetadataMap { headers: {"content-type": "application/grpc", "grpc-trace-bin": "AABniqIo9TrSF6TepfB0yzgNAZzAwpG45zK0AgE"} }, source: None } })
5+
```
6+
7+
See [Querying JSON objects(optional)](https://docs.dapr.io/reference/components-reference/supported-state-stores/setup-redis/#querying-json-objects-optional) for creation of a redis instance that supports querying json objects.
8+
9+
For this example, we will be following the query state example in the [Dapr docs](https://docs.dapr.io/developing-applications/building-blocks/state-management/howto-state-query-api/#example-data-and-query) and will be using mongo instead.
10+
11+
To setup MongoDB, execute the following command:
12+
<!-- STEP
13+
name: Run mongodb instance
14+
background: false
15+
sleep: 10
16+
timeout_seconds: 30
17+
-->
18+
```bash
19+
docker run -d --rm -p 27017:27017 --name mongodb mongo:5
20+
```
21+
<!-- END_STEP -->
22+
23+
You can then apply the statestore configuration using the `statestore/mongodb.yaml` file.
24+
25+
Then, execute the following commands to populate the state data in the statestore:
26+
27+
<!-- STEP
28+
name: Populate state store step 1/2
29+
background: true
30+
sleep: 5
31+
timeout_seconds: 10
32+
-->
33+
```bash
34+
dapr run --app-id demo --dapr-http-port 3500 --resources-path statestore/
35+
```
36+
<!-- END_STEP -->
37+
38+
In a new terminal, apply the test data:
39+
40+
<!-- STEP
41+
name: Populate state store step 2/2
42+
background: false
43+
sleep: 2
44+
timeout_seconds: 5
45+
-->
46+
```bash
47+
curl -X POST -H "Content-Type: application/json" http://localhost:3500/v1.0/state/statestore -d @./statestore/dataset.json
48+
``````
49+
<!-- END_STEP -->
50+
51+
1. To run the example we need to first build the examples using the following command:
52+
53+
```bash
54+
cargo build --examples
55+
```
56+
57+
2. Executing the first query
58+
Query:
59+
```json
60+
{
61+
"filter": {
62+
"EQ": { "state": "CA" }
63+
},
64+
"sort": [
65+
{
66+
"key": "person.id",
67+
"order": "DESC"
68+
}
69+
]
70+
}
71+
72+
```
73+
Execute the first state query using the following command:
74+
75+
<!-- STEP
76+
name: Run query_state_q1 example
77+
output_match_mode: substring
78+
match_order: none
79+
expected_stdout_lines:
80+
- 'San Francisco'
81+
background: false
82+
sleep: 15
83+
timeout_seconds: 30
84+
-->
85+
```bash
86+
dapr run --app-id=rustapp --dapr-grpc-port 3501 --resources-path statestore/ cargo run -- --example query_state_q1
87+
```
88+
<!-- END_STEP -->
89+
90+
Expected result:
91+
```
92+
Query results: [Object {"id": String("3"), "value": String("{\"city\":\"Sacramento\",\"state\":\"CA\",\"person\":{\"org\":\"Finance\",\"id\":1071.0}}")},
93+
Object {"id": String("7"), "value": String("{\"person\":{\"org\":\"Dev Ops\",\"id\":1015.0},\"city\":\"San Francisco\",\"state\":\"CA\"}")},
94+
Object {"id": String("5"), "value": String("{\"person\":{\"org\":\"Hardware\",\"id\":1007.0},\"city\":\"Los Angeles\",\"state\":\"CA\"}")},
95+
Object {"id": String("9"), "value": String("{\"person\":{\"org\":\"Finance\",\"id\":1002.0},\"city\":\"San Diego\",\"state\":\"CA\"}")}]
96+
```
97+
98+
3. Executing the second query
99+
Query:
100+
```json
101+
{
102+
"filter": {
103+
"IN": { "person.org": [ "Dev Ops", "Hardware" ] }
104+
}
105+
}
106+
```
107+
Execute the second state query using the following command:
108+
109+
<!-- STEP
110+
name: Run query_state_q2 example
111+
output_match_mode: substring
112+
match_order: none
113+
expected_stdout_lines:
114+
- 'New York'
115+
background: false
116+
sleep: 15
117+
timeout_seconds: 30
118+
-->
119+
```bash
120+
dapr run --app-id=rustapp --dapr-grpc-port 3501 --resources-path statestore/ cargo run -- --example query_state_q2
121+
```
122+
<!-- END_STEP -->
123+
124+
Expected result:
125+
```
126+
Query results: [Object {"id": String("5"), "value": String("{\"person\":{\"org\":\"Hardware\",\"id\":1007.0},\"city\":\"Los Angeles\",\"state\":\"CA\"}")},
127+
Object {"id": String("2"), "value": String("{\"person\":{\"id\":1028.0,\"org\":\"Hardware\"},\"city\":\"Portland\",\"state\":\"OR\"}")},
128+
Object {"id": String("4"), "value": String("{\"person\":{\"org\":\"Dev Ops\",\"id\":1042.0},\"city\":\"Spokane\",\"state\":\"WA\"}")},
129+
Object {"id": String("7"), "value": String("{\"person\":{\"org\":\"Dev Ops\",\"id\":1015.0},\"city\":\"San Francisco\",\"state\":\"CA\"}")},
130+
Object {"id": String("8"), "value": String("{\"city\":\"Redmond\",\"state\":\"WA\",\"person\":{\"id\":1077.0,\"org\":\"Hardware\"}}")},
131+
Object {"id": String("10"), "value": String("{\"person\":{\"org\":\"Dev Ops\",\"id\":1054.0},\"city\":\"New York\",\"state\":\"NY\"}")},
132+
Object {"id": String("1"), "value": String("{\"person\":{\"org\":\"Dev Ops\",\"id\":1036.0},\"city\":\"Seattle\",\"state\":\"WA\"}")}]
133+
```

examples/query_state/query1.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use serde_json::json;
2+
3+
#[tokio::main]
4+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
5+
// Introduce delay so that dapr grpc port is assigned before app tries to connect
6+
std::thread::sleep(std::time::Duration::new(5, 0));
7+
8+
// Set the Dapr address and create a connection
9+
let addr = "https://127.0.0.1".to_string();
10+
11+
// Create the client
12+
let mut client = dapr::Client::<dapr::client::TonicClient>::connect(addr).await?;
13+
14+
let query_condition = json!({
15+
"filter": {
16+
"EQ": { "state": "CA" }
17+
},
18+
"sort": [
19+
{
20+
"key": "person.id",
21+
"order": "DESC"
22+
}
23+
]
24+
});
25+
26+
let response = match client
27+
.query_state_alpha1("statestore", query_condition, None)
28+
.await
29+
{
30+
Ok(response) => response.results,
31+
Err(e) => {
32+
println!("Error: {:?}", e);
33+
return Ok(());
34+
}
35+
};
36+
37+
let mut results = Vec::new();
38+
for item in response {
39+
let value = String::from_utf8(item.data).unwrap();
40+
//push id and value as json
41+
results.push(json!({
42+
"id": item.key,
43+
"value": value
44+
}));
45+
}
46+
println!("Query results: {:?}", results);
47+
48+
Ok(())
49+
}

examples/query_state/query2.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use serde_json::json;
2+
3+
#[tokio::main]
4+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
5+
// Introduce delay so that dapr grpc port is assigned before app tries to connect
6+
std::thread::sleep(std::time::Duration::new(5, 0));
7+
8+
// Set the Dapr address and create a connection
9+
let addr = "https://127.0.0.1".to_string();
10+
11+
// Create the client
12+
let mut client = dapr::Client::<dapr::client::TonicClient>::connect(addr).await?;
13+
14+
let query_condition = json!({
15+
"filter": {
16+
"IN": { "person.org": [ "Dev Ops", "Hardware" ] }
17+
},
18+
});
19+
20+
let response = match client
21+
.query_state_alpha1("statestore", query_condition, None)
22+
.await
23+
{
24+
Ok(response) => response.results,
25+
Err(e) => {
26+
println!("Error: {:?}", e);
27+
return Ok(());
28+
}
29+
};
30+
31+
let mut results = Vec::new();
32+
for item in response {
33+
let value = String::from_utf8(item.data).unwrap();
34+
//push id and value as json
35+
results.push(json!({
36+
"id": item.key,
37+
"value": value
38+
}));
39+
}
40+
println!("Query results: {:?}", results);
41+
42+
Ok(())
43+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
[
2+
{
3+
"key": "1",
4+
"value": {
5+
"person": {
6+
"org": "Dev Ops",
7+
"id": 1036
8+
},
9+
"city": "Seattle",
10+
"state": "WA"
11+
}
12+
},
13+
{
14+
"key": "2",
15+
"value": {
16+
"person": {
17+
"org": "Hardware",
18+
"id": 1028
19+
},
20+
"city": "Portland",
21+
"state": "OR"
22+
}
23+
},
24+
{
25+
"key": "3",
26+
"value": {
27+
"person": {
28+
"org": "Finance",
29+
"id": 1071
30+
},
31+
"city": "Sacramento",
32+
"state": "CA"
33+
}
34+
},
35+
{
36+
"key": "4",
37+
"value": {
38+
"person": {
39+
"org": "Dev Ops",
40+
"id": 1042
41+
},
42+
"city": "Spokane",
43+
"state": "WA"
44+
}
45+
},
46+
{
47+
"key": "5",
48+
"value": {
49+
"person": {
50+
"org": "Hardware",
51+
"id": 1007
52+
},
53+
"city": "Los Angeles",
54+
"state": "CA"
55+
}
56+
},
57+
{
58+
"key": "6",
59+
"value": {
60+
"person": {
61+
"org": "Finance",
62+
"id": 1094
63+
},
64+
"city": "Eugene",
65+
"state": "OR"
66+
}
67+
},
68+
{
69+
"key": "7",
70+
"value": {
71+
"person": {
72+
"org": "Dev Ops",
73+
"id": 1015
74+
},
75+
"city": "San Francisco",
76+
"state": "CA"
77+
}
78+
},
79+
{
80+
"key": "8",
81+
"value": {
82+
"person": {
83+
"org": "Hardware",
84+
"id": 1077
85+
},
86+
"city": "Redmond",
87+
"state": "WA"
88+
}
89+
},
90+
{
91+
"key": "9",
92+
"value": {
93+
"person": {
94+
"org": "Finance",
95+
"id": 1002
96+
},
97+
"city": "San Diego",
98+
"state": "CA"
99+
}
100+
},
101+
{
102+
"key": "10",
103+
"value": {
104+
"person": {
105+
"org": "Dev Ops",
106+
"id": 1054
107+
},
108+
"city": "New York",
109+
"state": "NY"
110+
}
111+
}
112+
]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: dapr.io/v1alpha1
2+
kind: Component
3+
metadata:
4+
name: statestore
5+
spec:
6+
type: state.mongodb
7+
version: v1
8+
metadata:
9+
- name: host
10+
value: localhost:27017

0 commit comments

Comments
 (0)