Skip to main content

rocketmq_protocol/protocol/body/topic_info_wrapper/
topic_config_wrapper.rs

1// Copyright 2023 The RocketMQ Rust Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::collections::HashMap;
16
17use cheetah_string::CheetahString;
18use rocketmq_model::topic::TopicConfig;
19use serde::Deserialize;
20use serde::Serialize;
21
22use crate::protocol::static_topic::topic_queue_mapping_detail::TopicQueueMappingDetail;
23use crate::protocol::static_topic::topic_queue_mapping_info::TopicQueueMappingInfo;
24use crate::protocol::DataVersion;
25
26#[derive(Debug, Clone, Serialize, Deserialize, Default)]
27pub struct TopicConfigAndMappingSerializeWrapper {
28    #[serde(rename = "topicQueueMappingInfoMap")]
29    pub topic_queue_mapping_info_map: HashMap<CheetahString /* topic */, TopicQueueMappingInfo>,
30
31    #[serde(rename = "topicQueueMappingDetailMap")]
32    pub topic_queue_mapping_detail_map: HashMap<CheetahString /* topic */, TopicQueueMappingDetail>,
33
34    #[serde(rename = "mappingDataVersion")]
35    pub mapping_data_version: DataVersion,
36
37    #[serde(flatten)]
38    pub topic_config_serialize_wrapper: TopicConfigSerializeWrapper,
39}
40
41impl TopicConfigAndMappingSerializeWrapper {
42    pub fn topic_queue_mapping_info_map(&self) -> &HashMap<CheetahString, TopicQueueMappingInfo> {
43        &self.topic_queue_mapping_info_map
44    }
45
46    pub fn topic_queue_mapping_detail_map(&self) -> &HashMap<CheetahString /* topic */, TopicQueueMappingDetail> {
47        &self.topic_queue_mapping_detail_map
48    }
49
50    pub fn mapping_data_version(&self) -> &DataVersion {
51        &self.mapping_data_version
52    }
53    pub fn topic_config_serialize_wrapper(&self) -> &TopicConfigSerializeWrapper {
54        &self.topic_config_serialize_wrapper
55    }
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
59pub struct TopicConfigSerializeWrapper {
60    #[serde(rename = "topicConfigTable")]
61    pub topic_config_table: HashMap<CheetahString, TopicConfig>,
62    #[serde(rename = "dataVersion")]
63    pub data_version: DataVersion,
64}
65
66impl TopicConfigSerializeWrapper {
67    pub fn topic_config_table(&self) -> &HashMap<CheetahString, TopicConfig> {
68        &self.topic_config_table
69    }
70
71    pub fn data_version(&self) -> &DataVersion {
72        &self.data_version
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn topic_config_and_mapping_serialize_wrapper_getters() {
82        let mut wrapper = TopicConfigAndMappingSerializeWrapper::default();
83        let _topic_config = TopicConfig::default();
84        let topic_queue_mapping_info = TopicQueueMappingInfo::default();
85        let topic_queue_mapping_detail = TopicQueueMappingDetail::default();
86        let data_version = DataVersion::default();
87
88        let topic_config_serialize_wrapper = TopicConfigSerializeWrapper::default();
89        wrapper.mapping_data_version = data_version.clone();
90        wrapper.topic_config_serialize_wrapper = topic_config_serialize_wrapper.clone();
91        wrapper
92            .topic_queue_mapping_info_map
93            .insert("test".into(), topic_queue_mapping_info.clone());
94        wrapper
95            .topic_queue_mapping_detail_map
96            .insert("test".into(), topic_queue_mapping_detail.clone());
97
98        assert_eq!(wrapper.mapping_data_version(), &data_version);
99        assert_eq!(wrapper.topic_queue_mapping_info_map().len(), 1);
100        assert_eq!(wrapper.topic_queue_mapping_detail_map().len(), 1);
101        assert_eq!(
102            wrapper.topic_config_serialize_wrapper(),
103            &topic_config_serialize_wrapper
104        );
105    }
106
107    #[test]
108    fn topic_config_serialize_wrapper_methods() {
109        let mut wrapper = TopicConfigSerializeWrapper::default();
110        let topic_config = TopicConfig::default();
111        wrapper
112            .topic_config_table
113            .insert("test_topic".into(), topic_config.clone());
114        let data_version = DataVersion::default();
115        wrapper.data_version = data_version.clone();
116
117        assert_eq!(
118            wrapper
119                .topic_config_table()
120                .get(&CheetahString::from_static_str("test_topic")),
121            Some(&topic_config)
122        );
123        assert_eq!(wrapper.data_version(), &data_version);
124    }
125
126    fn create_topic_config(name: &str) -> (CheetahString, TopicConfig) {
127        (CheetahString::from(name), TopicConfig::default())
128    }
129
130    #[test]
131    fn test_json_serialization_field_names() {
132        let mut wrapper = TopicConfigSerializeWrapper::default();
133        let (k, v) = create_topic_config("serde_topic");
134
135        wrapper.topic_config_table.insert(k, v);
136
137        let json = serde_json::to_string(&wrapper).unwrap();
138
139        assert!(json.contains("topicConfigTable"));
140        assert!(json.contains("dataVersion"));
141    }
142
143    #[test]
144    fn test_json_deserialization_field_names() {
145        let json = r#"
146    {
147        "topicConfigTable": {},
148        "dataVersion": {
149            "stateVersion": 0,
150            "timestamp": 0,
151            "counter": 0
152        }
153    }
154    "#;
155
156        let wrapper: TopicConfigSerializeWrapper = serde_json::from_str(json).unwrap();
157
158        assert!(wrapper.topic_config_table.is_empty());
159    }
160
161    #[test]
162    fn test_serde_roundtrip() {
163        let mut wrapper = TopicConfigSerializeWrapper::default();
164
165        let (k1, v1) = create_topic_config("topic_round_1");
166        let (k2, v2) = create_topic_config("topic_round_2");
167
168        wrapper.topic_config_table.insert(k1, v1);
169        wrapper.topic_config_table.insert(k2, v2);
170
171        let json = serde_json::to_string(&wrapper).unwrap();
172        let decoded: TopicConfigSerializeWrapper = serde_json::from_str(&json).unwrap();
173
174        assert_eq!(wrapper, decoded);
175    }
176}