rocketmq_protocol/protocol/route/
route_data_view.rs1use std::cmp::Ordering;
16use std::collections::HashMap;
17
18use crate::common::wire_constants::MASTER_ID;
19use cheetah_string::CheetahString;
20use serde::Deserialize;
21use serde::Serialize;
22
23#[derive(Debug, Clone, Serialize, Deserialize, Default)]
24pub struct BrokerData {
25 cluster: CheetahString,
26 #[serde(rename = "brokerName")]
27 broker_name: CheetahString,
28 #[serde(rename = "brokerAddrs")]
29 broker_addrs: HashMap<u64 , CheetahString >,
30 #[serde(rename = "zoneName")]
31 zone_name: Option<CheetahString>,
32 #[serde(rename = "enableActingMaster")]
33 enable_acting_master: bool,
34}
35
36impl PartialEq for BrokerData {
37 fn eq(&self, other: &Self) -> bool {
38 self.broker_name == other.broker_name && self.broker_addrs == other.broker_addrs
39 }
40}
41
42impl Eq for BrokerData {}
43
44impl PartialOrd for BrokerData {
45 #[inline]
46 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
47 Some(self.cmp(other))
48 }
49}
50
51impl Ord for BrokerData {
52 #[inline]
53 fn cmp(&self, other: &Self) -> Ordering {
54 self.broker_name.cmp(&other.broker_name)
55 }
56}
57
58impl BrokerData {
59 pub fn new(
60 cluster: CheetahString,
61 broker_name: CheetahString,
62 broker_addrs: HashMap<u64, CheetahString>,
63 zone_name: Option<CheetahString>,
64 ) -> BrokerData {
65 BrokerData {
66 cluster,
67 broker_name,
68 broker_addrs,
69 zone_name,
70 enable_acting_master: false,
71 }
72 }
73
74 #[inline]
75 pub fn set_cluster(&mut self, cluster: CheetahString) {
76 self.cluster = cluster;
77 }
78
79 #[inline]
80 pub fn set_broker_name(&mut self, broker_name: CheetahString) {
81 self.broker_name = broker_name;
82 }
83
84 #[inline]
85 pub fn set_broker_addrs(&mut self, broker_addrs: HashMap<u64, CheetahString>) {
86 self.broker_addrs = broker_addrs;
87 }
88
89 #[inline]
90 pub fn set_zone_name(&mut self, zone_name: Option<CheetahString>) {
91 self.zone_name = zone_name;
92 }
93
94 #[inline]
95 pub fn set_enable_acting_master(&mut self, enable_acting_master: bool) {
96 self.enable_acting_master = enable_acting_master;
97 }
98
99 #[inline]
100 pub fn cluster(&self) -> &str {
101 &self.cluster
102 }
103
104 #[inline]
105 pub fn broker_name(&self) -> &CheetahString {
106 &self.broker_name
107 }
108
109 #[inline]
110 pub fn broker_addrs(&self) -> &HashMap<u64, CheetahString> {
111 &self.broker_addrs
112 }
113
114 #[inline]
115 pub fn broker_addrs_mut(&mut self) -> &mut HashMap<u64, CheetahString> {
116 &mut self.broker_addrs
117 }
118
119 #[inline]
120 pub fn remove_broker_by_addr(&mut self, broker_id: u64, broker_addr: &CheetahString) {
121 self.broker_addrs
122 .retain(|key, value| value != broker_addr || *key == broker_id);
123 }
124
125 #[inline]
126 pub fn zone_name(&self) -> Option<&CheetahString> {
127 self.zone_name.as_ref()
128 }
129
130 #[inline]
131 pub fn enable_acting_master(&self) -> bool {
132 self.enable_acting_master
133 }
134
135 pub fn select_broker_addr_with_index(&self, index: usize) -> Option<CheetahString> {
136 if let Some(master_address) = self.broker_addrs.get(&MASTER_ID) {
137 return Some(master_address.clone());
138 }
139 let mut slaves = self.broker_addrs.iter().collect::<Vec<_>>();
140 slaves.sort_unstable_by_key(|(id, _)| **id);
141 if slaves.is_empty() {
142 return None;
143 }
144 slaves.get(index % slaves.len()).map(|(_, value)| (*value).clone())
145 }
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Default)]
149pub struct QueueData {
150 #[serde(rename = "brokerName")]
151 pub broker_name: CheetahString,
152 #[serde(rename = "readQueueNums")]
153 pub read_queue_nums: u32,
154 #[serde(rename = "writeQueueNums")]
155 pub write_queue_nums: u32,
156 pub perm: u32,
157 #[serde(rename = "topicSysFlag")]
158 pub topic_sys_flag: u32,
159}
160
161impl QueueData {
162 pub fn new(
163 broker_name: CheetahString,
164 read_queue_nums: u32,
165 write_queue_nums: u32,
166 perm: u32,
167 topic_sys_flag: u32,
168 ) -> Self {
169 Self {
170 broker_name,
171 read_queue_nums,
172 write_queue_nums,
173 perm,
174 topic_sys_flag,
175 }
176 }
177
178 #[inline]
179 pub fn broker_name(&self) -> &CheetahString {
180 &self.broker_name
181 }
182
183 #[inline]
184 pub fn read_queue_nums(&self) -> u32 {
185 self.read_queue_nums
186 }
187
188 #[inline]
189 pub fn write_queue_nums(&self) -> u32 {
190 self.write_queue_nums
191 }
192
193 #[inline]
194 pub fn perm(&self) -> u32 {
195 self.perm
196 }
197
198 #[inline]
199 pub fn topic_sys_flag(&self) -> u32 {
200 self.topic_sys_flag
201 }
202}
203
204#[cfg(test)]
205mod tests {
206 use std::collections::HashMap;
207
208 use super::*;
209
210 #[test]
211 fn broker_data_methods_preserve_route_fields() {
212 let mut broker_data = BrokerData::new(
213 CheetahString::from("cluster1"),
214 CheetahString::from("broker1"),
215 HashMap::new(),
216 None,
217 );
218 assert_eq!(broker_data.cluster(), "cluster1");
219 assert_eq!(broker_data.broker_name(), "broker1");
220 assert!(broker_data.broker_addrs().is_empty());
221 assert_eq!(broker_data.zone_name(), None);
222 assert!(!broker_data.enable_acting_master());
223
224 broker_data.set_cluster(CheetahString::from("cluster2"));
225 broker_data.set_broker_name(CheetahString::from("broker2"));
226 broker_data.set_broker_addrs(HashMap::from([(1, CheetahString::from("127.0.0.1"))]));
227 broker_data
228 .broker_addrs_mut()
229 .insert(2, CheetahString::from("127.0.0.2"));
230 broker_data.set_zone_name(Some(CheetahString::from("zone1")));
231 broker_data.set_enable_acting_master(true);
232
233 assert_eq!(broker_data.cluster(), "cluster2");
234 assert_eq!(broker_data.broker_name(), "broker2");
235 assert_eq!(
236 broker_data.broker_addrs(),
237 &HashMap::from([
238 (1, CheetahString::from("127.0.0.1")),
239 (2, CheetahString::from("127.0.0.2")),
240 ])
241 );
242 assert_eq!(broker_data.zone_name(), Some(&CheetahString::from("zone1")));
243 assert!(broker_data.enable_acting_master());
244 }
245
246 #[test]
247 fn remove_broker_by_addr_keeps_the_current_id_only() {
248 let mut broker_data = BrokerData::new(
249 CheetahString::from("cluster1"),
250 CheetahString::from("broker1"),
251 HashMap::from([
252 (1, CheetahString::from("127.0.0.1")),
253 (2, CheetahString::from("127.0.0.1")),
254 (3, CheetahString::from("127.0.0.3")),
255 ]),
256 None,
257 );
258
259 broker_data.remove_broker_by_addr(1, &"127.0.0.1".into());
260 assert_eq!(
261 broker_data.broker_addrs(),
262 &HashMap::from([
263 (1, CheetahString::from("127.0.0.1")),
264 (3, CheetahString::from("127.0.0.3")),
265 ])
266 );
267 }
268
269 #[test]
270 fn select_broker_addr_prefers_master_and_indexes_slaves() {
271 let mut broker_data = BrokerData::new(
272 CheetahString::from("cluster1"),
273 CheetahString::from("broker1"),
274 HashMap::new(),
275 None,
276 );
277 assert_eq!(broker_data.select_broker_addr_with_index(0), None);
278
279 broker_data.set_broker_addrs(HashMap::from([
280 (4, CheetahString::from("127.0.0.4")),
281 (2, CheetahString::from("127.0.0.2")),
282 ]));
283 assert_eq!(
284 broker_data.select_broker_addr_with_index(0),
285 Some(CheetahString::from("127.0.0.2"))
286 );
287 assert_eq!(
288 broker_data.select_broker_addr_with_index(1),
289 Some(CheetahString::from("127.0.0.4"))
290 );
291 assert_eq!(
292 broker_data.select_broker_addr_with_index(2),
293 Some(CheetahString::from("127.0.0.2"))
294 );
295
296 broker_data
297 .broker_addrs_mut()
298 .insert(MASTER_ID, CheetahString::from("127.0.0.1"));
299 assert_eq!(
300 broker_data.select_broker_addr_with_index(1),
301 Some(CheetahString::from("127.0.0.1"))
302 );
303 }
304
305 #[test]
306 fn queue_data_methods_preserve_route_fields() {
307 let queue_data = QueueData::new(CheetahString::from("broker1"), 4, 4, 6, 0);
308
309 assert_eq!(queue_data.broker_name(), "broker1");
310 assert_eq!(queue_data.read_queue_nums(), 4);
311 assert_eq!(queue_data.write_queue_nums(), 4);
312 assert_eq!(queue_data.perm(), 6);
313 assert_eq!(queue_data.topic_sys_flag(), 0);
314 }
315}