client_sync_insecure/
client_sync_insecure.rs1use umadb_client::UmaDbClient;
2use umadb_dcb::{
3 DcbAppendCondition, DcbError, DcbEvent, DcbEventStoreSync, DcbQuery, DcbQueryItem, TrackingInfo,
4};
5use uuid::Uuid;
6
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 let url = "http://localhost:50051".to_string();
10 let client = UmaDbClient::new(url).connect()?;
11
12 let boundary = DcbQuery::new().item(
14 DcbQueryItem::new()
15 .types(["example"])
16 .tags(["tag1", "tag2"]),
17 );
18
19 let mut read_response = client.read(Some(boundary.clone()), None, false, None)?;
21
22 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 let last_known_position = read_response.head().unwrap();
37 println!("Last known position is: {:?}", last_known_position);
38
39 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 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 let conflicting_event = DcbEvent::default()
60 .event_type("example")
61 .tags(["tag1", "tag2"])
62 .data(b"Hello, world!")
63 .uuid(Uuid::new_v4()); let conflicting_result = client.append(
66 vec![conflicting_event],
67 Some(append_condition.clone()),
68 None,
69 );
70
71 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 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 let mut subscription = client.subscribe(None, None)?;
94
95 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 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 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 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}