pub struct UmaDbClient { /* private fields */ }Implementations§
Source§impl UmaDbClient
impl UmaDbClient
Sourcepub fn new(url: String) -> Self
pub fn new(url: String) -> Self
Examples found in repository?
examples/client_sync_insecure.rs (line 10)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 // Connect to the gRPC server
9 let url = "http://localhost:50051".to_string();
10 let client = UmaDbClient::new(url).connect()?;
11
12 // Define a consistency boundary
13 let boundary = DcbQuery::new().item(
14 DcbQueryItem::new()
15 .types(["example"])
16 .tags(["tag1", "tag2"]),
17 );
18
19 // Read events for a decision model
20 let mut read_response = client.read(Some(boundary.clone()), None, false, None)?;
21
22 // Build decision model
23 while let Some(result) = read_response.next() {
24 match result {
25 Ok(event) => {
26 println!(
27 "Got event at position {}: {:?}",
28 event.position, event.event
29 );
30 }
31 Err(status) => panic!("gRPC stream error: {}", status),
32 }
33 }
34
35 // Remember the last-known position
36 let last_known_position = read_response.head().unwrap();
37 println!("Last known position is: {:?}", last_known_position);
38
39 // Produce new event, attaching some metadata (e.g. provenance) that is
40 // stored alongside the event and returned when it is read back.
41 let event = DcbEvent::default()
42 .event_type("example")
43 .tags(["tag1", "tag2"])
44 .data(b"Hello, world!")
45 .uuid(Uuid::new_v4())
46 .metadata_entry("source", "client_sync_insecure")
47 .metadata_entry("correlation_id", Uuid::new_v4().to_string());
48
49 // Append event in consistency boundary
50 let append_condition = DcbAppendCondition {
51 fail_if_events_match: boundary.clone(),
52 after: last_known_position,
53 };
54 let position1 = client.append(vec![event.clone()], Some(append_condition.clone()), None)?;
55
56 println!("Appended event at position: {}", position1);
57
58 // Append conflicting event - expect an error
59 let conflicting_event = DcbEvent::default()
60 .event_type("example")
61 .tags(["tag1", "tag2"])
62 .data(b"Hello, world!")
63 .uuid(Uuid::new_v4()); // different UUID
64
65 let conflicting_result = client.append(
66 vec![conflicting_event],
67 Some(append_condition.clone()),
68 None,
69 );
70
71 // Expect an integrity error
72 match conflicting_result {
73 Err(DcbError::IntegrityError(integrity_error)) => {
74 println!("Conflicting event was rejected: {:?}", integrity_error);
75 }
76 other => panic!("Expected IntegrityError, got {:?}", other),
77 }
78
79 // Appending with identical event IDs and append condition is idempotent.
80 println!(
81 "Retrying to append event at position: {:?}",
82 last_known_position
83 );
84 let position2 = client.append(vec![event.clone()], Some(append_condition.clone()), None)?;
85
86 if position1 == position2 {
87 println!("Append method returned same commit position: {}", position2);
88 } else {
89 panic!("Expected idempotent retry!")
90 }
91
92 // Subscribe to all events for a projection
93 let mut subscription = client.subscribe(None, None)?;
94
95 // Build an up-to-date view
96 while let Some(result) = subscription.next() {
97 match result {
98 Ok(ev) => {
99 println!("Processing event at {}: {:?}", ev.position, ev.event);
100 if ev.position == position2 {
101 println!("Projection has processed new event!");
102 break;
103 }
104 }
105 Err(status) => panic!("gRPC stream error: {}", status),
106 }
107 }
108
109 // Track an upstream position
110 let upstream_position = client.get_tracking_info("upstream")?;
111 let next_upstream_position = upstream_position.unwrap_or(0) + 1;
112 println!("Next upstream position: {next_upstream_position}");
113 client.append(
114 vec![],
115 None,
116 Some(TrackingInfo {
117 source: "upstream".to_string(),
118 position: next_upstream_position,
119 }),
120 )?;
121 assert_eq!(
122 next_upstream_position,
123 client.get_tracking_info("upstream")?.unwrap()
124 );
125 println!("Upstream position tracked okay!");
126
127 // Try recording the same upstream position
128 let conflicting_result = client.append(
129 vec![],
130 None,
131 Some(TrackingInfo {
132 source: "upstream".to_string(),
133 position: next_upstream_position,
134 }),
135 );
136
137 // Expect an integrity error
138 match conflicting_result {
139 Err(DcbError::IntegrityError(integrity_error)) => {
140 println!(
141 "Conflicting upstream position was rejected: {:?}",
142 integrity_error
143 );
144 }
145 other => panic!("Expected IntegrityError, got {:?}", other),
146 }
147
148 Ok(())
149}More examples
examples/client_async_insecure.rs (line 13)
10async fn main() -> Result<(), Box<dyn std::error::Error>> {
11 // Connect to the gRPC server
12 let url = "http://localhost:50051".to_string();
13 let client = UmaDbClient::new(url).connect_async().await?;
14
15 // Define a consistency boundary
16 let boundary = DcbQuery::new().item(
17 DcbQueryItem::new()
18 .types(["example"])
19 .tags(["tag1", "tag2"]),
20 );
21
22 // Read events for a decision model
23 let mut read_response = client
24 .read(Some(boundary.clone()), None, false, None)
25 .await?;
26
27 // Build decision model
28 while let Some(result) = read_response.next().await {
29 match result {
30 Ok(event) => {
31 println!(
32 "Got event at position {}: {:?}",
33 event.position, event.event
34 );
35 }
36 Err(status) => panic!("gRPC stream error: {}", status),
37 }
38 }
39
40 // Remember the last-known position
41 let last_known_position = read_response.head().await?;
42 println!("Last known position is: {:?}", last_known_position);
43
44 // Produce new event, attaching some metadata (e.g. provenance) that is
45 // stored alongside the event and returned when it is read back.
46 let event = DcbEvent::default()
47 .event_type("example")
48 .tags(["tag1", "tag2"])
49 .data(b"Hello, world!")
50 .uuid(Uuid::new_v4())
51 .metadata_entry("source", "client_async_insecure")
52 .metadata_entry("correlation_id", Uuid::new_v4().to_string());
53
54 // Append event in consistency boundary
55 let append_condition = DcbAppendCondition {
56 fail_if_events_match: boundary.clone(),
57 after: last_known_position,
58 };
59 let position1 = client
60 .append(vec![event.clone()], Some(append_condition.clone()), None)
61 .await?;
62
63 println!("Appended event at position: {}", position1);
64
65 // Append conflicting event - expect an error
66 let conflicting_event = DcbEvent::default()
67 .event_type("example")
68 .tags(["tag1", "tag2"])
69 .data(b"Hello, world!")
70 .uuid(Uuid::new_v4()); // different UUID
71
72 let conflicting_result = client
73 .append(
74 vec![conflicting_event.clone()],
75 Some(append_condition.clone()),
76 None,
77 )
78 .await;
79
80 // Expect an integrity error
81 match conflicting_result {
82 Err(DcbError::IntegrityError(integrity_error)) => {
83 println!("Conflicting event was rejected: {:?}", integrity_error);
84 }
85 other => panic!("Expected IntegrityError, got {:?}", other),
86 }
87
88 // Appending with identical events IDs and append conditions is idempotent.
89 println!(
90 "Retrying to append event at position: {:?}",
91 last_known_position
92 );
93 let position2 = client
94 .append(vec![event.clone()], Some(append_condition.clone()), None)
95 .await?;
96
97 if position1 == position2 {
98 println!("Append method returned same commit position: {}", position2);
99 } else {
100 panic!("Expected idempotent retry!")
101 }
102
103 // Subscribe to all events for a projection
104 let mut subscription = client.subscribe(None, None).await?;
105
106 // Build an up-to-date view
107 while let Some(result) = subscription.next().await {
108 match result {
109 Ok(ev) => {
110 println!("Processing event at {}: {:?}", ev.position, ev.event);
111 if ev.position == position2 {
112 println!("Projection has processed new event!");
113 break;
114 }
115 }
116 Err(status) => panic!("gRPC stream error: {}", status),
117 }
118 }
119
120 // Track an upstream position
121 let upstream_position = client.get_tracking_info("upstream").await?;
122 let next_upstream_position = upstream_position.unwrap_or(0) + 1;
123 println!("Next upstream position: {next_upstream_position}");
124 client
125 .append(
126 vec![],
127 None,
128 Some(TrackingInfo {
129 source: "upstream".to_string(),
130 position: next_upstream_position,
131 }),
132 )
133 .await?;
134 assert_eq!(
135 next_upstream_position,
136 client.get_tracking_info("upstream").await?.unwrap()
137 );
138 println!("Upstream position tracked okay!");
139
140 // Try recording the same upstream position
141 let conflicting_result = client
142 .append(
143 vec![],
144 None,
145 Some(TrackingInfo {
146 source: "upstream".to_string(),
147 position: next_upstream_position,
148 }),
149 )
150 .await;
151
152 // Expect an integrity error
153 match conflicting_result {
154 Err(DcbError::IntegrityError(integrity_error)) => {
155 println!(
156 "Conflicting upstream position was rejected: {:?}",
157 integrity_error
158 );
159 }
160 other => panic!("Expected IntegrityError, got {:?}", other),
161 }
162
163 Ok(())
164}examples/client_sync_secure.rs (line 10)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 // Connect to the gRPC server
9 let url = "https://localhost:50051".to_string();
10 let client = UmaDbClient::new(url)
11 .ca_path("server.pem".to_string()) // For self-signed server certificates.
12 .api_key("umadb:example-api-key-4f7c2b1d9e5f4a038c1a".to_string())
13 .connect()?;
14
15 // Define a consistency boundary
16 let cb = DcbQuery {
17 items: vec![DcbQueryItem {
18 types: vec!["example".to_string()],
19 tags: vec!["tag1".to_string(), "tag2".to_string()],
20 }],
21 };
22
23 // Read events for a decision model
24 let mut read_response = client.read(Some(cb.clone()), None, false, None)?;
25
26 // Build decision model
27 while let Some(result) = read_response.next() {
28 match result {
29 Ok(event) => {
30 println!(
31 "Got event at position {}: {:?}",
32 event.position, event.event
33 );
34 }
35 Err(status) => panic!("gRPC stream error: {}", status),
36 }
37 }
38
39 // Remember the last-known position
40 let last_known_position = read_response.head().unwrap();
41 println!("Last known position is: {:?}", last_known_position);
42
43 // Produce new event, attaching some metadata (e.g. provenance) that is
44 // stored alongside the event and returned when it is read back.
45 let mut metadata = Vec::new();
46 metadata.push(("source".to_string(), "client_sync_secure".to_string()));
47 metadata.push(("correlation_id".to_string(), Uuid::new_v4().to_string()));
48 let event = DcbEvent {
49 event_type: "example".to_string(),
50 tags: vec!["tag1".to_string(), "tag2".to_string()],
51 data: b"Hello, world!".to_vec(),
52 uuid: Some(Uuid::new_v4()),
53 metadata,
54 };
55
56 // Append event in consistency boundary
57 let commit_position1 = client.append(
58 vec![event.clone()],
59 Some(DcbAppendCondition {
60 fail_if_events_match: cb.clone(),
61 after: last_known_position,
62 }),
63 None,
64 )?;
65 println!("Appended event at position: {}", commit_position1);
66
67 // Append conflicting event - expect an error
68 let conflicting_event = DcbEvent {
69 event_type: "example".to_string(),
70 tags: vec!["tag1".to_string(), "tag2".to_string()],
71 data: b"Hello, world!".to_vec(),
72 uuid: Some(Uuid::new_v4()), // different UUID
73 metadata: Vec::new(),
74 };
75 let conflicting_result = client.append(
76 vec![conflicting_event],
77 Some(DcbAppendCondition {
78 fail_if_events_match: cb.clone(),
79 after: last_known_position,
80 }),
81 None,
82 );
83
84 // Expect an integrity error
85 match conflicting_result {
86 Err(DcbError::IntegrityError(integrity_error)) => {
87 println!("Conflicting event was rejected: {:?}", integrity_error);
88 }
89 other => panic!("Expected IntegrityError, got {:?}", other),
90 }
91
92 // Conditional appends with event UUIDs are idempotent.
93 println!(
94 "Retrying to append event at position: {:?}",
95 last_known_position
96 );
97 let commit_position2 = client.append(
98 vec![event.clone()],
99 Some(DcbAppendCondition {
100 fail_if_events_match: cb.clone(),
101 after: last_known_position,
102 }),
103 None,
104 )?;
105
106 if commit_position1 == commit_position2 {
107 println!(
108 "Append method returned same commit position: {}",
109 commit_position2
110 );
111 } else {
112 panic!("Expected idempotent retry!")
113 }
114
115 // Subscribe to all events for a projection
116 let mut subscription = client.subscribe(None, None)?;
117
118 // Build an up-to-date view
119 while let Some(result) = subscription.next() {
120 match result {
121 Ok(ev) => {
122 println!("Processing event at {}: {:?}", ev.position, ev.event);
123 if ev.position == commit_position2 {
124 println!("Projection has processed new event!");
125 break;
126 }
127 }
128 Err(status) => panic!("gRPC stream error: {}", status),
129 }
130 }
131
132 // Track an upstream position
133 let upstream_position = client.get_tracking_info("upstream")?;
134 let next_upstream_position = upstream_position.unwrap_or(0) + 1;
135 println!("Next upstream position: {next_upstream_position}");
136 client.append(
137 vec![],
138 None,
139 Some(TrackingInfo {
140 source: "upstream".to_string(),
141 position: next_upstream_position,
142 }),
143 )?;
144 assert_eq!(
145 next_upstream_position,
146 client.get_tracking_info("upstream")?.unwrap()
147 );
148 println!("Upstream position tracked okay!");
149
150 // Try recording the same upstream position
151 let conflicting_result = client.append(
152 vec![],
153 None,
154 Some(TrackingInfo {
155 source: "upstream".to_string(),
156 position: next_upstream_position,
157 }),
158 );
159
160 // Expect an integrity error
161 match conflicting_result {
162 Err(DcbError::IntegrityError(integrity_error)) => {
163 println!(
164 "Conflicting upstream position was rejected: {:?}",
165 integrity_error
166 );
167 }
168 other => panic!("Expected IntegrityError, got {:?}", other),
169 }
170
171 Ok(())
172}examples/client_async_secure.rs (line 13)
10async fn main() -> Result<(), Box<dyn std::error::Error>> {
11 // Connect to the gRPC server
12 let url = "https://localhost:50051".to_string();
13 let client = UmaDbClient::new(url)
14 .ca_path("server.pem".to_string()) // For self-signed server certificates.
15 .api_key("umadb:example-api-key-4f7c2b1d9e5f4a038c1a".to_string())
16 .connect_async()
17 .await?;
18
19 // Define a consistency boundary
20 let cb = DcbQuery {
21 items: vec![DcbQueryItem {
22 types: vec!["example".to_string()],
23 tags: vec!["tag1".to_string(), "tag2".to_string()],
24 }],
25 };
26
27 // Read events for a decision model
28 let mut read_response = client.read(Some(cb.clone()), None, false, None).await?;
29
30 // Build decision model
31 while let Some(result) = read_response.next().await {
32 match result {
33 Ok(event) => {
34 println!(
35 "Got event at position {}: {:?}",
36 event.position, event.event
37 );
38 }
39 Err(status) => panic!("gRPC stream error: {}", status),
40 }
41 }
42
43 // Remember the last-known position
44 let last_known_position = read_response.head().await?;
45 println!("Last known position is: {:?}", last_known_position);
46
47 // Produce new event, attaching some metadata (e.g. provenance) that is
48 // stored alongside the event and returned when it is read back.
49 let mut metadata = Vec::new();
50 metadata.push(("source".to_string(), "client_async_secure".to_string()));
51 metadata.push(("correlation_id".to_string(), Uuid::new_v4().to_string()));
52 let event = DcbEvent {
53 event_type: "example".to_string(),
54 tags: vec!["tag1".to_string(), "tag2".to_string()],
55 data: b"Hello, world!".to_vec(),
56 uuid: Some(Uuid::new_v4()),
57 metadata,
58 };
59
60 // Append event in consistency boundary
61 let commit_position1 = client
62 .append(
63 vec![event.clone()],
64 Some(DcbAppendCondition {
65 fail_if_events_match: cb.clone(),
66 after: last_known_position,
67 }),
68 None,
69 )
70 .await?;
71 println!("Appended event at position: {}", commit_position1);
72
73 // Append conflicting event - expect an error
74 let conflicting_event = DcbEvent {
75 event_type: "example".to_string(),
76 tags: vec!["tag1".to_string(), "tag2".to_string()],
77 data: b"Hello, world!".to_vec(),
78 uuid: Some(Uuid::new_v4()), // different UUID
79 metadata: Vec::new(),
80 };
81 let conflicting_result = client
82 .append(
83 vec![conflicting_event.clone()],
84 Some(DcbAppendCondition {
85 fail_if_events_match: cb.clone(),
86 after: last_known_position,
87 }),
88 None,
89 )
90 .await;
91
92 // Expect an integrity error
93 match conflicting_result {
94 Err(DcbError::IntegrityError(integrity_error)) => {
95 println!("Conflicting event was rejected: {:?}", integrity_error);
96 }
97 other => panic!("Expected IntegrityError, got {:?}", other),
98 }
99
100 // Conditional appends with event UUIDs are idempotent.
101 println!(
102 "Retrying to append event at position: {:?}",
103 last_known_position
104 );
105 let commit_position2 = client
106 .append(
107 vec![event.clone()],
108 Some(DcbAppendCondition {
109 fail_if_events_match: cb.clone(),
110 after: last_known_position,
111 }),
112 None,
113 )
114 .await?;
115
116 if commit_position1 == commit_position2 {
117 println!(
118 "Append method returned same commit position: {}",
119 commit_position2
120 );
121 } else {
122 panic!("Expected idempotent retry!")
123 }
124
125 // Subscribe to all events for a projection
126 let mut subscription = client.subscribe(None, None).await?;
127
128 // Build an up-to-date view
129 while let Some(result) = subscription.next().await {
130 match result {
131 Ok(ev) => {
132 println!("Processing event at {}: {:?}", ev.position, ev.event);
133 if ev.position == commit_position2 {
134 println!("Projection has processed new event!");
135 break;
136 }
137 }
138 Err(status) => panic!("gRPC stream error: {}", status),
139 }
140 }
141
142 // Track an upstream position
143 let upstream_position = client.get_tracking_info("upstream").await?;
144 let next_upstream_position = upstream_position.unwrap_or(0) + 1;
145 println!("Next upstream position: {next_upstream_position}");
146 client
147 .append(
148 vec![],
149 None,
150 Some(TrackingInfo {
151 source: "upstream".to_string(),
152 position: next_upstream_position,
153 }),
154 )
155 .await?;
156 assert_eq!(
157 next_upstream_position,
158 client.get_tracking_info("upstream").await?.unwrap()
159 );
160 println!("Upstream position tracked okay!");
161
162 // Try recording the same upstream position
163 let conflicting_result = client
164 .append(
165 vec![],
166 None,
167 Some(TrackingInfo {
168 source: "upstream".to_string(),
169 position: next_upstream_position,
170 }),
171 )
172 .await;
173
174 // Expect an integrity error
175 match conflicting_result {
176 Err(DcbError::IntegrityError(integrity_error)) => {
177 println!(
178 "Conflicting upstream position was rejected: {:?}",
179 integrity_error
180 );
181 }
182 other => panic!("Expected IntegrityError, got {:?}", other),
183 }
184
185 Ok(())
186}Sourcepub fn ca_path(self, ca_path: String) -> Self
pub fn ca_path(self, ca_path: String) -> Self
Examples found in repository?
examples/client_sync_secure.rs (line 11)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 // Connect to the gRPC server
9 let url = "https://localhost:50051".to_string();
10 let client = UmaDbClient::new(url)
11 .ca_path("server.pem".to_string()) // For self-signed server certificates.
12 .api_key("umadb:example-api-key-4f7c2b1d9e5f4a038c1a".to_string())
13 .connect()?;
14
15 // Define a consistency boundary
16 let cb = DcbQuery {
17 items: vec![DcbQueryItem {
18 types: vec!["example".to_string()],
19 tags: vec!["tag1".to_string(), "tag2".to_string()],
20 }],
21 };
22
23 // Read events for a decision model
24 let mut read_response = client.read(Some(cb.clone()), None, false, None)?;
25
26 // Build decision model
27 while let Some(result) = read_response.next() {
28 match result {
29 Ok(event) => {
30 println!(
31 "Got event at position {}: {:?}",
32 event.position, event.event
33 );
34 }
35 Err(status) => panic!("gRPC stream error: {}", status),
36 }
37 }
38
39 // Remember the last-known position
40 let last_known_position = read_response.head().unwrap();
41 println!("Last known position is: {:?}", last_known_position);
42
43 // Produce new event, attaching some metadata (e.g. provenance) that is
44 // stored alongside the event and returned when it is read back.
45 let mut metadata = Vec::new();
46 metadata.push(("source".to_string(), "client_sync_secure".to_string()));
47 metadata.push(("correlation_id".to_string(), Uuid::new_v4().to_string()));
48 let event = DcbEvent {
49 event_type: "example".to_string(),
50 tags: vec!["tag1".to_string(), "tag2".to_string()],
51 data: b"Hello, world!".to_vec(),
52 uuid: Some(Uuid::new_v4()),
53 metadata,
54 };
55
56 // Append event in consistency boundary
57 let commit_position1 = client.append(
58 vec![event.clone()],
59 Some(DcbAppendCondition {
60 fail_if_events_match: cb.clone(),
61 after: last_known_position,
62 }),
63 None,
64 )?;
65 println!("Appended event at position: {}", commit_position1);
66
67 // Append conflicting event - expect an error
68 let conflicting_event = DcbEvent {
69 event_type: "example".to_string(),
70 tags: vec!["tag1".to_string(), "tag2".to_string()],
71 data: b"Hello, world!".to_vec(),
72 uuid: Some(Uuid::new_v4()), // different UUID
73 metadata: Vec::new(),
74 };
75 let conflicting_result = client.append(
76 vec![conflicting_event],
77 Some(DcbAppendCondition {
78 fail_if_events_match: cb.clone(),
79 after: last_known_position,
80 }),
81 None,
82 );
83
84 // Expect an integrity error
85 match conflicting_result {
86 Err(DcbError::IntegrityError(integrity_error)) => {
87 println!("Conflicting event was rejected: {:?}", integrity_error);
88 }
89 other => panic!("Expected IntegrityError, got {:?}", other),
90 }
91
92 // Conditional appends with event UUIDs are idempotent.
93 println!(
94 "Retrying to append event at position: {:?}",
95 last_known_position
96 );
97 let commit_position2 = client.append(
98 vec![event.clone()],
99 Some(DcbAppendCondition {
100 fail_if_events_match: cb.clone(),
101 after: last_known_position,
102 }),
103 None,
104 )?;
105
106 if commit_position1 == commit_position2 {
107 println!(
108 "Append method returned same commit position: {}",
109 commit_position2
110 );
111 } else {
112 panic!("Expected idempotent retry!")
113 }
114
115 // Subscribe to all events for a projection
116 let mut subscription = client.subscribe(None, None)?;
117
118 // Build an up-to-date view
119 while let Some(result) = subscription.next() {
120 match result {
121 Ok(ev) => {
122 println!("Processing event at {}: {:?}", ev.position, ev.event);
123 if ev.position == commit_position2 {
124 println!("Projection has processed new event!");
125 break;
126 }
127 }
128 Err(status) => panic!("gRPC stream error: {}", status),
129 }
130 }
131
132 // Track an upstream position
133 let upstream_position = client.get_tracking_info("upstream")?;
134 let next_upstream_position = upstream_position.unwrap_or(0) + 1;
135 println!("Next upstream position: {next_upstream_position}");
136 client.append(
137 vec![],
138 None,
139 Some(TrackingInfo {
140 source: "upstream".to_string(),
141 position: next_upstream_position,
142 }),
143 )?;
144 assert_eq!(
145 next_upstream_position,
146 client.get_tracking_info("upstream")?.unwrap()
147 );
148 println!("Upstream position tracked okay!");
149
150 // Try recording the same upstream position
151 let conflicting_result = client.append(
152 vec![],
153 None,
154 Some(TrackingInfo {
155 source: "upstream".to_string(),
156 position: next_upstream_position,
157 }),
158 );
159
160 // Expect an integrity error
161 match conflicting_result {
162 Err(DcbError::IntegrityError(integrity_error)) => {
163 println!(
164 "Conflicting upstream position was rejected: {:?}",
165 integrity_error
166 );
167 }
168 other => panic!("Expected IntegrityError, got {:?}", other),
169 }
170
171 Ok(())
172}More examples
examples/client_async_secure.rs (line 14)
10async fn main() -> Result<(), Box<dyn std::error::Error>> {
11 // Connect to the gRPC server
12 let url = "https://localhost:50051".to_string();
13 let client = UmaDbClient::new(url)
14 .ca_path("server.pem".to_string()) // For self-signed server certificates.
15 .api_key("umadb:example-api-key-4f7c2b1d9e5f4a038c1a".to_string())
16 .connect_async()
17 .await?;
18
19 // Define a consistency boundary
20 let cb = DcbQuery {
21 items: vec![DcbQueryItem {
22 types: vec!["example".to_string()],
23 tags: vec!["tag1".to_string(), "tag2".to_string()],
24 }],
25 };
26
27 // Read events for a decision model
28 let mut read_response = client.read(Some(cb.clone()), None, false, None).await?;
29
30 // Build decision model
31 while let Some(result) = read_response.next().await {
32 match result {
33 Ok(event) => {
34 println!(
35 "Got event at position {}: {:?}",
36 event.position, event.event
37 );
38 }
39 Err(status) => panic!("gRPC stream error: {}", status),
40 }
41 }
42
43 // Remember the last-known position
44 let last_known_position = read_response.head().await?;
45 println!("Last known position is: {:?}", last_known_position);
46
47 // Produce new event, attaching some metadata (e.g. provenance) that is
48 // stored alongside the event and returned when it is read back.
49 let mut metadata = Vec::new();
50 metadata.push(("source".to_string(), "client_async_secure".to_string()));
51 metadata.push(("correlation_id".to_string(), Uuid::new_v4().to_string()));
52 let event = DcbEvent {
53 event_type: "example".to_string(),
54 tags: vec!["tag1".to_string(), "tag2".to_string()],
55 data: b"Hello, world!".to_vec(),
56 uuid: Some(Uuid::new_v4()),
57 metadata,
58 };
59
60 // Append event in consistency boundary
61 let commit_position1 = client
62 .append(
63 vec![event.clone()],
64 Some(DcbAppendCondition {
65 fail_if_events_match: cb.clone(),
66 after: last_known_position,
67 }),
68 None,
69 )
70 .await?;
71 println!("Appended event at position: {}", commit_position1);
72
73 // Append conflicting event - expect an error
74 let conflicting_event = DcbEvent {
75 event_type: "example".to_string(),
76 tags: vec!["tag1".to_string(), "tag2".to_string()],
77 data: b"Hello, world!".to_vec(),
78 uuid: Some(Uuid::new_v4()), // different UUID
79 metadata: Vec::new(),
80 };
81 let conflicting_result = client
82 .append(
83 vec![conflicting_event.clone()],
84 Some(DcbAppendCondition {
85 fail_if_events_match: cb.clone(),
86 after: last_known_position,
87 }),
88 None,
89 )
90 .await;
91
92 // Expect an integrity error
93 match conflicting_result {
94 Err(DcbError::IntegrityError(integrity_error)) => {
95 println!("Conflicting event was rejected: {:?}", integrity_error);
96 }
97 other => panic!("Expected IntegrityError, got {:?}", other),
98 }
99
100 // Conditional appends with event UUIDs are idempotent.
101 println!(
102 "Retrying to append event at position: {:?}",
103 last_known_position
104 );
105 let commit_position2 = client
106 .append(
107 vec![event.clone()],
108 Some(DcbAppendCondition {
109 fail_if_events_match: cb.clone(),
110 after: last_known_position,
111 }),
112 None,
113 )
114 .await?;
115
116 if commit_position1 == commit_position2 {
117 println!(
118 "Append method returned same commit position: {}",
119 commit_position2
120 );
121 } else {
122 panic!("Expected idempotent retry!")
123 }
124
125 // Subscribe to all events for a projection
126 let mut subscription = client.subscribe(None, None).await?;
127
128 // Build an up-to-date view
129 while let Some(result) = subscription.next().await {
130 match result {
131 Ok(ev) => {
132 println!("Processing event at {}: {:?}", ev.position, ev.event);
133 if ev.position == commit_position2 {
134 println!("Projection has processed new event!");
135 break;
136 }
137 }
138 Err(status) => panic!("gRPC stream error: {}", status),
139 }
140 }
141
142 // Track an upstream position
143 let upstream_position = client.get_tracking_info("upstream").await?;
144 let next_upstream_position = upstream_position.unwrap_or(0) + 1;
145 println!("Next upstream position: {next_upstream_position}");
146 client
147 .append(
148 vec![],
149 None,
150 Some(TrackingInfo {
151 source: "upstream".to_string(),
152 position: next_upstream_position,
153 }),
154 )
155 .await?;
156 assert_eq!(
157 next_upstream_position,
158 client.get_tracking_info("upstream").await?.unwrap()
159 );
160 println!("Upstream position tracked okay!");
161
162 // Try recording the same upstream position
163 let conflicting_result = client
164 .append(
165 vec![],
166 None,
167 Some(TrackingInfo {
168 source: "upstream".to_string(),
169 position: next_upstream_position,
170 }),
171 )
172 .await;
173
174 // Expect an integrity error
175 match conflicting_result {
176 Err(DcbError::IntegrityError(integrity_error)) => {
177 println!(
178 "Conflicting upstream position was rejected: {:?}",
179 integrity_error
180 );
181 }
182 other => panic!("Expected IntegrityError, got {:?}", other),
183 }
184
185 Ok(())
186}Sourcepub fn api_key(self, api_key: String) -> Self
pub fn api_key(self, api_key: String) -> Self
Examples found in repository?
examples/client_sync_secure.rs (line 12)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 // Connect to the gRPC server
9 let url = "https://localhost:50051".to_string();
10 let client = UmaDbClient::new(url)
11 .ca_path("server.pem".to_string()) // For self-signed server certificates.
12 .api_key("umadb:example-api-key-4f7c2b1d9e5f4a038c1a".to_string())
13 .connect()?;
14
15 // Define a consistency boundary
16 let cb = DcbQuery {
17 items: vec![DcbQueryItem {
18 types: vec!["example".to_string()],
19 tags: vec!["tag1".to_string(), "tag2".to_string()],
20 }],
21 };
22
23 // Read events for a decision model
24 let mut read_response = client.read(Some(cb.clone()), None, false, None)?;
25
26 // Build decision model
27 while let Some(result) = read_response.next() {
28 match result {
29 Ok(event) => {
30 println!(
31 "Got event at position {}: {:?}",
32 event.position, event.event
33 );
34 }
35 Err(status) => panic!("gRPC stream error: {}", status),
36 }
37 }
38
39 // Remember the last-known position
40 let last_known_position = read_response.head().unwrap();
41 println!("Last known position is: {:?}", last_known_position);
42
43 // Produce new event, attaching some metadata (e.g. provenance) that is
44 // stored alongside the event and returned when it is read back.
45 let mut metadata = Vec::new();
46 metadata.push(("source".to_string(), "client_sync_secure".to_string()));
47 metadata.push(("correlation_id".to_string(), Uuid::new_v4().to_string()));
48 let event = DcbEvent {
49 event_type: "example".to_string(),
50 tags: vec!["tag1".to_string(), "tag2".to_string()],
51 data: b"Hello, world!".to_vec(),
52 uuid: Some(Uuid::new_v4()),
53 metadata,
54 };
55
56 // Append event in consistency boundary
57 let commit_position1 = client.append(
58 vec![event.clone()],
59 Some(DcbAppendCondition {
60 fail_if_events_match: cb.clone(),
61 after: last_known_position,
62 }),
63 None,
64 )?;
65 println!("Appended event at position: {}", commit_position1);
66
67 // Append conflicting event - expect an error
68 let conflicting_event = DcbEvent {
69 event_type: "example".to_string(),
70 tags: vec!["tag1".to_string(), "tag2".to_string()],
71 data: b"Hello, world!".to_vec(),
72 uuid: Some(Uuid::new_v4()), // different UUID
73 metadata: Vec::new(),
74 };
75 let conflicting_result = client.append(
76 vec![conflicting_event],
77 Some(DcbAppendCondition {
78 fail_if_events_match: cb.clone(),
79 after: last_known_position,
80 }),
81 None,
82 );
83
84 // Expect an integrity error
85 match conflicting_result {
86 Err(DcbError::IntegrityError(integrity_error)) => {
87 println!("Conflicting event was rejected: {:?}", integrity_error);
88 }
89 other => panic!("Expected IntegrityError, got {:?}", other),
90 }
91
92 // Conditional appends with event UUIDs are idempotent.
93 println!(
94 "Retrying to append event at position: {:?}",
95 last_known_position
96 );
97 let commit_position2 = client.append(
98 vec![event.clone()],
99 Some(DcbAppendCondition {
100 fail_if_events_match: cb.clone(),
101 after: last_known_position,
102 }),
103 None,
104 )?;
105
106 if commit_position1 == commit_position2 {
107 println!(
108 "Append method returned same commit position: {}",
109 commit_position2
110 );
111 } else {
112 panic!("Expected idempotent retry!")
113 }
114
115 // Subscribe to all events for a projection
116 let mut subscription = client.subscribe(None, None)?;
117
118 // Build an up-to-date view
119 while let Some(result) = subscription.next() {
120 match result {
121 Ok(ev) => {
122 println!("Processing event at {}: {:?}", ev.position, ev.event);
123 if ev.position == commit_position2 {
124 println!("Projection has processed new event!");
125 break;
126 }
127 }
128 Err(status) => panic!("gRPC stream error: {}", status),
129 }
130 }
131
132 // Track an upstream position
133 let upstream_position = client.get_tracking_info("upstream")?;
134 let next_upstream_position = upstream_position.unwrap_or(0) + 1;
135 println!("Next upstream position: {next_upstream_position}");
136 client.append(
137 vec![],
138 None,
139 Some(TrackingInfo {
140 source: "upstream".to_string(),
141 position: next_upstream_position,
142 }),
143 )?;
144 assert_eq!(
145 next_upstream_position,
146 client.get_tracking_info("upstream")?.unwrap()
147 );
148 println!("Upstream position tracked okay!");
149
150 // Try recording the same upstream position
151 let conflicting_result = client.append(
152 vec![],
153 None,
154 Some(TrackingInfo {
155 source: "upstream".to_string(),
156 position: next_upstream_position,
157 }),
158 );
159
160 // Expect an integrity error
161 match conflicting_result {
162 Err(DcbError::IntegrityError(integrity_error)) => {
163 println!(
164 "Conflicting upstream position was rejected: {:?}",
165 integrity_error
166 );
167 }
168 other => panic!("Expected IntegrityError, got {:?}", other),
169 }
170
171 Ok(())
172}More examples
examples/client_async_secure.rs (line 15)
10async fn main() -> Result<(), Box<dyn std::error::Error>> {
11 // Connect to the gRPC server
12 let url = "https://localhost:50051".to_string();
13 let client = UmaDbClient::new(url)
14 .ca_path("server.pem".to_string()) // For self-signed server certificates.
15 .api_key("umadb:example-api-key-4f7c2b1d9e5f4a038c1a".to_string())
16 .connect_async()
17 .await?;
18
19 // Define a consistency boundary
20 let cb = DcbQuery {
21 items: vec![DcbQueryItem {
22 types: vec!["example".to_string()],
23 tags: vec!["tag1".to_string(), "tag2".to_string()],
24 }],
25 };
26
27 // Read events for a decision model
28 let mut read_response = client.read(Some(cb.clone()), None, false, None).await?;
29
30 // Build decision model
31 while let Some(result) = read_response.next().await {
32 match result {
33 Ok(event) => {
34 println!(
35 "Got event at position {}: {:?}",
36 event.position, event.event
37 );
38 }
39 Err(status) => panic!("gRPC stream error: {}", status),
40 }
41 }
42
43 // Remember the last-known position
44 let last_known_position = read_response.head().await?;
45 println!("Last known position is: {:?}", last_known_position);
46
47 // Produce new event, attaching some metadata (e.g. provenance) that is
48 // stored alongside the event and returned when it is read back.
49 let mut metadata = Vec::new();
50 metadata.push(("source".to_string(), "client_async_secure".to_string()));
51 metadata.push(("correlation_id".to_string(), Uuid::new_v4().to_string()));
52 let event = DcbEvent {
53 event_type: "example".to_string(),
54 tags: vec!["tag1".to_string(), "tag2".to_string()],
55 data: b"Hello, world!".to_vec(),
56 uuid: Some(Uuid::new_v4()),
57 metadata,
58 };
59
60 // Append event in consistency boundary
61 let commit_position1 = client
62 .append(
63 vec![event.clone()],
64 Some(DcbAppendCondition {
65 fail_if_events_match: cb.clone(),
66 after: last_known_position,
67 }),
68 None,
69 )
70 .await?;
71 println!("Appended event at position: {}", commit_position1);
72
73 // Append conflicting event - expect an error
74 let conflicting_event = DcbEvent {
75 event_type: "example".to_string(),
76 tags: vec!["tag1".to_string(), "tag2".to_string()],
77 data: b"Hello, world!".to_vec(),
78 uuid: Some(Uuid::new_v4()), // different UUID
79 metadata: Vec::new(),
80 };
81 let conflicting_result = client
82 .append(
83 vec![conflicting_event.clone()],
84 Some(DcbAppendCondition {
85 fail_if_events_match: cb.clone(),
86 after: last_known_position,
87 }),
88 None,
89 )
90 .await;
91
92 // Expect an integrity error
93 match conflicting_result {
94 Err(DcbError::IntegrityError(integrity_error)) => {
95 println!("Conflicting event was rejected: {:?}", integrity_error);
96 }
97 other => panic!("Expected IntegrityError, got {:?}", other),
98 }
99
100 // Conditional appends with event UUIDs are idempotent.
101 println!(
102 "Retrying to append event at position: {:?}",
103 last_known_position
104 );
105 let commit_position2 = client
106 .append(
107 vec![event.clone()],
108 Some(DcbAppendCondition {
109 fail_if_events_match: cb.clone(),
110 after: last_known_position,
111 }),
112 None,
113 )
114 .await?;
115
116 if commit_position1 == commit_position2 {
117 println!(
118 "Append method returned same commit position: {}",
119 commit_position2
120 );
121 } else {
122 panic!("Expected idempotent retry!")
123 }
124
125 // Subscribe to all events for a projection
126 let mut subscription = client.subscribe(None, None).await?;
127
128 // Build an up-to-date view
129 while let Some(result) = subscription.next().await {
130 match result {
131 Ok(ev) => {
132 println!("Processing event at {}: {:?}", ev.position, ev.event);
133 if ev.position == commit_position2 {
134 println!("Projection has processed new event!");
135 break;
136 }
137 }
138 Err(status) => panic!("gRPC stream error: {}", status),
139 }
140 }
141
142 // Track an upstream position
143 let upstream_position = client.get_tracking_info("upstream").await?;
144 let next_upstream_position = upstream_position.unwrap_or(0) + 1;
145 println!("Next upstream position: {next_upstream_position}");
146 client
147 .append(
148 vec![],
149 None,
150 Some(TrackingInfo {
151 source: "upstream".to_string(),
152 position: next_upstream_position,
153 }),
154 )
155 .await?;
156 assert_eq!(
157 next_upstream_position,
158 client.get_tracking_info("upstream").await?.unwrap()
159 );
160 println!("Upstream position tracked okay!");
161
162 // Try recording the same upstream position
163 let conflicting_result = client
164 .append(
165 vec![],
166 None,
167 Some(TrackingInfo {
168 source: "upstream".to_string(),
169 position: next_upstream_position,
170 }),
171 )
172 .await;
173
174 // Expect an integrity error
175 match conflicting_result {
176 Err(DcbError::IntegrityError(integrity_error)) => {
177 println!(
178 "Conflicting upstream position was rejected: {:?}",
179 integrity_error
180 );
181 }
182 other => panic!("Expected IntegrityError, got {:?}", other),
183 }
184
185 Ok(())
186}pub fn batch_size(self, batch_size: u32) -> Self
Sourcepub fn connect(&self) -> DcbResult<SyncUmaDbClient>
pub fn connect(&self) -> DcbResult<SyncUmaDbClient>
Examples found in repository?
examples/client_sync_insecure.rs (line 10)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 // Connect to the gRPC server
9 let url = "http://localhost:50051".to_string();
10 let client = UmaDbClient::new(url).connect()?;
11
12 // Define a consistency boundary
13 let boundary = DcbQuery::new().item(
14 DcbQueryItem::new()
15 .types(["example"])
16 .tags(["tag1", "tag2"]),
17 );
18
19 // Read events for a decision model
20 let mut read_response = client.read(Some(boundary.clone()), None, false, None)?;
21
22 // Build decision model
23 while let Some(result) = read_response.next() {
24 match result {
25 Ok(event) => {
26 println!(
27 "Got event at position {}: {:?}",
28 event.position, event.event
29 );
30 }
31 Err(status) => panic!("gRPC stream error: {}", status),
32 }
33 }
34
35 // Remember the last-known position
36 let last_known_position = read_response.head().unwrap();
37 println!("Last known position is: {:?}", last_known_position);
38
39 // Produce new event, attaching some metadata (e.g. provenance) that is
40 // stored alongside the event and returned when it is read back.
41 let event = DcbEvent::default()
42 .event_type("example")
43 .tags(["tag1", "tag2"])
44 .data(b"Hello, world!")
45 .uuid(Uuid::new_v4())
46 .metadata_entry("source", "client_sync_insecure")
47 .metadata_entry("correlation_id", Uuid::new_v4().to_string());
48
49 // Append event in consistency boundary
50 let append_condition = DcbAppendCondition {
51 fail_if_events_match: boundary.clone(),
52 after: last_known_position,
53 };
54 let position1 = client.append(vec![event.clone()], Some(append_condition.clone()), None)?;
55
56 println!("Appended event at position: {}", position1);
57
58 // Append conflicting event - expect an error
59 let conflicting_event = DcbEvent::default()
60 .event_type("example")
61 .tags(["tag1", "tag2"])
62 .data(b"Hello, world!")
63 .uuid(Uuid::new_v4()); // different UUID
64
65 let conflicting_result = client.append(
66 vec![conflicting_event],
67 Some(append_condition.clone()),
68 None,
69 );
70
71 // Expect an integrity error
72 match conflicting_result {
73 Err(DcbError::IntegrityError(integrity_error)) => {
74 println!("Conflicting event was rejected: {:?}", integrity_error);
75 }
76 other => panic!("Expected IntegrityError, got {:?}", other),
77 }
78
79 // Appending with identical event IDs and append condition is idempotent.
80 println!(
81 "Retrying to append event at position: {:?}",
82 last_known_position
83 );
84 let position2 = client.append(vec![event.clone()], Some(append_condition.clone()), None)?;
85
86 if position1 == position2 {
87 println!("Append method returned same commit position: {}", position2);
88 } else {
89 panic!("Expected idempotent retry!")
90 }
91
92 // Subscribe to all events for a projection
93 let mut subscription = client.subscribe(None, None)?;
94
95 // Build an up-to-date view
96 while let Some(result) = subscription.next() {
97 match result {
98 Ok(ev) => {
99 println!("Processing event at {}: {:?}", ev.position, ev.event);
100 if ev.position == position2 {
101 println!("Projection has processed new event!");
102 break;
103 }
104 }
105 Err(status) => panic!("gRPC stream error: {}", status),
106 }
107 }
108
109 // Track an upstream position
110 let upstream_position = client.get_tracking_info("upstream")?;
111 let next_upstream_position = upstream_position.unwrap_or(0) + 1;
112 println!("Next upstream position: {next_upstream_position}");
113 client.append(
114 vec![],
115 None,
116 Some(TrackingInfo {
117 source: "upstream".to_string(),
118 position: next_upstream_position,
119 }),
120 )?;
121 assert_eq!(
122 next_upstream_position,
123 client.get_tracking_info("upstream")?.unwrap()
124 );
125 println!("Upstream position tracked okay!");
126
127 // Try recording the same upstream position
128 let conflicting_result = client.append(
129 vec![],
130 None,
131 Some(TrackingInfo {
132 source: "upstream".to_string(),
133 position: next_upstream_position,
134 }),
135 );
136
137 // Expect an integrity error
138 match conflicting_result {
139 Err(DcbError::IntegrityError(integrity_error)) => {
140 println!(
141 "Conflicting upstream position was rejected: {:?}",
142 integrity_error
143 );
144 }
145 other => panic!("Expected IntegrityError, got {:?}", other),
146 }
147
148 Ok(())
149}More examples
examples/client_sync_secure.rs (line 13)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 // Connect to the gRPC server
9 let url = "https://localhost:50051".to_string();
10 let client = UmaDbClient::new(url)
11 .ca_path("server.pem".to_string()) // For self-signed server certificates.
12 .api_key("umadb:example-api-key-4f7c2b1d9e5f4a038c1a".to_string())
13 .connect()?;
14
15 // Define a consistency boundary
16 let cb = DcbQuery {
17 items: vec![DcbQueryItem {
18 types: vec!["example".to_string()],
19 tags: vec!["tag1".to_string(), "tag2".to_string()],
20 }],
21 };
22
23 // Read events for a decision model
24 let mut read_response = client.read(Some(cb.clone()), None, false, None)?;
25
26 // Build decision model
27 while let Some(result) = read_response.next() {
28 match result {
29 Ok(event) => {
30 println!(
31 "Got event at position {}: {:?}",
32 event.position, event.event
33 );
34 }
35 Err(status) => panic!("gRPC stream error: {}", status),
36 }
37 }
38
39 // Remember the last-known position
40 let last_known_position = read_response.head().unwrap();
41 println!("Last known position is: {:?}", last_known_position);
42
43 // Produce new event, attaching some metadata (e.g. provenance) that is
44 // stored alongside the event and returned when it is read back.
45 let mut metadata = Vec::new();
46 metadata.push(("source".to_string(), "client_sync_secure".to_string()));
47 metadata.push(("correlation_id".to_string(), Uuid::new_v4().to_string()));
48 let event = DcbEvent {
49 event_type: "example".to_string(),
50 tags: vec!["tag1".to_string(), "tag2".to_string()],
51 data: b"Hello, world!".to_vec(),
52 uuid: Some(Uuid::new_v4()),
53 metadata,
54 };
55
56 // Append event in consistency boundary
57 let commit_position1 = client.append(
58 vec![event.clone()],
59 Some(DcbAppendCondition {
60 fail_if_events_match: cb.clone(),
61 after: last_known_position,
62 }),
63 None,
64 )?;
65 println!("Appended event at position: {}", commit_position1);
66
67 // Append conflicting event - expect an error
68 let conflicting_event = DcbEvent {
69 event_type: "example".to_string(),
70 tags: vec!["tag1".to_string(), "tag2".to_string()],
71 data: b"Hello, world!".to_vec(),
72 uuid: Some(Uuid::new_v4()), // different UUID
73 metadata: Vec::new(),
74 };
75 let conflicting_result = client.append(
76 vec![conflicting_event],
77 Some(DcbAppendCondition {
78 fail_if_events_match: cb.clone(),
79 after: last_known_position,
80 }),
81 None,
82 );
83
84 // Expect an integrity error
85 match conflicting_result {
86 Err(DcbError::IntegrityError(integrity_error)) => {
87 println!("Conflicting event was rejected: {:?}", integrity_error);
88 }
89 other => panic!("Expected IntegrityError, got {:?}", other),
90 }
91
92 // Conditional appends with event UUIDs are idempotent.
93 println!(
94 "Retrying to append event at position: {:?}",
95 last_known_position
96 );
97 let commit_position2 = client.append(
98 vec![event.clone()],
99 Some(DcbAppendCondition {
100 fail_if_events_match: cb.clone(),
101 after: last_known_position,
102 }),
103 None,
104 )?;
105
106 if commit_position1 == commit_position2 {
107 println!(
108 "Append method returned same commit position: {}",
109 commit_position2
110 );
111 } else {
112 panic!("Expected idempotent retry!")
113 }
114
115 // Subscribe to all events for a projection
116 let mut subscription = client.subscribe(None, None)?;
117
118 // Build an up-to-date view
119 while let Some(result) = subscription.next() {
120 match result {
121 Ok(ev) => {
122 println!("Processing event at {}: {:?}", ev.position, ev.event);
123 if ev.position == commit_position2 {
124 println!("Projection has processed new event!");
125 break;
126 }
127 }
128 Err(status) => panic!("gRPC stream error: {}", status),
129 }
130 }
131
132 // Track an upstream position
133 let upstream_position = client.get_tracking_info("upstream")?;
134 let next_upstream_position = upstream_position.unwrap_or(0) + 1;
135 println!("Next upstream position: {next_upstream_position}");
136 client.append(
137 vec![],
138 None,
139 Some(TrackingInfo {
140 source: "upstream".to_string(),
141 position: next_upstream_position,
142 }),
143 )?;
144 assert_eq!(
145 next_upstream_position,
146 client.get_tracking_info("upstream")?.unwrap()
147 );
148 println!("Upstream position tracked okay!");
149
150 // Try recording the same upstream position
151 let conflicting_result = client.append(
152 vec![],
153 None,
154 Some(TrackingInfo {
155 source: "upstream".to_string(),
156 position: next_upstream_position,
157 }),
158 );
159
160 // Expect an integrity error
161 match conflicting_result {
162 Err(DcbError::IntegrityError(integrity_error)) => {
163 println!(
164 "Conflicting upstream position was rejected: {:?}",
165 integrity_error
166 );
167 }
168 other => panic!("Expected IntegrityError, got {:?}", other),
169 }
170
171 Ok(())
172}Sourcepub async fn connect_async(&self) -> DcbResult<AsyncUmaDbClient>
pub async fn connect_async(&self) -> DcbResult<AsyncUmaDbClient>
Examples found in repository?
examples/client_async_insecure.rs (line 13)
10async fn main() -> Result<(), Box<dyn std::error::Error>> {
11 // Connect to the gRPC server
12 let url = "http://localhost:50051".to_string();
13 let client = UmaDbClient::new(url).connect_async().await?;
14
15 // Define a consistency boundary
16 let boundary = DcbQuery::new().item(
17 DcbQueryItem::new()
18 .types(["example"])
19 .tags(["tag1", "tag2"]),
20 );
21
22 // Read events for a decision model
23 let mut read_response = client
24 .read(Some(boundary.clone()), None, false, None)
25 .await?;
26
27 // Build decision model
28 while let Some(result) = read_response.next().await {
29 match result {
30 Ok(event) => {
31 println!(
32 "Got event at position {}: {:?}",
33 event.position, event.event
34 );
35 }
36 Err(status) => panic!("gRPC stream error: {}", status),
37 }
38 }
39
40 // Remember the last-known position
41 let last_known_position = read_response.head().await?;
42 println!("Last known position is: {:?}", last_known_position);
43
44 // Produce new event, attaching some metadata (e.g. provenance) that is
45 // stored alongside the event and returned when it is read back.
46 let event = DcbEvent::default()
47 .event_type("example")
48 .tags(["tag1", "tag2"])
49 .data(b"Hello, world!")
50 .uuid(Uuid::new_v4())
51 .metadata_entry("source", "client_async_insecure")
52 .metadata_entry("correlation_id", Uuid::new_v4().to_string());
53
54 // Append event in consistency boundary
55 let append_condition = DcbAppendCondition {
56 fail_if_events_match: boundary.clone(),
57 after: last_known_position,
58 };
59 let position1 = client
60 .append(vec![event.clone()], Some(append_condition.clone()), None)
61 .await?;
62
63 println!("Appended event at position: {}", position1);
64
65 // Append conflicting event - expect an error
66 let conflicting_event = DcbEvent::default()
67 .event_type("example")
68 .tags(["tag1", "tag2"])
69 .data(b"Hello, world!")
70 .uuid(Uuid::new_v4()); // different UUID
71
72 let conflicting_result = client
73 .append(
74 vec![conflicting_event.clone()],
75 Some(append_condition.clone()),
76 None,
77 )
78 .await;
79
80 // Expect an integrity error
81 match conflicting_result {
82 Err(DcbError::IntegrityError(integrity_error)) => {
83 println!("Conflicting event was rejected: {:?}", integrity_error);
84 }
85 other => panic!("Expected IntegrityError, got {:?}", other),
86 }
87
88 // Appending with identical events IDs and append conditions is idempotent.
89 println!(
90 "Retrying to append event at position: {:?}",
91 last_known_position
92 );
93 let position2 = client
94 .append(vec![event.clone()], Some(append_condition.clone()), None)
95 .await?;
96
97 if position1 == position2 {
98 println!("Append method returned same commit position: {}", position2);
99 } else {
100 panic!("Expected idempotent retry!")
101 }
102
103 // Subscribe to all events for a projection
104 let mut subscription = client.subscribe(None, None).await?;
105
106 // Build an up-to-date view
107 while let Some(result) = subscription.next().await {
108 match result {
109 Ok(ev) => {
110 println!("Processing event at {}: {:?}", ev.position, ev.event);
111 if ev.position == position2 {
112 println!("Projection has processed new event!");
113 break;
114 }
115 }
116 Err(status) => panic!("gRPC stream error: {}", status),
117 }
118 }
119
120 // Track an upstream position
121 let upstream_position = client.get_tracking_info("upstream").await?;
122 let next_upstream_position = upstream_position.unwrap_or(0) + 1;
123 println!("Next upstream position: {next_upstream_position}");
124 client
125 .append(
126 vec![],
127 None,
128 Some(TrackingInfo {
129 source: "upstream".to_string(),
130 position: next_upstream_position,
131 }),
132 )
133 .await?;
134 assert_eq!(
135 next_upstream_position,
136 client.get_tracking_info("upstream").await?.unwrap()
137 );
138 println!("Upstream position tracked okay!");
139
140 // Try recording the same upstream position
141 let conflicting_result = client
142 .append(
143 vec![],
144 None,
145 Some(TrackingInfo {
146 source: "upstream".to_string(),
147 position: next_upstream_position,
148 }),
149 )
150 .await;
151
152 // Expect an integrity error
153 match conflicting_result {
154 Err(DcbError::IntegrityError(integrity_error)) => {
155 println!(
156 "Conflicting upstream position was rejected: {:?}",
157 integrity_error
158 );
159 }
160 other => panic!("Expected IntegrityError, got {:?}", other),
161 }
162
163 Ok(())
164}More examples
examples/client_async_secure.rs (line 16)
10async fn main() -> Result<(), Box<dyn std::error::Error>> {
11 // Connect to the gRPC server
12 let url = "https://localhost:50051".to_string();
13 let client = UmaDbClient::new(url)
14 .ca_path("server.pem".to_string()) // For self-signed server certificates.
15 .api_key("umadb:example-api-key-4f7c2b1d9e5f4a038c1a".to_string())
16 .connect_async()
17 .await?;
18
19 // Define a consistency boundary
20 let cb = DcbQuery {
21 items: vec![DcbQueryItem {
22 types: vec!["example".to_string()],
23 tags: vec!["tag1".to_string(), "tag2".to_string()],
24 }],
25 };
26
27 // Read events for a decision model
28 let mut read_response = client.read(Some(cb.clone()), None, false, None).await?;
29
30 // Build decision model
31 while let Some(result) = read_response.next().await {
32 match result {
33 Ok(event) => {
34 println!(
35 "Got event at position {}: {:?}",
36 event.position, event.event
37 );
38 }
39 Err(status) => panic!("gRPC stream error: {}", status),
40 }
41 }
42
43 // Remember the last-known position
44 let last_known_position = read_response.head().await?;
45 println!("Last known position is: {:?}", last_known_position);
46
47 // Produce new event, attaching some metadata (e.g. provenance) that is
48 // stored alongside the event and returned when it is read back.
49 let mut metadata = Vec::new();
50 metadata.push(("source".to_string(), "client_async_secure".to_string()));
51 metadata.push(("correlation_id".to_string(), Uuid::new_v4().to_string()));
52 let event = DcbEvent {
53 event_type: "example".to_string(),
54 tags: vec!["tag1".to_string(), "tag2".to_string()],
55 data: b"Hello, world!".to_vec(),
56 uuid: Some(Uuid::new_v4()),
57 metadata,
58 };
59
60 // Append event in consistency boundary
61 let commit_position1 = client
62 .append(
63 vec![event.clone()],
64 Some(DcbAppendCondition {
65 fail_if_events_match: cb.clone(),
66 after: last_known_position,
67 }),
68 None,
69 )
70 .await?;
71 println!("Appended event at position: {}", commit_position1);
72
73 // Append conflicting event - expect an error
74 let conflicting_event = DcbEvent {
75 event_type: "example".to_string(),
76 tags: vec!["tag1".to_string(), "tag2".to_string()],
77 data: b"Hello, world!".to_vec(),
78 uuid: Some(Uuid::new_v4()), // different UUID
79 metadata: Vec::new(),
80 };
81 let conflicting_result = client
82 .append(
83 vec![conflicting_event.clone()],
84 Some(DcbAppendCondition {
85 fail_if_events_match: cb.clone(),
86 after: last_known_position,
87 }),
88 None,
89 )
90 .await;
91
92 // Expect an integrity error
93 match conflicting_result {
94 Err(DcbError::IntegrityError(integrity_error)) => {
95 println!("Conflicting event was rejected: {:?}", integrity_error);
96 }
97 other => panic!("Expected IntegrityError, got {:?}", other),
98 }
99
100 // Conditional appends with event UUIDs are idempotent.
101 println!(
102 "Retrying to append event at position: {:?}",
103 last_known_position
104 );
105 let commit_position2 = client
106 .append(
107 vec![event.clone()],
108 Some(DcbAppendCondition {
109 fail_if_events_match: cb.clone(),
110 after: last_known_position,
111 }),
112 None,
113 )
114 .await?;
115
116 if commit_position1 == commit_position2 {
117 println!(
118 "Append method returned same commit position: {}",
119 commit_position2
120 );
121 } else {
122 panic!("Expected idempotent retry!")
123 }
124
125 // Subscribe to all events for a projection
126 let mut subscription = client.subscribe(None, None).await?;
127
128 // Build an up-to-date view
129 while let Some(result) = subscription.next().await {
130 match result {
131 Ok(ev) => {
132 println!("Processing event at {}: {:?}", ev.position, ev.event);
133 if ev.position == commit_position2 {
134 println!("Projection has processed new event!");
135 break;
136 }
137 }
138 Err(status) => panic!("gRPC stream error: {}", status),
139 }
140 }
141
142 // Track an upstream position
143 let upstream_position = client.get_tracking_info("upstream").await?;
144 let next_upstream_position = upstream_position.unwrap_or(0) + 1;
145 println!("Next upstream position: {next_upstream_position}");
146 client
147 .append(
148 vec![],
149 None,
150 Some(TrackingInfo {
151 source: "upstream".to_string(),
152 position: next_upstream_position,
153 }),
154 )
155 .await?;
156 assert_eq!(
157 next_upstream_position,
158 client.get_tracking_info("upstream").await?.unwrap()
159 );
160 println!("Upstream position tracked okay!");
161
162 // Try recording the same upstream position
163 let conflicting_result = client
164 .append(
165 vec![],
166 None,
167 Some(TrackingInfo {
168 source: "upstream".to_string(),
169 position: next_upstream_position,
170 }),
171 )
172 .await;
173
174 // Expect an integrity error
175 match conflicting_result {
176 Err(DcbError::IntegrityError(integrity_error)) => {
177 println!(
178 "Conflicting upstream position was rejected: {:?}",
179 integrity_error
180 );
181 }
182 other => panic!("Expected IntegrityError, got {:?}", other),
183 }
184
185 Ok(())
186}Auto Trait Implementations§
impl Freeze for UmaDbClient
impl RefUnwindSafe for UmaDbClient
impl Send for UmaDbClient
impl Sync for UmaDbClient
impl Unpin for UmaDbClient
impl UnsafeUnpin for UmaDbClient
impl UnwindSafe for UmaDbClient
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
Wrap the input message
T in a tonic::Request