diff --git a/Cargo.lock b/Cargo.lock index 77d6d6baa..d3102ab79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -812,6 +812,7 @@ dependencies = [ name = "bd-log-matcher" version = "1.0.0" dependencies = [ + "ahash", "anyhow", "assert_matches", "bd-log-primitives", diff --git a/api b/api index 5ea82a7bb..6599a8acc 160000 --- a/api +++ b/api @@ -1 +1 @@ -Subproject commit 5ea82a7bb82470ad2dd14a77379be16310de221a +Subproject commit 6599a8accb379e78c516d96157b438e720823295 diff --git a/bd-log-matcher/Cargo.toml b/bd-log-matcher/Cargo.toml index f31498433..51b308685 100644 --- a/bd-log-matcher/Cargo.toml +++ b/bd-log-matcher/Cargo.toml @@ -9,6 +9,7 @@ version = "1.0.0" doctest = false [dependencies] +ahash.workspace = true anyhow.workspace = true bd-log-primitives.path = "../bd-log-primitives" bd-proto.path = "../bd-proto" diff --git a/bd-log-matcher/src/matcher.rs b/bd-log-matcher/src/matcher.rs index 3d68dbee8..fc29f123a 100644 --- a/bd-log-matcher/src/matcher.rs +++ b/bd-log-matcher/src/matcher.rs @@ -21,11 +21,12 @@ use base_log_matcher::tag_match::Value_match::{ DoubleValueMatch, IntValueMatch, IsSetMatch, + JsonValueMatch, SemVerValueMatch, StringValueMatch, }; use bd_log_primitives::tiny_set::TinyMap; -use bd_log_primitives::{FieldsRef, LogLevel, LogMessage}; +use bd_log_primitives::{DataValue, FieldsRef, LogLevel, LogMessage}; use bd_proto::protos::config::v1::config::log_matcher::base_log_matcher::StringMatchType; use bd_proto::protos::config::v1::config::log_matcher::{ BaseLogMatcher as LegacyBaseLogMatcher, @@ -39,6 +40,10 @@ use bd_proto::protos::log_matcher::log_matcher; use bd_proto::protos::logging::payload::LogType; use bd_proto::protos::state::scope::StateScope; use bd_proto::protos::value_matcher::value_matcher::Operator; +use bd_proto::protos::value_matcher::value_matcher::json_path_value_match::{ + KeyOrIndex, + key_or_index, +}; use bd_state::Scope; use log_matcher::LogMatcher; use log_matcher::log_matcher::{BaseLogMatcher, Matcher, base_log_matcher}; @@ -162,6 +167,14 @@ impl Tree { .get(message, fields, state) .is_some_and(|input| criteria.evaluate(input.as_ref())), Leaf::IsSetValue(input) => input.get(message, fields, state).is_some(), + Leaf::JsonPathValue { + field_key, + path, + matcher, + } => fields + .field(field_key) + .and_then(|value| resolve_json_path(value, path)) + .is_some_and(|input| matcher.evaluate(input.as_ref(), extracted_fields)), Leaf::Any => true, }, Self::Or(or_matchers) => or_matchers.iter().any(|matcher| { @@ -259,10 +272,24 @@ pub enum Leaf { /// Whether a given tag is set or not. IsSetValue(InputType), + /// Uses a destructured JSON path to match against a string value within a Map structure stored in + /// a tag. + JsonPathValue { + field_key: String, + path: Vec, + matcher: StringMatch, + }, + /// Always true. Any, } +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum JsonPathToken { + Key(String), + Index(i32), +} + impl Leaf { fn new_legacy(log_matcher: &LegacyBaseLogMatcher) -> Result { fn map_string_value(value: &str, match_type: StringMatchType) -> Result { @@ -436,8 +463,71 @@ impl Leaf { version::VersionMatch::from_proto(sem_ver_value_match)?, ), IsSetMatch(_) => Self::IsSetValue(InputType::Field(tag_match.tag_key.clone())), + JsonValueMatch(json_value_match) => { + let path = json_value_match + .key_or_index + .iter() + .map(parse_json_path) + .collect::>>()?; + Self::JsonPathValue { + field_key: tag_match.tag_key.clone(), + path, + matcher: StringMatch::new( + json_value_match.operator, + ValueOrSavedFieldId::Value(json_value_match.match_value.clone()), + )?, + } + }, }, }, ) } } + +fn parse_json_path(key_or_index: &KeyOrIndex) -> Result { + match key_or_index + .key_or_index + .as_ref() + .ok_or_else(|| anyhow!("missing json path key or index"))? + { + key_or_index::Key_or_index::Key(key) => Ok(JsonPathToken::Key(key.clone())), + key_or_index::Key_or_index::Index(index) => Ok(JsonPathToken::Index(*index)), + } +} + +fn resolve_json_path<'a>(value: &'a DataValue, path: &[JsonPathToken]) -> Option> { + let mut current = value; + for token in path { + match token { + JsonPathToken::Key(key) => { + let DataValue::Map(map_data) = current else { + return None; + }; + current = map_data.entries().get(key)?; + }, + JsonPathToken::Index(index) => { + let DataValue::Array(array_data) = current else { + return None; + }; + let items = array_data.items(); + let len = i32::try_from(items.len()).ok()?; + let index = if *index < 0 { len + *index } else { *index }; + let index: usize = index.try_into().ok()?; + current = items.get(index)?; + }, + } + } + + match current { + DataValue::String(value) => Some(Cow::Borrowed(value.as_str())), + DataValue::SharedString(value) => Some(Cow::Borrowed(value.as_ref())), + DataValue::StaticString(value) => Some(Cow::Borrowed(value)), + DataValue::Bytes(_) + | DataValue::Boolean(_) + | DataValue::U64(_) + | DataValue::I64(_) + | DataValue::Double(_) + | DataValue::Map(_) + | DataValue::Array(_) => None, + } +} diff --git a/bd-log-matcher/src/matcher_test.rs b/bd-log-matcher/src/matcher_test.rs index da99d762a..65f8b1b49 100644 --- a/bd-log-matcher/src/matcher_test.rs +++ b/bd-log-matcher/src/matcher_test.rs @@ -9,6 +9,7 @@ use crate::builder; use crate::matcher::Tree; use crate::matcher::base_log_matcher::tag_match::Value_match::DoubleValueMatch; use crate::test::TestMatcher; +use ahash::AHashMap; use bd_log_primitives::tiny_set::TinyMap; use bd_log_primitives::{ DataValue, @@ -24,10 +25,14 @@ use bd_proto::protos::log_matcher::log_matcher::{LogMatcher, log_matcher}; use bd_proto::protos::logging::payload::LogType; use bd_proto::protos::state::matcher::state_value_match; use bd_proto::protos::state::scope::StateScope; -use bd_proto::protos::value_matcher::value_matcher::Operator; use bd_proto::protos::value_matcher::value_matcher::double_value_match::Double_value_match_type; use bd_proto::protos::value_matcher::value_matcher::int_value_match::Int_value_match_type; +use bd_proto::protos::value_matcher::value_matcher::json_path_value_match::{ + KeyOrIndex, + key_or_index, +}; use bd_proto::protos::value_matcher::value_matcher::string_value_match::String_value_match_type; +use bd_proto::protos::value_matcher::value_matcher::{JsonPathValueMatch, Operator}; use bd_state::StateReader; use log_matcher::base_log_matcher::Match_type::{MessageMatch, StateMatch, TagMatch}; use log_matcher::base_log_matcher::tag_match::Value_match::{ @@ -78,6 +83,15 @@ fn binary_log_tag(key: &'static str, value: &'static [u8]) -> Input<'static> { ) } +fn map_log_tag(key: &'static str, value: DataValue) -> Input<'static> { + ( + LogType::NORMAL, + log_level::DEBUG, + LogMessage::String("message".into()), + [(key.into(), value)].into(), + ) +} + fn log_type(log_type: LogType) -> Input<'static> { ( log_type, @@ -96,6 +110,321 @@ fn log_level(log_level: LogLevel) -> Input<'static> { ) } +#[test] +fn json_path_matcher_string_match() { + let config = simple_log_matcher(TagMatch(base_log_matcher::TagMatch { + tag_key: "payload".to_string(), + value_match: Some( + log_matcher::base_log_matcher::tag_match::Value_match::JsonValueMatch(JsonPathValueMatch { + operator: Operator::OPERATOR_EQUALS.into(), + match_value: "value".to_string(), + key_or_index: vec![ + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Key("nested".to_string())), + ..Default::default() + }, + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Key("key".to_string())), + ..Default::default() + }, + ], + ..Default::default() + }), + ), + ..Default::default() + })); + + let input = map_log_tag( + "payload", + DataValue::from(AHashMap::from_iter([( + "nested".to_string(), + DataValue::from(AHashMap::from_iter([( + "key".to_string(), + DataValue::String("value".to_string()), + )])), + )])), + ); + let input_mismatch = map_log_tag( + "payload", + DataValue::from(AHashMap::from_iter([( + "nested".to_string(), + DataValue::from(AHashMap::from_iter([( + "key".to_string(), + DataValue::String("other".to_string()), + )])), + )])), + ); + + match_test_runner(config, vec![(input, true), (input_mismatch, false)]); +} + +#[test] +fn json_path_matcher_array_index() { + let config = simple_log_matcher(TagMatch(base_log_matcher::TagMatch { + tag_key: "payload".to_string(), + value_match: Some( + log_matcher::base_log_matcher::tag_match::Value_match::JsonValueMatch(JsonPathValueMatch { + operator: Operator::OPERATOR_EQUALS.into(), + match_value: "first".to_string(), + key_or_index: vec![ + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Key("items".to_string())), + ..Default::default() + }, + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Index(0)), + ..Default::default() + }, + ], + ..Default::default() + }), + ), + ..Default::default() + })); + + let input = map_log_tag( + "payload", + DataValue::from(AHashMap::from_iter([( + "items".to_string(), + DataValue::from(vec![ + DataValue::String("first".to_string()), + DataValue::String("second".to_string()), + ]), + )])), + ); + let input_mismatch = map_log_tag( + "payload", + DataValue::from(AHashMap::from_iter([( + "items".to_string(), + DataValue::from(vec![DataValue::String("second".to_string())]), + )])), + ); + + match_test_runner(config, vec![(input, true), (input_mismatch, false)]); +} + +#[test] +fn json_path_matcher_non_map_field() { + let config = simple_log_matcher(TagMatch(base_log_matcher::TagMatch { + tag_key: "payload".to_string(), + value_match: Some( + log_matcher::base_log_matcher::tag_match::Value_match::JsonValueMatch(JsonPathValueMatch { + operator: Operator::OPERATOR_EQUALS.into(), + match_value: "value".to_string(), + key_or_index: vec![KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Key("nested".to_string())), + ..Default::default() + }], + ..Default::default() + }), + ), + ..Default::default() + })); + + let input = log_tag("payload", "value"); + + match_test_runner(config, vec![(input, false)]); +} + +#[test] +fn json_path_matcher_missing_key() { + let config = simple_log_matcher(TagMatch(base_log_matcher::TagMatch { + tag_key: "payload".to_string(), + value_match: Some( + log_matcher::base_log_matcher::tag_match::Value_match::JsonValueMatch(JsonPathValueMatch { + operator: Operator::OPERATOR_EQUALS.into(), + match_value: "value".to_string(), + key_or_index: vec![KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Key("missing".to_string())), + ..Default::default() + }], + ..Default::default() + }), + ), + ..Default::default() + })); + + let input = map_log_tag( + "payload", + DataValue::from(AHashMap::from_iter([( + "nested".to_string(), + DataValue::String("value".to_string()), + )])), + ); + + match_test_runner(config, vec![(input, false)]); +} + +#[test] +fn json_path_matcher_out_of_range_index() { + let config = simple_log_matcher(TagMatch(base_log_matcher::TagMatch { + tag_key: "payload".to_string(), + value_match: Some( + log_matcher::base_log_matcher::tag_match::Value_match::JsonValueMatch(JsonPathValueMatch { + operator: Operator::OPERATOR_EQUALS.into(), + match_value: "value".to_string(), + key_or_index: vec![ + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Key("items".to_string())), + ..Default::default() + }, + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Index(3)), + ..Default::default() + }, + ], + ..Default::default() + }), + ), + ..Default::default() + })); + + let input = map_log_tag( + "payload", + DataValue::from(AHashMap::from_iter([( + "items".to_string(), + DataValue::from(vec![DataValue::String("value".to_string())]), + )])), + ); + + match_test_runner(config, vec![(input, false)]); +} + +#[test] +fn json_path_matcher_negative_index() { + let config = simple_log_matcher(TagMatch(base_log_matcher::TagMatch { + tag_key: "payload".to_string(), + value_match: Some( + log_matcher::base_log_matcher::tag_match::Value_match::JsonValueMatch(JsonPathValueMatch { + operator: Operator::OPERATOR_EQUALS.into(), + match_value: "last".to_string(), + key_or_index: vec![ + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Key("items".to_string())), + ..Default::default() + }, + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Index(-1)), + ..Default::default() + }, + ], + ..Default::default() + }), + ), + ..Default::default() + })); + + let input = map_log_tag( + "payload", + DataValue::from(AHashMap::from_iter([( + "items".to_string(), + DataValue::from(vec![ + DataValue::String("first".to_string()), + DataValue::String("last".to_string()), + ]), + )])), + ); + let input_mismatch = map_log_tag( + "payload", + DataValue::from(AHashMap::from_iter([( + "items".to_string(), + DataValue::from(vec![DataValue::String("only".to_string())]), + )])), + ); + + match_test_runner(config, vec![(input, true), (input_mismatch, false)]); +} + +#[test] +fn json_path_matcher_negative_index_out_of_range() { + let config = simple_log_matcher(TagMatch(base_log_matcher::TagMatch { + tag_key: "payload".to_string(), + value_match: Some( + log_matcher::base_log_matcher::tag_match::Value_match::JsonValueMatch(JsonPathValueMatch { + operator: Operator::OPERATOR_EQUALS.into(), + match_value: "value".to_string(), + key_or_index: vec![ + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Key("items".to_string())), + ..Default::default() + }, + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Index(-3)), + ..Default::default() + }, + ], + ..Default::default() + }), + ), + ..Default::default() + })); + + let input = map_log_tag( + "payload", + DataValue::from(AHashMap::from_iter([( + "items".to_string(), + DataValue::from(vec![ + DataValue::String("first".to_string()), + DataValue::String("last".to_string()), + ]), + )])), + ); + + match_test_runner(config, vec![(input, false)]); +} + +#[test] +fn json_path_matcher_nested_key_index() { + let config = simple_log_matcher(TagMatch(base_log_matcher::TagMatch { + tag_key: "payload".to_string(), + value_match: Some( + log_matcher::base_log_matcher::tag_match::Value_match::JsonValueMatch(JsonPathValueMatch { + operator: Operator::OPERATOR_EQUALS.into(), + match_value: "value".to_string(), + key_or_index: vec![ + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Key("items".to_string())), + ..Default::default() + }, + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Index(0)), + ..Default::default() + }, + KeyOrIndex { + key_or_index: Some(key_or_index::Key_or_index::Key("inner".to_string())), + ..Default::default() + }, + ], + ..Default::default() + }), + ), + ..Default::default() + })); + + let input = map_log_tag( + "payload", + DataValue::from(AHashMap::from_iter([( + "items".to_string(), + DataValue::from(vec![DataValue::from(AHashMap::from_iter([( + "inner".to_string(), + DataValue::String("value".to_string()), + )]))]), + )])), + ); + let input_mismatch = map_log_tag( + "payload", + DataValue::from(AHashMap::from_iter([( + "items".to_string(), + DataValue::from(vec![DataValue::from(AHashMap::from_iter([( + "inner".to_string(), + DataValue::String("other".to_string()), + )]))]), + )])), + ); + + match_test_runner(config, vec![(input, true), (input_mismatch, false)]); +} + #[test] fn test_message_string_eq_matcher() { match_test_runner( diff --git a/bd-log-primitives/src/lib.rs b/bd-log-primitives/src/lib.rs index 8a30ee613..cf6b3e4d7 100644 --- a/bd-log-primitives/src/lib.rs +++ b/bd-log-primitives/src/lib.rs @@ -27,7 +27,7 @@ use crate::zlib::DEFAULT_MOBILE_ZLIB_COMPRESSION_LEVEL; use ahash::AHashMap; use bd_macros::proto_serializable; use bd_proto::protos::logging::payload::data::Data_type; -use bd_proto::protos::logging::payload::{BinaryData, Data, LogType}; +use bd_proto::protos::logging::payload::{ArrayData, BinaryData, Data, LogType, MapData}; use bd_proto_util::serialization::ProtoMessageSerialize; use bd_time::OffsetDateTimeExt as _; use flate2::Compression; @@ -162,6 +162,92 @@ impl std::ops::Deref for LogBinaryData { } } +#[proto_serializable(validate_against = "bd_proto::protos::logging::payload::MapData")] +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct LogMapData { + #[field(id = 1)] + entries: AHashMap, +} + +impl LogMapData { + #[must_use] + pub fn new(entries: AHashMap) -> Self { + Self { entries } + } + + #[must_use] + pub fn entries(&self) -> &AHashMap { + &self.entries + } + + #[must_use] + pub fn into_entries(self) -> AHashMap { + self.entries + } + + #[must_use] + pub fn into_proto(self) -> MapData { + MapData { + entries: self + .entries + .into_iter() + .map(|(key, value)| (key, value.into_proto())) + .collect(), + ..Default::default() + } + } + + pub fn from_proto(map_data: MapData) -> Option { + let entries = map_data + .entries + .into_iter() + .map(|(key, value)| DataValue::from_proto(value).map(|value| (key, value))) + .collect::>>()?; + Some(Self { entries }) + } +} + +#[proto_serializable(validate_against = "bd_proto::protos::logging::payload::ArrayData")] +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct LogArrayData { + #[field(id = 1)] + items: Vec, +} + +impl LogArrayData { + #[must_use] + pub fn new(items: Vec) -> Self { + Self { items } + } + + #[must_use] + pub fn items(&self) -> &Vec { + &self.items + } + + #[must_use] + pub fn into_items(self) -> Vec { + self.items + } + + #[must_use] + pub fn into_proto(self) -> ArrayData { + ArrayData { + items: self.items.into_iter().map(DataValue::into_proto).collect(), + ..Default::default() + } + } + + pub fn from_proto(array_data: ArrayData) -> Option { + let items = array_data + .items + .into_iter() + .map(DataValue::from_proto) + .collect::>>()?; + Some(Self { items }) + } +} + /// A union type that allows representing either a UTF-8 string, binary data, or primitive values. #[proto_serializable(validate_against = "bd_proto::protos::logging::payload::Data")] #[derive(Debug, Clone, PartialEq, Eq)] @@ -182,6 +268,10 @@ pub enum DataValue { I64(i64), #[field(id = 4)] Double(NotNan), + #[field(id = 7)] + Map(LogMapData), + #[field(id = 8)] + Array(LogArrayData), } impl DataValue { @@ -207,6 +297,8 @@ impl DataValue { Self::U64(v) => Data_type::IntData(v), Self::I64(v) => Data_type::SintData(v), Self::Double(v) => Data_type::DoubleData(*v), + Self::Map(map_data) => Data_type::MapData(map_data.into_proto()), + Self::Array(array_data) => Data_type::ArrayData(array_data.into_proto()), }), ..Default::default() } @@ -220,6 +312,8 @@ impl DataValue { Data_type::IntData(v) => Some(Self::U64(v)), Data_type::SintData(v) => Some(Self::I64(v)), Data_type::DoubleData(v) => Some(Self::Double(NotNan::new(v).ok()?)), + Data_type::MapData(map_data) => Some(Self::Map(LogMapData::from_proto(map_data)?)), + Data_type::ArrayData(array_data) => Some(Self::Array(LogArrayData::from_proto(array_data)?)), } } @@ -230,7 +324,13 @@ impl DataValue { Self::String(s) => Some(s.as_ref()), Self::SharedString(s) => Some(s.as_ref()), Self::StaticString(s) => Some(s), - Self::Bytes(_) | Self::Boolean(_) | Self::U64(_) | Self::I64(_) | Self::Double(_) => None, + Self::Bytes(_) + | Self::Boolean(_) + | Self::U64(_) + | Self::I64(_) + | Self::Double(_) + | Self::Map(_) + | Self::Array(_) => None, } } @@ -244,7 +344,9 @@ impl DataValue { | Self::Boolean(_) | Self::U64(_) | Self::I64(_) - | Self::Double(_) => None, + | Self::Double(_) + | Self::Map(_) + | Self::Array(_) => None, Self::Bytes(b) => Some(b.as_ref()), } } @@ -268,6 +370,24 @@ impl From> for DataValue { } } +impl Default for DataValue { + fn default() -> Self { + Self::String(String::new()) + } +} + +impl From> for DataValue { + fn from(value: AHashMap) -> Self { + Self::Map(LogMapData::new(value)) + } +} + +impl From> for DataValue { + fn from(value: Vec) -> Self { + Self::Array(LogArrayData::new(value)) + } +} + impl From<&str> for DataValue { fn from(s: &str) -> Self { Self::String(s.to_string()) @@ -297,6 +417,8 @@ impl std::fmt::Display for LogMessage { Self::U64(v) => write!(f, "{v}"), Self::I64(v) => write!(f, "{v}"), Self::Double(v) => write!(f, "{v}"), + Self::Map(map_data) => write!(f, "map:{:?}", map_data.entries()), + Self::Array(array_data) => write!(f, "array:{:?}", array_data.items()), } } } @@ -792,6 +914,15 @@ impl<'a> FieldsRef<'a> { self.matching_field_value(field_key).map(Cow::Borrowed) } + + #[must_use] + pub fn field(&self, field_key: &str) -> Option<&'a LogFieldValue> { + if let Some(value) = self.captured_fields.get(field_key) { + return Some(value); + } + + self.matching_fields.get(field_key) + } } // @@ -829,6 +960,8 @@ impl MemorySized for LogFieldValue { | Self::I64(_) | Self::Double(_) => 0, Self::Bytes(b) => b.capacity(), + Self::Map(map_data) => map_data.entries().size(), + Self::Array(array_data) => array_data.items().size(), } } } diff --git a/bd-log-primitives/src/lib_test.rs b/bd-log-primitives/src/lib_test.rs index 890c349e5..8308ca0db 100644 --- a/bd-log-primitives/src/lib_test.rs +++ b/bd-log-primitives/src/lib_test.rs @@ -11,7 +11,7 @@ use crate::{DataValue, EncodableLog, Log, LogFieldValue, LogType}; use ahash::AHashMap; use bd_proto::protos::logging::payload::data::Data_type; use bd_proto::protos::logging::payload::log::Field; -use bd_proto::protos::logging::payload::{BinaryData, Data}; +use bd_proto::protos::logging::payload::{ArrayData, BinaryData, Data, MapData}; use ordered_float::NotNan; use protobuf::{Message, MessageFull}; use std::borrow::Cow; @@ -44,7 +44,8 @@ fn custom_proto_encoder() { Data::descriptor() .fields() .for_each(|field| match field.name() { - "string_data" | "binary_data" | "int_data" | "double_data" | "bool_data" | "sint_data" => {}, + "string_data" | "binary_data" | "int_data" | "double_data" | "bool_data" | "sint_data" + | "map_data" | "array_data" => {}, other => panic!("unexpected field added to Data proto: {other}"), }); // Note that "type" is unused currently and not encoded. @@ -104,6 +105,38 @@ fn data_encoding() { ..Default::default() }, ), + ( + LogFieldValue::from(AHashMap::from_iter([( + "key".to_string(), + LogFieldValue::String("value".to_string()), + )])), + Data { + data_type: Some(Data_type::MapData(MapData { + entries: std::collections::HashMap::from_iter([( + "key".to_string(), + Data { + data_type: Some(Data_type::StringData("value".to_string())), + ..Default::default() + }, + )]), + ..Default::default() + })), + ..Default::default() + }, + ), + ( + LogFieldValue::from(vec![LogFieldValue::String("value".to_string())]), + Data { + data_type: Some(Data_type::ArrayData(ArrayData { + items: vec![Data { + data_type: Some(Data_type::StringData("value".to_string())), + ..Default::default() + }], + ..Default::default() + })), + ..Default::default() + }, + ), ]; for (input, expected) in cases { diff --git a/bd-logger/src/async_log_buffer_test.rs b/bd-logger/src/async_log_buffer_test.rs index d3081d249..34a92b2eb 100644 --- a/bd-logger/src/async_log_buffer_test.rs +++ b/bd-logger/src/async_log_buffer_test.rs @@ -278,7 +278,7 @@ fn log_line_size_is_computed_correctly() { } } - let baseline_log_expected_size = 488; + let baseline_log_expected_size = 688; let baseline_log = create_baseline_log(); assert_eq!(baseline_log_expected_size, baseline_log.size()); @@ -328,7 +328,7 @@ fn annotated_log_line_size_is_computed_correctly() { } } - let baseline_log_expected_size = 561; + let baseline_log_expected_size = 761; let baseline_log = create_baseline_log(); assert_eq!(baseline_log_expected_size, baseline_log.size()); diff --git a/bd-logger/src/network.rs b/bd-logger/src/network.rs index b95e78e63..6990fa0a8 100644 --- a/bd-logger/src/network.rs +++ b/bd-logger/src/network.rs @@ -292,7 +292,9 @@ fn get_int_field_value(fields: &AnnotatedLogFields, field_key: &str) -> Option return None, + | DataValue::Double(_) + | DataValue::Map(_) + | DataValue::Array(_) => return None, }; string_value.parse::().ok() diff --git a/bd-metadata/src/lib.rs b/bd-metadata/src/lib.rs index 75890e578..875658ddb 100644 --- a/bd-metadata/src/lib.rs +++ b/bd-metadata/src/lib.rs @@ -30,7 +30,7 @@ use std::collections::HashMap; // Version 34: Added support for data idle timeouts and reconnect delays. // Version 35: Added support for workflow matching and tag extraction against feature flags. // Version 36: Added support for state to the worfklow engine. -const CONFIGURATION_VERSION: &str = "36"; +const CONFIGURATION_VERSION: &str = "37"; /// The platform we're currently running as. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] diff --git a/bd-proto/src/protos/log_matcher/log_matcher.rs b/bd-proto/src/protos/log_matcher/log_matcher.rs index 8a0a4716a..782bc3962 100644 --- a/bd-proto/src/protos/log_matcher/log_matcher.rs +++ b/bd-proto/src/protos/log_matcher/log_matcher.rs @@ -1182,8 +1182,57 @@ pub mod log_matcher { } } + // .bitdrift_public.protobuf.value_matcher.v1.JsonPathValueMatch json_value_match = 7; + + pub fn json_value_match(&self) -> &super::super::super::value_matcher::JsonPathValueMatch { + match self.value_match { + ::std::option::Option::Some(tag_match::Value_match::JsonValueMatch(ref v)) => v, + _ => ::default_instance(), + } + } + + pub fn clear_json_value_match(&mut self) { + self.value_match = ::std::option::Option::None; + } + + pub fn has_json_value_match(&self) -> bool { + match self.value_match { + ::std::option::Option::Some(tag_match::Value_match::JsonValueMatch(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_json_value_match(&mut self, v: super::super::super::value_matcher::JsonPathValueMatch) { + self.value_match = ::std::option::Option::Some(tag_match::Value_match::JsonValueMatch(v)) + } + + // Mutable pointer to the field. + pub fn mut_json_value_match(&mut self) -> &mut super::super::super::value_matcher::JsonPathValueMatch { + if let ::std::option::Option::Some(tag_match::Value_match::JsonValueMatch(_)) = self.value_match { + } else { + self.value_match = ::std::option::Option::Some(tag_match::Value_match::JsonValueMatch(super::super::super::value_matcher::JsonPathValueMatch::new())); + } + match self.value_match { + ::std::option::Option::Some(tag_match::Value_match::JsonValueMatch(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_json_value_match(&mut self) -> super::super::super::value_matcher::JsonPathValueMatch { + if self.has_json_value_match() { + match self.value_match.take() { + ::std::option::Option::Some(tag_match::Value_match::JsonValueMatch(v)) => v, + _ => panic!(), + } + } else { + super::super::super::value_matcher::JsonPathValueMatch::new() + } + } + pub(in super::super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(6); + let mut fields = ::std::vec::Vec::with_capacity(7); let mut oneofs = ::std::vec::Vec::with_capacity(1); fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( "tag_key", @@ -1225,6 +1274,13 @@ pub mod log_matcher { TagMatch::mut_double_value_match, TagMatch::set_double_value_match, )); + fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, super::super::super::value_matcher::JsonPathValueMatch>( + "json_value_match", + TagMatch::has_json_value_match, + TagMatch::json_value_match, + TagMatch::mut_json_value_match, + TagMatch::set_json_value_match, + )); oneofs.push(tag_match::Value_match::generated_oneof_descriptor_data()); ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( "LogMatcher.BaseLogMatcher.TagMatch", @@ -1262,6 +1318,9 @@ pub mod log_matcher { 50 => { self.value_match = ::std::option::Option::Some(tag_match::Value_match::DoubleValueMatch(is.read_message()?)); }, + 58 => { + self.value_match = ::std::option::Option::Some(tag_match::Value_match::JsonValueMatch(is.read_message()?)); + }, tag => { ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; }, @@ -1299,6 +1358,10 @@ pub mod log_matcher { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; }, + &tag_match::Value_match::JsonValueMatch(ref v) => { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }, }; } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); @@ -1327,6 +1390,9 @@ pub mod log_matcher { &tag_match::Value_match::DoubleValueMatch(ref v) => { ::protobuf::rt::write_message_field_with_cached_size(6, v, os)?; }, + &tag_match::Value_match::JsonValueMatch(ref v) => { + ::protobuf::rt::write_message_field_with_cached_size(7, v, os)?; + }, }; } os.write_unknown_fields(self.special_fields.unknown_fields())?; @@ -1352,6 +1418,7 @@ pub mod log_matcher { self.value_match = ::std::option::Option::None; self.value_match = ::std::option::Option::None; self.value_match = ::std::option::Option::None; + self.value_match = ::std::option::Option::None; self.special_fields.clear(); } @@ -1398,6 +1465,8 @@ pub mod log_matcher { IsSetMatch(super::super::super::super::value_matcher::IsSetMatch), // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.matcher.v1.LogMatcher.BaseLogMatcher.TagMatch.double_value_match) DoubleValueMatch(super::super::super::super::value_matcher::DoubleValueMatch), + // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.matcher.v1.LogMatcher.BaseLogMatcher.TagMatch.json_value_match) + JsonValueMatch(super::super::super::super::value_matcher::JsonPathValueMatch), } impl ::protobuf::Oneof for Value_match { @@ -1706,42 +1775,44 @@ static file_descriptor_proto_data: &'static [u8] = b"\ blic.protobuf.matcher.v1\x1a/bitdrift_public/protobuf/state/v1/matcher.p\ roto\x1a-bitdrift_public/protobuf/state/v1/scope.proto\x1a=bitdrift_publ\ ic/protobuf/value_matcher/v1/value_matcher.proto\x1a\x17validate/validat\ - e.proto\"\xab\x0e\n\nLogMatcher\x12c\n\x0cbase_matcher\x18\x01\x20\x01(\ + e.proto\"\x96\x0f\n\nLogMatcher\x12c\n\x0cbase_matcher\x18\x01\x20\x01(\ \x0b2>.bitdrift_public.protobuf.matcher.v1.LogMatcher.BaseLogMatcherH\0R\ \x0bbaseMatcher\x12\\\n\nor_matcher\x18\x02\x20\x01(\x0b2;.bitdrift_publ\ ic.protobuf.matcher.v1.LogMatcher.MatcherListH\0R\torMatcher\x12^\n\x0ba\ nd_matcher\x18\x03\x20\x01(\x0b2;.bitdrift_public.protobuf.matcher.v1.Lo\ gMatcher.MatcherListH\0R\nandMatcher\x12R\n\x0bnot_matcher\x18\x04\x20\ \x01(\x0b2/.bitdrift_public.protobuf.matcher.v1.LogMatcherH\0R\nnotMatch\ - er\x1a\xa8\n\n\x0eBaseLogMatcher\x12r\n\rmessage_match\x18\x01\x20\x01(\ - \x0b2K.bitdrift_public.protobuf.matcher.v1.LogMatcher.BaseLogMatcher.Mes\ - sageMatchH\0R\x0cmessageMatch\x12f\n\ttag_match\x18\x02\x20\x01(\x0b2G.b\ - itdrift_public.protobuf.matcher.v1.LogMatcher.BaseLogMatcher.TagMatchH\0\ - R\x08tagMatch\x12l\n\x0bstate_match\x18\x04\x20\x01(\x0b2I.bitdrift_publ\ - ic.protobuf.matcher.v1.LogMatcher.BaseLogMatcher.StateMatchH\0R\nstateMa\ - tch\x1ay\n\x0cMessageMatch\x12i\n\x12string_value_match\x18\x01\x20\x01(\ - \x0b2;.bitdrift_public.protobuf.value_matcher.v1.StringValueMatchR\x10st\ - ringValueMatch\x1a\xc9\x04\n\x08TagMatch\x12\"\n\x07tag_key\x18\x01\x20\ - \x01(\tR\x06tagKeyB\t\xfaB\x06r\x04\x10\x01\x18@\x12k\n\x12string_value_\ - match\x18\x02\x20\x01(\x0b2;.bitdrift_public.protobuf.value_matcher.v1.S\ - tringValueMatchH\0R\x10stringValueMatch\x12b\n\x0fint_value_match\x18\ - \x03\x20\x01(\x0b28.bitdrift_public.protobuf.value_matcher.v1.IntValueMa\ - tchH\0R\rintValueMatch\x12l\n\x13sem_ver_value_match\x18\x04\x20\x01(\ - \x0b2;.bitdrift_public.protobuf.value_matcher.v1.SemVerValueMatchH\0R\ - \x10semVerValueMatch\x12Y\n\x0cis_set_match\x18\x05\x20\x01(\x0b25.bitdr\ - ift_public.protobuf.value_matcher.v1.IsSetMatchH\0R\nisSetMatch\x12k\n\ - \x12double_value_match\x18\x06\x20\x01(\x0b2;.bitdrift_public.protobuf.v\ - alue_matcher.v1.DoubleValueMatchH\0R\x10doubleValueMatchB\x12\n\x0bvalue\ - _match\x12\x03\xf8B\x01\x1a\xeb\x01\n\nStateMatch\x12M\n\x05scope\x18\ - \x01\x20\x01(\x0e2-.bitdrift_public.protobuf.state.v1.StateScopeR\x05sco\ - peB\x08\xfaB\x05\x82\x01\x02\x10\x01\x12$\n\tstate_key\x18\x02\x20\x01(\ - \tR\x08stateKeyB\x07\xfaB\x04r\x02\x10\x01\x12h\n\x11state_value_match\ - \x18\x03\x20\x01(\x0b22.bitdrift_public.protobuf.state.v1.StateValueMatc\ - hR\x0fstateValueMatchB\x08\xfaB\x05\x8a\x01\x02\x10\x01B\x11\n\nmatch_ty\ - pe\x12\x03\xf8B\x01J\x04\x08\x03\x10\x04\x1ak\n\x0bMatcherList\x12\\\n\ - \x0clog_matchers\x18\x01\x20\x03(\x0b2/.bitdrift_public.protobuf.matcher\ - .v1.LogMatcherR\x0blogMatchersB\x08\xfaB\x05\x92\x01\x02\x08\x02B\x0e\n\ - \x07matcher\x12\x03\xf8B\x01b\x06proto3\ + er\x1a\x93\x0b\n\x0eBaseLogMatcher\x12r\n\rmessage_match\x18\x01\x20\x01\ + (\x0b2K.bitdrift_public.protobuf.matcher.v1.LogMatcher.BaseLogMatcher.Me\ + ssageMatchH\0R\x0cmessageMatch\x12f\n\ttag_match\x18\x02\x20\x01(\x0b2G.\ + bitdrift_public.protobuf.matcher.v1.LogMatcher.BaseLogMatcher.TagMatchH\ + \0R\x08tagMatch\x12l\n\x0bstate_match\x18\x04\x20\x01(\x0b2I.bitdrift_pu\ + blic.protobuf.matcher.v1.LogMatcher.BaseLogMatcher.StateMatchH\0R\nstate\ + Match\x1ay\n\x0cMessageMatch\x12i\n\x12string_value_match\x18\x01\x20\ + \x01(\x0b2;.bitdrift_public.protobuf.value_matcher.v1.StringValueMatchR\ + \x10stringValueMatch\x1a\xb4\x05\n\x08TagMatch\x12\"\n\x07tag_key\x18\ + \x01\x20\x01(\tR\x06tagKeyB\t\xfaB\x06r\x04\x10\x01\x18@\x12k\n\x12strin\ + g_value_match\x18\x02\x20\x01(\x0b2;.bitdrift_public.protobuf.value_matc\ + her.v1.StringValueMatchH\0R\x10stringValueMatch\x12b\n\x0fint_value_matc\ + h\x18\x03\x20\x01(\x0b28.bitdrift_public.protobuf.value_matcher.v1.IntVa\ + lueMatchH\0R\rintValueMatch\x12l\n\x13sem_ver_value_match\x18\x04\x20\ + \x01(\x0b2;.bitdrift_public.protobuf.value_matcher.v1.SemVerValueMatchH\ + \0R\x10semVerValueMatch\x12Y\n\x0cis_set_match\x18\x05\x20\x01(\x0b25.bi\ + tdrift_public.protobuf.value_matcher.v1.IsSetMatchH\0R\nisSetMatch\x12k\ + \n\x12double_value_match\x18\x06\x20\x01(\x0b2;.bitdrift_public.protobuf\ + .value_matcher.v1.DoubleValueMatchH\0R\x10doubleValueMatch\x12i\n\x10jso\ + n_value_match\x18\x07\x20\x01(\x0b2=.bitdrift_public.protobuf.value_matc\ + her.v1.JsonPathValueMatchH\0R\x0ejsonValueMatchB\x12\n\x0bvalue_match\ + \x12\x03\xf8B\x01\x1a\xeb\x01\n\nStateMatch\x12M\n\x05scope\x18\x01\x20\ + \x01(\x0e2-.bitdrift_public.protobuf.state.v1.StateScopeR\x05scopeB\x08\ + \xfaB\x05\x82\x01\x02\x10\x01\x12$\n\tstate_key\x18\x02\x20\x01(\tR\x08s\ + tateKeyB\x07\xfaB\x04r\x02\x10\x01\x12h\n\x11state_value_match\x18\x03\ + \x20\x01(\x0b22.bitdrift_public.protobuf.state.v1.StateValueMatchR\x0fst\ + ateValueMatchB\x08\xfaB\x05\x8a\x01\x02\x10\x01B\x11\n\nmatch_type\x12\ + \x03\xf8B\x01J\x04\x08\x03\x10\x04\x1ak\n\x0bMatcherList\x12\\\n\x0clog_\ + matchers\x18\x01\x20\x03(\x0b2/.bitdrift_public.protobuf.matcher.v1.LogM\ + atcherR\x0blogMatchersB\x08\xfaB\x05\x92\x01\x02\x08\x02B\x0e\n\x07match\ + er\x12\x03\xf8B\x01b\x06proto3\ "; /// `FileDescriptorProto` object which was a source for this generated file diff --git a/bd-proto/src/protos/logging/payload.rs b/bd-proto/src/protos/logging/payload.rs index b81fb1f20..fde6052ba 100644 --- a/bd-proto/src/protos/logging/payload.rs +++ b/bd-proto/src/protos/logging/payload.rs @@ -390,8 +390,106 @@ impl Data { self.data_type = ::std::option::Option::Some(data::Data_type::BoolData(v)) } + // .bitdrift_public.protobuf.logging.v1.MapData map_data = 7; + + pub fn map_data(&self) -> &MapData { + match self.data_type { + ::std::option::Option::Some(data::Data_type::MapData(ref v)) => v, + _ => ::default_instance(), + } + } + + pub fn clear_map_data(&mut self) { + self.data_type = ::std::option::Option::None; + } + + pub fn has_map_data(&self) -> bool { + match self.data_type { + ::std::option::Option::Some(data::Data_type::MapData(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_map_data(&mut self, v: MapData) { + self.data_type = ::std::option::Option::Some(data::Data_type::MapData(v)) + } + + // Mutable pointer to the field. + pub fn mut_map_data(&mut self) -> &mut MapData { + if let ::std::option::Option::Some(data::Data_type::MapData(_)) = self.data_type { + } else { + self.data_type = ::std::option::Option::Some(data::Data_type::MapData(MapData::new())); + } + match self.data_type { + ::std::option::Option::Some(data::Data_type::MapData(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_map_data(&mut self) -> MapData { + if self.has_map_data() { + match self.data_type.take() { + ::std::option::Option::Some(data::Data_type::MapData(v)) => v, + _ => panic!(), + } + } else { + MapData::new() + } + } + + // .bitdrift_public.protobuf.logging.v1.ArrayData array_data = 8; + + pub fn array_data(&self) -> &ArrayData { + match self.data_type { + ::std::option::Option::Some(data::Data_type::ArrayData(ref v)) => v, + _ => ::default_instance(), + } + } + + pub fn clear_array_data(&mut self) { + self.data_type = ::std::option::Option::None; + } + + pub fn has_array_data(&self) -> bool { + match self.data_type { + ::std::option::Option::Some(data::Data_type::ArrayData(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_array_data(&mut self, v: ArrayData) { + self.data_type = ::std::option::Option::Some(data::Data_type::ArrayData(v)) + } + + // Mutable pointer to the field. + pub fn mut_array_data(&mut self) -> &mut ArrayData { + if let ::std::option::Option::Some(data::Data_type::ArrayData(_)) = self.data_type { + } else { + self.data_type = ::std::option::Option::Some(data::Data_type::ArrayData(ArrayData::new())); + } + match self.data_type { + ::std::option::Option::Some(data::Data_type::ArrayData(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_array_data(&mut self) -> ArrayData { + if self.has_array_data() { + match self.data_type.take() { + ::std::option::Option::Some(data::Data_type::ArrayData(v)) => v, + _ => panic!(), + } + } else { + ArrayData::new() + } + } + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(6); + let mut fields = ::std::vec::Vec::with_capacity(8); let mut oneofs = ::std::vec::Vec::with_capacity(1); fields.push(::protobuf::reflect::rt::v2::make_oneof_deref_has_get_set_simpler_accessor::<_, _>( "string_data", @@ -430,6 +528,20 @@ impl Data { Data::bool_data, Data::set_bool_data, )); + fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, MapData>( + "map_data", + Data::has_map_data, + Data::map_data, + Data::mut_map_data, + Data::set_map_data, + )); + fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, ArrayData>( + "array_data", + Data::has_array_data, + Data::array_data, + Data::mut_array_data, + Data::set_array_data, + )); oneofs.push(data::Data_type::generated_oneof_descriptor_data()); ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( "Data", @@ -467,6 +579,12 @@ impl ::protobuf::Message for Data { 48 => { self.data_type = ::std::option::Option::Some(data::Data_type::BoolData(is.read_bool()?)); }, + 58 => { + self.data_type = ::std::option::Option::Some(data::Data_type::MapData(is.read_message()?)); + }, + 66 => { + self.data_type = ::std::option::Option::Some(data::Data_type::ArrayData(is.read_message()?)); + }, tag => { ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; }, @@ -500,6 +618,14 @@ impl ::protobuf::Message for Data { &data::Data_type::BoolData(v) => { my_size += 1 + 1; }, + &data::Data_type::MapData(ref v) => { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }, + &data::Data_type::ArrayData(ref v) => { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }, }; } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); @@ -528,6 +654,12 @@ impl ::protobuf::Message for Data { &data::Data_type::BoolData(v) => { os.write_bool(6, v)?; }, + &data::Data_type::MapData(ref v) => { + ::protobuf::rt::write_message_field_with_cached_size(7, v, os)?; + }, + &data::Data_type::ArrayData(ref v) => { + ::protobuf::rt::write_message_field_with_cached_size(8, v, os)?; + }, }; } os.write_unknown_fields(self.special_fields.unknown_fields())?; @@ -553,6 +685,8 @@ impl ::protobuf::Message for Data { self.data_type = ::std::option::Option::None; self.data_type = ::std::option::Option::None; self.data_type = ::std::option::Option::None; + self.data_type = ::std::option::Option::None; + self.data_type = ::std::option::Option::None; self.special_fields.clear(); } @@ -600,6 +734,10 @@ pub mod data { SintData(i64), // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.logging.v1.Data.bool_data) BoolData(bool), + // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.logging.v1.Data.map_data) + MapData(super::MapData), + // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.logging.v1.Data.array_data) + ArrayData(super::ArrayData), } impl ::protobuf::Oneof for Data_type { @@ -619,6 +757,271 @@ pub mod data { } } +// @@protoc_insertion_point(message:bitdrift_public.protobuf.logging.v1.MapData) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct MapData { + // message fields + // @@protoc_insertion_point(field:bitdrift_public.protobuf.logging.v1.MapData.entries) + pub entries: ::std::collections::HashMap<::std::string::String, Data>, + // special fields + // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.logging.v1.MapData.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a MapData { + fn default() -> &'a MapData { + ::default_instance() + } +} + +impl MapData { + pub fn new() -> MapData { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_map_simpler_accessor_new::<_, _>( + "entries", + |m: &MapData| { &m.entries }, + |m: &mut MapData| { &mut m.entries }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "MapData", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for MapData { + const NAME: &'static str = "MapData"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + let len = is.read_raw_varint32()?; + let old_limit = is.push_limit(len as u64)?; + let mut key = ::std::default::Default::default(); + let mut value = ::std::default::Default::default(); + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => key = is.read_string()?, + 18 => value = is.read_message()?, + _ => ::protobuf::rt::skip_field_for_tag(tag, is)?, + }; + } + is.pop_limit(old_limit); + self.entries.insert(key, value); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + for (k, v) in &self.entries { + let mut entry_size = 0; + entry_size += ::protobuf::rt::string_size(1, &k); + let len = v.compute_size(); + entry_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(entry_size) + entry_size + }; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + for (k, v) in &self.entries { + let mut entry_size = 0; + entry_size += ::protobuf::rt::string_size(1, &k); + let len = v.cached_size() as u64; + entry_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + os.write_raw_varint32(10)?; // Tag. + os.write_raw_varint32(entry_size as u32)?; + os.write_string(1, &k)?; + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + }; + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> MapData { + MapData::new() + } + + fn clear(&mut self) { + self.entries.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static MapData { + static instance: ::protobuf::rt::Lazy = ::protobuf::rt::Lazy::new(); + instance.get(MapData::new) + } +} + +impl ::protobuf::MessageFull for MapData { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("MapData").unwrap()).clone() + } +} + +impl ::std::fmt::Display for MapData { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MapData { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:bitdrift_public.protobuf.logging.v1.ArrayData) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct ArrayData { + // message fields + // @@protoc_insertion_point(field:bitdrift_public.protobuf.logging.v1.ArrayData.items) + pub items: ::std::vec::Vec, + // special fields + // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.logging.v1.ArrayData.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a ArrayData { + fn default() -> &'a ArrayData { + ::default_instance() + } +} + +impl ArrayData { + pub fn new() -> ArrayData { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "items", + |m: &ArrayData| { &m.items }, + |m: &mut ArrayData| { &mut m.items }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "ArrayData", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for ArrayData { + const NAME: &'static str = "ArrayData"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.items.push(is.read_message()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + for v in &self.items { + ::protobuf::rt::write_message_field_with_cached_size(1, v, os)?; + }; + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> ArrayData { + ArrayData::new() + } + + fn clear(&mut self) { + self.items.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static ArrayData { + static instance: ArrayData = ArrayData { + items: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for ArrayData { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("ArrayData").unwrap()).clone() + } +} + +impl ::std::fmt::Display for ArrayData { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ArrayData { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + // @@protoc_insertion_point(message:bitdrift_public.protobuf.logging.v1.Log) #[derive(PartialEq,Clone,Default,Debug)] pub struct Log { @@ -1274,31 +1677,40 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \n1bitdrift_public/protobuf/logging/v1/payload.proto\x12#bitdrift_public\ .protobuf.logging.v1\"H\n\nBinaryData\x12\x17\n\x04type\x18\x01\x20\x01(\ \tH\0R\x04type\x88\x01\x01\x12\x18\n\x07payload\x18\x02\x20\x01(\x0cR\ - \x07payloadB\x07\n\x05_type\"\x88\x02\n\x04Data\x12!\n\x0bstring_data\ + \x07payloadB\x07\n\x05_type\"\xa4\x03\n\x04Data\x12!\n\x0bstring_data\ \x18\x01\x20\x01(\tH\0R\nstringData\x12R\n\x0bbinary_data\x18\x02\x20\ \x01(\x0b2/.bitdrift_public.protobuf.logging.v1.BinaryDataH\0R\nbinaryDa\ ta\x12\x1b\n\x08int_data\x18\x03\x20\x01(\x04H\0R\x07intData\x12!\n\x0bd\ ouble_data\x18\x04\x20\x01(\x01H\0R\ndoubleData\x12\x1d\n\tsint_data\x18\ \x05\x20\x01(\x03H\0R\x08sintData\x12\x1d\n\tbool_data\x18\x06\x20\x01(\ - \x08H\0R\x08boolDataB\x0b\n\tdata_type\"\xb8\x05\n\x03Log\x120\n\x14time\ - stamp_unix_micro\x18\x01\x20\x01(\x04R\x12timestampUnixMicro\x12\x1b\n\t\ - log_level\x18\x02\x20\x01(\rR\x08logLevel\x12C\n\x07message\x18\x03\x20\ - \x01(\x0b2).bitdrift_public.protobuf.logging.v1.DataR\x07message\x12F\n\ - \x06fields\x18\x04\x20\x03(\x0b2..bitdrift_public.protobuf.logging.v1.Lo\ - g.FieldR\x06fields\x12\x1d\n\nsession_id\x18\x05\x20\x01(\tR\tsessionId\ - \x12\x1d\n\naction_ids\x18\x06\x20\x03(\tR\tactionIds\x12G\n\x08log_type\ - \x18\x07\x20\x01(\x0e2,.bitdrift_public.protobuf.logging.v1.LogTypeR\x07\ - logType\x12\x1d\n\nstream_ids\x18\x08\x20\x03(\tR\tstreamIds\x12/\n\x13c\ - ompressed_contents\x18\t\x20\x01(\x0cR\x12compressedContents\x1aZ\n\x05F\ - ield\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12?\n\x05value\x18\x02\ - \x20\x01(\x0b2).bitdrift_public.protobuf.logging.v1.DataR\x05value\x1a\ - \xa1\x01\n\x12CompressedContents\x12C\n\x07message\x18\x01\x20\x01(\x0b2\ - ).bitdrift_public.protobuf.logging.v1.DataR\x07message\x12F\n\x06fields\ - \x18\x02\x20\x03(\x0b2..bitdrift_public.protobuf.logging.v1.Log.FieldR\ - \x06fields*x\n\x07LogType\x12\n\n\x06NORMAL\x10\0\x12\n\n\x06REPLAY\x10\ - \x01\x12\r\n\tLIFECYCLE\x10\x02\x12\x0c\n\x08RESOURCE\x10\x03\x12\x10\n\ - \x0cINTERNAL_SDK\x10\x04\x12\x08\n\x04VIEW\x10\x05\x12\n\n\x06DEVICE\x10\ - \x06\x12\x06\n\x02UX\x10\x07\x12\x08\n\x04SPAN\x10\x08b\x06proto3\ + \x08H\0R\x08boolData\x12I\n\x08map_data\x18\x07\x20\x01(\x0b2,.bitdrift_\ + public.protobuf.logging.v1.MapDataH\0R\x07mapData\x12O\n\narray_data\x18\ + \x08\x20\x01(\x0b2..bitdrift_public.protobuf.logging.v1.ArrayDataH\0R\ta\ + rrayDataB\x0b\n\tdata_type\"\xc5\x01\n\x07MapData\x12S\n\x07entries\x18\ + \x01\x20\x03(\x0b29.bitdrift_public.protobuf.logging.v1.MapData.EntriesE\ + ntryR\x07entries\x1ae\n\x0cEntriesEntry\x12\x10\n\x03key\x18\x01\x20\x01\ + (\tR\x03key\x12?\n\x05value\x18\x02\x20\x01(\x0b2).bitdrift_public.proto\ + buf.logging.v1.DataR\x05value:\x028\x01\"L\n\tArrayData\x12?\n\x05items\ + \x18\x01\x20\x03(\x0b2).bitdrift_public.protobuf.logging.v1.DataR\x05ite\ + ms\"\xb8\x05\n\x03Log\x120\n\x14timestamp_unix_micro\x18\x01\x20\x01(\ + \x04R\x12timestampUnixMicro\x12\x1b\n\tlog_level\x18\x02\x20\x01(\rR\x08\ + logLevel\x12C\n\x07message\x18\x03\x20\x01(\x0b2).bitdrift_public.protob\ + uf.logging.v1.DataR\x07message\x12F\n\x06fields\x18\x04\x20\x03(\x0b2..b\ + itdrift_public.protobuf.logging.v1.Log.FieldR\x06fields\x12\x1d\n\nsessi\ + on_id\x18\x05\x20\x01(\tR\tsessionId\x12\x1d\n\naction_ids\x18\x06\x20\ + \x03(\tR\tactionIds\x12G\n\x08log_type\x18\x07\x20\x01(\x0e2,.bitdrift_p\ + ublic.protobuf.logging.v1.LogTypeR\x07logType\x12\x1d\n\nstream_ids\x18\ + \x08\x20\x03(\tR\tstreamIds\x12/\n\x13compressed_contents\x18\t\x20\x01(\ + \x0cR\x12compressedContents\x1aZ\n\x05Field\x12\x10\n\x03key\x18\x01\x20\ + \x01(\tR\x03key\x12?\n\x05value\x18\x02\x20\x01(\x0b2).bitdrift_public.p\ + rotobuf.logging.v1.DataR\x05value\x1a\xa1\x01\n\x12CompressedContents\ + \x12C\n\x07message\x18\x01\x20\x01(\x0b2).bitdrift_public.protobuf.loggi\ + ng.v1.DataR\x07message\x12F\n\x06fields\x18\x02\x20\x03(\x0b2..bitdrift_\ + public.protobuf.logging.v1.Log.FieldR\x06fields*x\n\x07LogType\x12\n\n\ + \x06NORMAL\x10\0\x12\n\n\x06REPLAY\x10\x01\x12\r\n\tLIFECYCLE\x10\x02\ + \x12\x0c\n\x08RESOURCE\x10\x03\x12\x10\n\x0cINTERNAL_SDK\x10\x04\x12\x08\ + \n\x04VIEW\x10\x05\x12\n\n\x06DEVICE\x10\x06\x12\x06\n\x02UX\x10\x07\x12\ + \x08\n\x04SPAN\x10\x08b\x06proto3\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -1316,9 +1728,11 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { file_descriptor.get(|| { let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { let mut deps = ::std::vec::Vec::with_capacity(0); - let mut messages = ::std::vec::Vec::with_capacity(5); + let mut messages = ::std::vec::Vec::with_capacity(7); messages.push(BinaryData::generated_message_descriptor_data()); messages.push(Data::generated_message_descriptor_data()); + messages.push(MapData::generated_message_descriptor_data()); + messages.push(ArrayData::generated_message_descriptor_data()); messages.push(Log::generated_message_descriptor_data()); messages.push(log::Field::generated_message_descriptor_data()); messages.push(log::CompressedContents::generated_message_descriptor_data()); diff --git a/bd-proto/src/protos/value_matcher/value_matcher.rs b/bd-proto/src/protos/value_matcher/value_matcher.rs index 0c57a8545..303680b03 100644 --- a/bd-proto/src/protos/value_matcher/value_matcher.rs +++ b/bd-proto/src/protos/value_matcher/value_matcher.rs @@ -1002,6 +1002,418 @@ impl ::protobuf::reflect::ProtobufValue for SemVerValueMatch { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } +// @@protoc_insertion_point(message:bitdrift_public.protobuf.value_matcher.v1.JsonPathValueMatch) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct JsonPathValueMatch { + // message fields + // @@protoc_insertion_point(field:bitdrift_public.protobuf.value_matcher.v1.JsonPathValueMatch.operator) + pub operator: ::protobuf::EnumOrUnknown, + // @@protoc_insertion_point(field:bitdrift_public.protobuf.value_matcher.v1.JsonPathValueMatch.key_or_index) + pub key_or_index: ::std::vec::Vec, + // @@protoc_insertion_point(field:bitdrift_public.protobuf.value_matcher.v1.JsonPathValueMatch.match_value) + pub match_value: ::std::string::String, + // special fields + // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.value_matcher.v1.JsonPathValueMatch.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a JsonPathValueMatch { + fn default() -> &'a JsonPathValueMatch { + ::default_instance() + } +} + +impl JsonPathValueMatch { + pub fn new() -> JsonPathValueMatch { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(3); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "operator", + |m: &JsonPathValueMatch| { &m.operator }, + |m: &mut JsonPathValueMatch| { &mut m.operator }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "key_or_index", + |m: &JsonPathValueMatch| { &m.key_or_index }, + |m: &mut JsonPathValueMatch| { &mut m.key_or_index }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "match_value", + |m: &JsonPathValueMatch| { &m.match_value }, + |m: &mut JsonPathValueMatch| { &mut m.match_value }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "JsonPathValueMatch", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for JsonPathValueMatch { + const NAME: &'static str = "JsonPathValueMatch"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 8 => { + self.operator = is.read_enum_or_unknown()?; + }, + 26 => { + self.key_or_index.push(is.read_message()?); + }, + 18 => { + self.match_value = is.read_string()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if self.operator != ::protobuf::EnumOrUnknown::new(Operator::OPERATOR_UNSPECIFIED) { + my_size += ::protobuf::rt::int32_size(1, self.operator.value()); + } + for value in &self.key_or_index { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + if !self.match_value.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.match_value); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if self.operator != ::protobuf::EnumOrUnknown::new(Operator::OPERATOR_UNSPECIFIED) { + os.write_enum(1, ::protobuf::EnumOrUnknown::value(&self.operator))?; + } + for v in &self.key_or_index { + ::protobuf::rt::write_message_field_with_cached_size(3, v, os)?; + }; + if !self.match_value.is_empty() { + os.write_string(2, &self.match_value)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> JsonPathValueMatch { + JsonPathValueMatch::new() + } + + fn clear(&mut self) { + self.operator = ::protobuf::EnumOrUnknown::new(Operator::OPERATOR_UNSPECIFIED); + self.key_or_index.clear(); + self.match_value.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static JsonPathValueMatch { + static instance: JsonPathValueMatch = JsonPathValueMatch { + operator: ::protobuf::EnumOrUnknown::from_i32(0), + key_or_index: ::std::vec::Vec::new(), + match_value: ::std::string::String::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for JsonPathValueMatch { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("JsonPathValueMatch").unwrap()).clone() + } +} + +impl ::std::fmt::Display for JsonPathValueMatch { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for JsonPathValueMatch { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +/// Nested message and enums of message `JsonPathValueMatch` +pub mod json_path_value_match { + // @@protoc_insertion_point(message:bitdrift_public.protobuf.value_matcher.v1.JsonPathValueMatch.KeyOrIndex) + #[derive(PartialEq,Clone,Default,Debug)] + pub struct KeyOrIndex { + // message oneof groups + pub key_or_index: ::std::option::Option, + // special fields + // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.value_matcher.v1.JsonPathValueMatch.KeyOrIndex.special_fields) + pub special_fields: ::protobuf::SpecialFields, + } + + impl<'a> ::std::default::Default for &'a KeyOrIndex { + fn default() -> &'a KeyOrIndex { + ::default_instance() + } + } + + impl KeyOrIndex { + pub fn new() -> KeyOrIndex { + ::std::default::Default::default() + } + + // string key = 1; + + pub fn key(&self) -> &str { + match self.key_or_index { + ::std::option::Option::Some(key_or_index::Key_or_index::Key(ref v)) => v, + _ => "", + } + } + + pub fn clear_key(&mut self) { + self.key_or_index = ::std::option::Option::None; + } + + pub fn has_key(&self) -> bool { + match self.key_or_index { + ::std::option::Option::Some(key_or_index::Key_or_index::Key(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_key(&mut self, v: ::std::string::String) { + self.key_or_index = ::std::option::Option::Some(key_or_index::Key_or_index::Key(v)) + } + + // Mutable pointer to the field. + pub fn mut_key(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(key_or_index::Key_or_index::Key(_)) = self.key_or_index { + } else { + self.key_or_index = ::std::option::Option::Some(key_or_index::Key_or_index::Key(::std::string::String::new())); + } + match self.key_or_index { + ::std::option::Option::Some(key_or_index::Key_or_index::Key(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_key(&mut self) -> ::std::string::String { + if self.has_key() { + match self.key_or_index.take() { + ::std::option::Option::Some(key_or_index::Key_or_index::Key(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } + + // int32 index = 2; + + pub fn index(&self) -> i32 { + match self.key_or_index { + ::std::option::Option::Some(key_or_index::Key_or_index::Index(v)) => v, + _ => 0, + } + } + + pub fn clear_index(&mut self) { + self.key_or_index = ::std::option::Option::None; + } + + pub fn has_index(&self) -> bool { + match self.key_or_index { + ::std::option::Option::Some(key_or_index::Key_or_index::Index(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_index(&mut self, v: i32) { + self.key_or_index = ::std::option::Option::Some(key_or_index::Key_or_index::Index(v)) + } + + pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(1); + fields.push(::protobuf::reflect::rt::v2::make_oneof_deref_has_get_set_simpler_accessor::<_, _>( + "key", + KeyOrIndex::has_key, + KeyOrIndex::key, + KeyOrIndex::set_key, + )); + fields.push(::protobuf::reflect::rt::v2::make_oneof_copy_has_get_set_simpler_accessors::<_, _>( + "index", + KeyOrIndex::has_index, + KeyOrIndex::index, + KeyOrIndex::set_index, + )); + oneofs.push(key_or_index::Key_or_index::generated_oneof_descriptor_data()); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "JsonPathValueMatch.KeyOrIndex", + fields, + oneofs, + ) + } + } + + impl ::protobuf::Message for KeyOrIndex { + const NAME: &'static str = "KeyOrIndex"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.key_or_index = ::std::option::Option::Some(key_or_index::Key_or_index::Key(is.read_string()?)); + }, + 16 => { + self.key_or_index = ::std::option::Option::Some(key_or_index::Key_or_index::Index(is.read_int32()?)); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let ::std::option::Option::Some(ref v) = self.key_or_index { + match v { + &key_or_index::Key_or_index::Key(ref v) => { + my_size += ::protobuf::rt::string_size(1, &v); + }, + &key_or_index::Key_or_index::Index(v) => { + my_size += ::protobuf::rt::int32_size(2, v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let ::std::option::Option::Some(ref v) = self.key_or_index { + match v { + &key_or_index::Key_or_index::Key(ref v) => { + os.write_string(1, v)?; + }, + &key_or_index::Key_or_index::Index(v) => { + os.write_int32(2, v)?; + }, + }; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> KeyOrIndex { + KeyOrIndex::new() + } + + fn clear(&mut self) { + self.key_or_index = ::std::option::Option::None; + self.key_or_index = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static KeyOrIndex { + static instance: KeyOrIndex = KeyOrIndex { + key_or_index: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } + } + + impl ::protobuf::MessageFull for KeyOrIndex { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| super::file_descriptor().message_by_package_relative_name("JsonPathValueMatch.KeyOrIndex").unwrap()).clone() + } + } + + impl ::std::fmt::Display for KeyOrIndex { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } + } + + impl ::protobuf::reflect::ProtobufValue for KeyOrIndex { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; + } + + /// Nested message and enums of message `KeyOrIndex` + pub mod key_or_index { + + #[derive(Clone,PartialEq,Debug)] + // @@protoc_insertion_point(oneof:bitdrift_public.protobuf.value_matcher.v1.JsonPathValueMatch.KeyOrIndex.key_or_index) + pub enum Key_or_index { + // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.value_matcher.v1.JsonPathValueMatch.KeyOrIndex.key) + Key(::std::string::String), + // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.value_matcher.v1.JsonPathValueMatch.KeyOrIndex.index) + Index(i32), + } + + impl ::protobuf::Oneof for Key_or_index { + } + + impl ::protobuf::OneofFull for Key_or_index { + fn descriptor() -> ::protobuf::reflect::OneofDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::OneofDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| ::descriptor().oneof_by_name("key_or_index").unwrap()).clone() + } + } + + impl Key_or_index { + pub(in super::super) fn generated_oneof_descriptor_data() -> ::protobuf::reflect::GeneratedOneofDescriptorData { + ::protobuf::reflect::GeneratedOneofDescriptorData::new::("key_or_index") + } + } + } +} + // @@protoc_insertion_point(message:bitdrift_public.protobuf.value_matcher.v1.IsSetMatch) #[derive(PartialEq,Clone,Default,Debug)] pub struct IsSetMatch { @@ -1217,13 +1629,21 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01\n\x10SemVerValueMatch\x12Y\n\x08operator\x18\x01\x20\x01(\x0e23.bit\ drift_public.protobuf.value_matcher.v1.OperatorR\x08operatorB\x08\xfaB\ \x05\x82\x01\x02\x10\x01\x12(\n\x0bmatch_value\x18\x02\x20\x01(\tR\nmatc\ - hValueB\x07\xfaB\x04r\x02\x10\x01\"\x0c\n\nIsSetMatch*\xea\x01\n\x08Oper\ - ator\x12\x18\n\x14OPERATOR_UNSPECIFIED\x10\0\x12\x16\n\x12OPERATOR_LESS_\ - THAN\x10\x01\x12\x1f\n\x1bOPERATOR_LESS_THAN_OR_EQUAL\x10\x02\x12\x13\n\ - \x0fOPERATOR_EQUALS\x10\x03\x12\x19\n\x15OPERATOR_GREATER_THAN\x10\x04\ - \x12\"\n\x1eOPERATOR_GREATER_THAN_OR_EQUAL\x10\x05\x12\x17\n\x13OPERATOR\ - _NOT_EQUALS\x10\x06\x12\x12\n\x0eOPERATOR_REGEX\x10\x07\"\x04\x08\x08\ - \x10\x08\"\x04\x08\t\x10\tb\x06proto3\ + hValueB\x07\xfaB\x04r\x02\x10\x01\"\xe7\x02\n\x12JsonPathValueMatch\x12Y\ + \n\x08operator\x18\x01\x20\x01(\x0e23.bitdrift_public.protobuf.value_mat\ + cher.v1.OperatorR\x08operatorB\x08\xfaB\x05\x82\x01\x02\x10\x01\x12t\n\ + \x0ckey_or_index\x18\x03\x20\x03(\x0b2H.bitdrift_public.protobuf.value_m\ + atcher.v1.JsonPathValueMatch.KeyOrIndexR\nkeyOrIndexB\x08\xfaB\x05\x92\ + \x01\x02\x08\x01\x12(\n\x0bmatch_value\x18\x02\x20\x01(\tR\nmatchValueB\ + \x07\xfaB\x04r\x02\x10\x01\x1aV\n\nKeyOrIndex\x12\x1b\n\x03key\x18\x01\ + \x20\x01(\tH\0R\x03keyB\x07\xfaB\x04r\x02\x10\x01\x12\x16\n\x05index\x18\ + \x02\x20\x01(\x05H\0R\x05indexB\x13\n\x0ckey_or_index\x12\x03\xf8B\x01\"\ + \x0c\n\nIsSetMatch*\xea\x01\n\x08Operator\x12\x18\n\x14OPERATOR_UNSPECIF\ + IED\x10\0\x12\x16\n\x12OPERATOR_LESS_THAN\x10\x01\x12\x1f\n\x1bOPERATOR_\ + LESS_THAN_OR_EQUAL\x10\x02\x12\x13\n\x0fOPERATOR_EQUALS\x10\x03\x12\x19\ + \n\x15OPERATOR_GREATER_THAN\x10\x04\x12\"\n\x1eOPERATOR_GREATER_THAN_OR_\ + EQUAL\x10\x05\x12\x17\n\x13OPERATOR_NOT_EQUALS\x10\x06\x12\x12\n\x0eOPER\ + ATOR_REGEX\x10\x07\"\x04\x08\x08\x10\x08\"\x04\x08\t\x10\tb\x06proto3\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -1242,12 +1662,14 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { let mut deps = ::std::vec::Vec::with_capacity(1); deps.push(super::validate::file_descriptor().clone()); - let mut messages = ::std::vec::Vec::with_capacity(5); + let mut messages = ::std::vec::Vec::with_capacity(7); messages.push(StringValueMatch::generated_message_descriptor_data()); messages.push(IntValueMatch::generated_message_descriptor_data()); messages.push(DoubleValueMatch::generated_message_descriptor_data()); messages.push(SemVerValueMatch::generated_message_descriptor_data()); + messages.push(JsonPathValueMatch::generated_message_descriptor_data()); messages.push(IsSetMatch::generated_message_descriptor_data()); + messages.push(json_path_value_match::KeyOrIndex::generated_message_descriptor_data()); let mut enums = ::std::vec::Vec::with_capacity(1); enums.push(Operator::generated_enum_descriptor_data()); ::protobuf::reflect::GeneratedFileDescriptor::new_generated( diff --git a/bd-test-helpers/src/test_api_server/log_upload.rs b/bd-test-helpers/src/test_api_server/log_upload.rs index 00a495bd0..1221efbbd 100644 --- a/bd-test-helpers/src/test_api_server/log_upload.rs +++ b/bd-test-helpers/src/test_api_server/log_upload.rs @@ -7,7 +7,6 @@ use bd_log_primitives::DataValue; use bd_proto::protos::client::api::LogUploadRequest; -use bd_proto::protos::logging::payload::data::Data_type; use bd_proto::protos::logging::payload::{Log, LogType}; use protobuf::Message; @@ -69,16 +68,13 @@ impl WrappedLog { #[must_use] pub fn typed_message(&self) -> DataValue { - match self.0.message.data_type.as_ref().unwrap() { - Data_type::StringData(string_data) => DataValue::String(string_data.clone()), - Data_type::BinaryData(binary_data) => DataValue::Bytes(binary_data.payload.clone().into()), - Data_type::BoolData(bool_data) => DataValue::Boolean(*bool_data), - Data_type::IntData(int_data) => DataValue::U64(*int_data), - Data_type::SintData(sint_data) => DataValue::I64(*sint_data), - Data_type::DoubleData(double_data) => { - DataValue::Double(ordered_float::NotNan::new(*double_data).unwrap()) - }, - } + self + .0 + .message + .clone() + .into_option() + .and_then(DataValue::from_proto) + .expect("missing message value") } #[must_use] @@ -88,17 +84,13 @@ impl WrappedLog { .fields .iter() .map(|field| { - if field.value.has_string_data() { - ( - field.key.clone(), - DataValue::String(field.value.string_data().to_string()), - ) - } else { - ( - field.key.clone(), - DataValue::Bytes(field.value.binary_data().payload.clone().into()), - ) - } + let value = field + .value + .clone() + .into_option() + .and_then(DataValue::from_proto) + .expect("missing field value"); + (field.key.clone(), value) }) .collect() }