rocketmq_common/common/message/
message_queue_assignment.rs1use std::collections::HashMap;
16use std::hash::Hash;
17use std::hash::Hasher;
18
19use cheetah_string::CheetahString;
20use serde::Deserialize;
21use serde::Serialize;
22
23use crate::common::message::message_enum::MessageRequestMode;
24use crate::common::message::message_queue::MessageQueue;
25
26#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
27#[serde(rename_all = "camelCase")]
28pub struct MessageQueueAssignment {
29 pub message_queue: Option<MessageQueue>,
30 pub mode: MessageRequestMode,
31 pub attachments: Option<HashMap<CheetahString, CheetahString>>,
32}
33
34impl Hash for MessageQueueAssignment {
35 fn hash<H: Hasher>(&self, state: &mut H) {
36 self.message_queue.hash(state);
37 self.mode.hash(state);
38 if let Some(ref attachments) = self.attachments {
39 let mut sorted_attachments: Vec<_> = attachments.iter().collect();
40 sorted_attachments.sort_by_key(|(k, _)| k.as_str());
41 for (key, value) in sorted_attachments {
42 key.hash(state);
43 value.hash(state);
44 }
45 }
46 }
47}
48
49impl Default for MessageQueueAssignment {
50 fn default() -> Self {
51 MessageQueueAssignment {
52 message_queue: None,
53 mode: MessageRequestMode::Pull,
54 attachments: None,
55 }
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn test_message_queue_assignment() {
65 let msg_queue_assignment = MessageQueueAssignment::default();
66
67 assert_eq!(msg_queue_assignment.message_queue, None);
68 assert_eq!(msg_queue_assignment.mode, MessageRequestMode::Pull);
69 assert_eq!(msg_queue_assignment.attachments, None);
70 }
71
72 #[test]
73 fn test_message_queue_assignment_hash() {
74 let mut first_msg_queue = MessageQueue::default();
75 first_msg_queue.set_broker_name(CheetahString::from("defaultBroker"));
76 first_msg_queue.set_queue_id(123);
77 first_msg_queue.set_topic(CheetahString::from("testTopic"));
78 let mut first_props = HashMap::new();
79 first_props.insert(CheetahString::from("rocketmqHome"), CheetahString::from("/new/path"));
80 first_props.insert(
81 CheetahString::from("kvConfigPath"),
82 CheetahString::from("/new/kvConfigPath"),
83 );
84 let first = MessageQueueAssignment {
85 message_queue: Some(first_msg_queue),
86 mode: MessageRequestMode::Pull,
87 attachments: Some(first_props),
88 };
89
90 let mut second_msg_queue = MessageQueue::default();
91 second_msg_queue.set_broker_name(CheetahString::from("defaultBroker"));
92 second_msg_queue.set_queue_id(123);
93 second_msg_queue.set_topic(CheetahString::from("testTopic"));
94 let mut second_props = HashMap::new();
95 second_props.insert(CheetahString::from("rocketmqHome"), CheetahString::from("/new/path"));
96 second_props.insert(
97 CheetahString::from("kvConfigPath"),
98 CheetahString::from("/new/kvConfigPath"),
99 );
100 let second = MessageQueueAssignment {
101 message_queue: Some(second_msg_queue),
102 mode: MessageRequestMode::Pull,
103 attachments: Some(second_props),
104 };
105
106 let mut first_hasher = std::collections::hash_map::DefaultHasher::new();
107 let mut second_hasher = std::collections::hash_map::DefaultHasher::new();
108
109 first.hash(&mut first_hasher);
110 let hash_first = first_hasher.finish();
111 second.hash(&mut second_hasher);
112 let hash_second = second_hasher.finish();
113
114 assert_eq!(hash_first, hash_second);
115 }
116
117 #[test]
118 fn test_message_queue_assignment_hash_differences() {
119 let mut first_props = HashMap::new();
120 first_props.insert(CheetahString::from("rocketmqHome"), CheetahString::from("/new/path"));
121 let mut second_props = HashMap::new();
122 second_props.insert(
123 CheetahString::from("rocketmqHome"),
124 CheetahString::from("/some/other/path"),
125 );
126
127 let first = MessageQueueAssignment {
128 message_queue: None,
129 mode: MessageRequestMode::Pull,
130 attachments: Some(first_props),
131 };
132
133 let second = MessageQueueAssignment {
134 message_queue: None,
135 mode: MessageRequestMode::Pull,
136 attachments: Some(second_props),
137 };
138
139 let mut first_hasher = std::collections::hash_map::DefaultHasher::new();
140 let mut second_hasher = std::collections::hash_map::DefaultHasher::new();
141
142 first.hash(&mut first_hasher);
143 let hash_first = first_hasher.finish();
144 second.hash(&mut second_hasher);
145 let hash_second = second_hasher.finish();
146
147 assert_ne!(hash_first, hash_second);
148
149 let mut first_msg_queue = MessageQueue::default();
150 first_msg_queue.set_broker_name(CheetahString::from("defaultBroker"));
151 let mut second_msg_queue = MessageQueue::default();
152 second_msg_queue.set_broker_name(CheetahString::from("nonDefaultBroker"));
153
154 let first = MessageQueueAssignment {
155 message_queue: Some(first_msg_queue),
156 mode: MessageRequestMode::Pull,
157 attachments: None,
158 };
159 let second = MessageQueueAssignment {
160 message_queue: Some(second_msg_queue),
161 mode: MessageRequestMode::Pull,
162 attachments: None,
163 };
164
165 let mut first_hasher = std::collections::hash_map::DefaultHasher::new();
166 let mut second_hasher = std::collections::hash_map::DefaultHasher::new();
167
168 first.hash(&mut first_hasher);
169 let hash_first = first_hasher.finish();
170 second.hash(&mut second_hasher);
171 let hash_second = second_hasher.finish();
172
173 assert_ne!(hash_first, hash_second);
174
175 let first = MessageQueueAssignment {
176 message_queue: None,
177 mode: MessageRequestMode::Pop,
178 attachments: None,
179 };
180 let second = MessageQueueAssignment {
181 message_queue: None,
182 mode: MessageRequestMode::Pull,
183 attachments: None,
184 };
185
186 let mut first_hasher = std::collections::hash_map::DefaultHasher::new();
187 let mut second_hasher = std::collections::hash_map::DefaultHasher::new();
188
189 first.hash(&mut first_hasher);
190 let hash_first = first_hasher.finish();
191 second.hash(&mut second_hasher);
192 let hash_second = second_hasher.finish();
193
194 assert_ne!(hash_first, hash_second);
195 }
196}