Skip to content

Commit c8d8f40

Browse files
committed
fix: avro serialisation of nested records with implicit namespace (#545)
1 parent 76716df commit c8d8f40

File tree

3 files changed

+94
-5
lines changed

3 files changed

+94
-5
lines changed

backend/Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/Cargo.toml

+18-4
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,33 @@ openssl-src = { version = "111", features = ["force-engine"] }
1717
serde_json = "1.0"
1818
dirs = "5.0.1"
1919
serde = { version = "1.0.171", features = ["derive"] }
20-
tauri = { version = "1.4", features = ["dialog-open", "dialog-save", "fs-write-file", "os-all", "updater", "window-create", "window-set-focus", "window-set-min-size", "window-set-title"] }
20+
tauri = { version = "1.4", features = [
21+
"dialog-open",
22+
"dialog-save",
23+
"fs-write-file",
24+
"os-all",
25+
"updater",
26+
"window-create",
27+
"window-set-focus",
28+
"window-set-min-size",
29+
"window-set-title",
30+
] }
2131
reqwest = { version = "0.11", features = ["json", "blocking"] }
2232
url = { version = "2", features = ["serde"] }
2333
tokio = { version = "1", features = ["full"] }
2434
futures = { version = "0.3" }
25-
apache-avro = { git = "https://github.com/apache/avro", rev = "8c3ee165432cf557429a984df6acbc075a848ac9" }
35+
# todo: replace the fork with the apache repo when https://github.com/apache/avro/pull/2374 is merged
36+
# apache-avro = { git = "https://github.com/apache/avro", rev = "<todo>" }
37+
apache-avro = { git = "https://github.com/andrewinci/avro", rev = "c0583d12944567872079c6162e976f9ea9477e8a" }
2638
log = { version = "0.4" }
2739
env_logger = { version = "0.10.0" }
2840
async-trait = "0.1.71"
2941
num-bigint = "0.4"
3042
rust_decimal = "1.30"
3143
rusqlite = { version = "0.28.0", features = ["bundled", "backup", "hooks"] }
32-
rust-keystore = { git = "https://github.com/andrewinci/rust-keystore", features = ["p12"], tag = "v0.1.2" }
44+
rust-keystore = { git = "https://github.com/andrewinci/rust-keystore", features = [
45+
"p12",
46+
], tag = "v0.1.2" }
3347
r2d2 = "0.8.10"
3448
r2d2_sqlite = "0.21.0"
3549
toml = "0.7"
@@ -69,6 +83,6 @@ custom-protocol = ["tauri/custom-protocol"]
6983
integration_tests = []
7084

7185
[profile.release]
72-
strip = true
86+
strip = true
7387
lto = true
7488
opt-level = "s"

backend/src/core/avro/json_to_avro.rs

+75
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,42 @@ mod tests {
222222
use super::parse_decimal;
223223
use crate::core::avro::avro_schema::AvroSchema;
224224
use crate::core::avro::avro_schema::RecordField;
225+
use crate::core::avro::error::AvroResult;
225226
use crate::core::avro::AvroError;
227+
use crate::core::avro::AvroParser;
228+
use crate::core::avro::ResolvedAvroSchema;
229+
use crate::core::avro::SchemaProvider;
230+
use apache_avro::Schema;
226231

227232
use apache_avro::types::Value as AvroValue;
233+
use async_trait::async_trait;
228234
use serde_json::json;
229235
use serde_json::Value as JsonValue;
230236

237+
struct MockSchemaProvider {}
238+
#[async_trait]
239+
impl SchemaProvider for MockSchemaProvider {
240+
async fn get_schema_by_id(&self, id: i32) -> AvroResult<ResolvedAvroSchema> {
241+
let json_schema = &get_test_avro_schema();
242+
let schema = Schema::parse_str(json_schema).expect("invalid test schema");
243+
Ok(ResolvedAvroSchema::from(id, &schema))
244+
}
245+
async fn get_schema_by_name(&self, _: &str) -> AvroResult<ResolvedAvroSchema> {
246+
let json_schema = &get_test_avro_schema();
247+
let schema = Schema::parse_str(json_schema).expect("invalid test schema");
248+
Ok(ResolvedAvroSchema::from(123, &schema))
249+
}
250+
}
251+
252+
#[tokio::test]
253+
async fn test_parse_nested_records_with_implicit_namespace() {
254+
let mock_provider = MockSchemaProvider {};
255+
let sut = AvroParser::new(mock_provider.into());
256+
let sample_json = &get_test_avro_message();
257+
let res = sut.json_to_avro(sample_json, "sample").await;
258+
assert!(res.is_ok())
259+
}
260+
231261
#[test]
232262
fn test_decimal() {
233263
// happy path
@@ -311,4 +341,49 @@ mod tests {
311341
schema: schema,
312342
}
313343
}
344+
345+
fn get_test_avro_message() -> String {
346+
r#"{
347+
"outer_field_1": {
348+
"middle_field_1": {
349+
"inner_field_1": 1.7
350+
},
351+
"middle_field_2": {
352+
"inner_field_1": 1.8
353+
}
354+
}
355+
}"#
356+
.to_string()
357+
}
358+
fn get_test_avro_schema() -> String {
359+
r#"{
360+
"name": "record_name",
361+
"namespace": "space",
362+
"type": "record",
363+
"fields": [
364+
{
365+
"name": "outer_field_1",
366+
"type": {
367+
"type": "record",
368+
"name": "middle_record_name",
369+
"namespace": "middle_namespace",
370+
"fields": [
371+
{
372+
"name": "middle_field_1",
373+
"type": {
374+
"type": "record",
375+
"name": "inner_record_name",
376+
"fields": [
377+
{ "name": "inner_field_1", "type": "double" }
378+
]
379+
}
380+
},
381+
{ "name": "middle_field_2", "type": "inner_record_name" }
382+
]
383+
}
384+
}
385+
]
386+
}"#
387+
.to_string()
388+
}
314389
}

0 commit comments

Comments
 (0)