Skip to content

Commit 877b2cb

Browse files
authored
[query-engine] Expose allow_undefined_keys on BridgeOptions (open-telemetry#1286)
Relates to open-telemetry#1281 ## Changes * Allow `allow_undefined_keys` on attributes schema to be set via `BridgeOptions`
1 parent 4ed8aa6 commit 877b2cb

File tree

2 files changed

+99
-3
lines changed

2 files changed

+99
-3
lines changed

rust/experimental/query_engine/engine-recordset-otlp-bridge/src/bridge.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,30 @@ mod tests {
613613
run_test_failure("source | extend Attributes.Body = 'hello world'");
614614
}
615615

616+
#[test]
617+
fn test_parse_kql_query_into_pipeline_with_attributes_schema_and_allow_undefined_keys() {
618+
let run_test_success = |query: &str| {
619+
parse_kql_query_into_pipeline(
620+
query,
621+
Some(
622+
BridgeOptions::new().with_attributes_schema(
623+
ParserMapSchema::new()
624+
.with_key_definition("Body", ParserMapKeySchema::Any)
625+
.with_key_definition("int_value", ParserMapKeySchema::Integer)
626+
.set_allow_undefined_keys(),
627+
),
628+
),
629+
)
630+
.unwrap();
631+
};
632+
633+
run_test_success("source | extend int_value = 1234");
634+
run_test_success("source | extend Custom = 1234");
635+
636+
run_test_success("source | summarize by int_value");
637+
run_test_success("source | summarize by unknown");
638+
}
639+
616640
#[test]
617641
fn test_parse_kql_query_into_pipeline_with_attributes_schema_error() {
618642
let e = parse_kql_query_into_pipeline(

rust/experimental/query_engine/engine-recordset-otlp-bridge/src/bridge_options.rs

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl BridgeOptions {
6464
fn parser_map_schema_from_json(
6565
map_schema_value: &serde_json::Value,
6666
) -> Result<ParserMapSchema, String> {
67-
/* Expected JSON structure looks like this:
67+
/* Expected JSON structure looks like this...
6868
{
6969
"key1": "Any",
7070
"key2": "Double",
@@ -78,10 +78,31 @@ fn parser_map_schema_from_json(
7878
}
7979
*/
8080

81-
if let serde_json::Value::Object(o) = map_schema_value {
81+
/* ...or like this (allows options to also be specified):
82+
{
83+
"schema": {
84+
"key1": "Any",
85+
"key2": "Double",
86+
"key3": "Map",
87+
"key4": {
88+
"type": "Map",
89+
"schema": {
90+
"sub-key1": "Integer"
91+
}
92+
}
93+
},
94+
"options": {
95+
"allow_undefined_keys": true // default if not specified is false
96+
}
97+
}
98+
*/
99+
100+
fn parse_schema(
101+
schema: &serde_json::Map<String, serde_json::Value>,
102+
) -> Result<ParserMapSchema, String> {
82103
let mut map = ParserMapSchema::new();
83104

84-
for (key, value) in o {
105+
for (key, value) in schema {
85106
match value {
86107
serde_json::Value::String(s) => match ParserMapKeySchema::try_from(s.as_str()) {
87108
Ok(s) => map = map.with_key_definition(key.as_str(), s),
@@ -126,6 +147,30 @@ fn parser_map_schema_from_json(
126147
}
127148

128149
Ok(map)
150+
}
151+
152+
if let serde_json::Value::Object(o) = map_schema_value {
153+
if o.keys().len() == 2 && o.contains_key("schema") && o.contains_key("options") {
154+
if let Some(serde_json::Value::Object(schema)) = o.get("schema") {
155+
let mut schema = parse_schema(schema)?;
156+
157+
if let Some(serde_json::Value::Object(options)) = o.get("options") {
158+
if let Some(serde_json::Value::Bool(b)) = options.get("allow_undefined_keys")
159+
&& *b
160+
{
161+
schema = schema.set_allow_undefined_keys();
162+
}
163+
} else {
164+
return Err("Options was not a map".into());
165+
}
166+
167+
Ok(schema)
168+
} else {
169+
Err("Schema was not a map".into())
170+
}
171+
} else {
172+
parse_schema(o)
173+
}
129174
} else {
130175
Err(format!("Expected a map found: {map_schema_value:?}"))
131176
}
@@ -222,4 +267,31 @@ mod tests {
222267
),
223268
);
224269
}
270+
271+
#[test]
272+
fn test_bridge_options_from_json_with_allow_undefined_keys() {
273+
let run_test = |json: &str, expected: BridgeOptions| {
274+
let actual = BridgeOptions::from_json(json).unwrap();
275+
276+
assert_eq!(expected, actual);
277+
};
278+
279+
run_test(
280+
r#"{
281+
"attributes_schema": {
282+
"schema": {
283+
"double_key": "Double"
284+
},
285+
"options": {
286+
"allow_undefined_keys": true
287+
}
288+
}
289+
}"#,
290+
BridgeOptions::new().with_attributes_schema(
291+
ParserMapSchema::new()
292+
.with_key_definition("double_key", ParserMapKeySchema::Double)
293+
.set_allow_undefined_keys(),
294+
),
295+
);
296+
}
225297
}

0 commit comments

Comments
 (0)