rocketmq_model/common/message/
message_ext.rs1use std::any::Any;
16use std::collections::HashMap;
17use std::fmt;
18use std::net::SocketAddr;
19
20use bytes::Buf;
21use bytes::BufMut;
22use bytes::Bytes;
23use cheetah_string::CheetahString;
24
25use crate::common::message::message_single::Message;
26use crate::common::message::MessageTrait;
27use crate::common::sys_flag::message_sys_flag::MessageSysFlag;
28
29#[derive(Clone)]
30pub struct MessageExt {
31 pub message: Message,
32 pub broker_name: CheetahString,
33 pub queue_id: i32,
34 pub store_size: i32,
35 pub queue_offset: i64,
36 pub sys_flag: i32,
37 pub born_timestamp: i64,
38 pub born_host: SocketAddr,
39 pub store_timestamp: i64,
40 pub store_host: SocketAddr,
41 pub msg_id: CheetahString,
42 pub commit_log_offset: i64,
43 pub body_crc: u32,
44 pub reconsume_times: i32,
45 pub prepared_transaction_offset: i64,
46}
47
48impl MessageExt {
49 pub fn socket_address_2_byte_buffer(ip: &SocketAddr) -> bytes::Bytes {
50 match ip {
51 SocketAddr::V4(value) => {
52 let mut byte_buffer = bytes::BytesMut::with_capacity(4 + 4);
53 byte_buffer.put_slice(&value.ip().octets());
54 byte_buffer.put_i32(value.port() as i32);
55 byte_buffer.copy_to_bytes(byte_buffer.len())
56 }
57 SocketAddr::V6(value) => {
58 let mut byte_buffer = bytes::BytesMut::with_capacity(16 + 4);
59 byte_buffer.put_slice(&value.ip().octets());
60 byte_buffer.put_i32(value.port() as i32);
61 byte_buffer.copy_to_bytes(byte_buffer.len())
62 }
63 }
64 }
65
66 #[inline]
67 pub fn born_host_bytes(&self) -> bytes::Bytes {
68 Self::socket_address_2_byte_buffer(&self.born_host)
69 }
70
71 #[inline]
72 pub fn born_store_bytes(&self) -> bytes::Bytes {
73 Self::socket_address_2_byte_buffer(&self.store_host)
74 }
75
76 #[inline]
77 pub fn topic(&self) -> &CheetahString {
78 self.message.topic()
79 }
80
81 #[inline]
82 pub fn born_host(&self) -> SocketAddr {
83 self.born_host
84 }
85
86 #[inline]
87 pub fn store_host(&self) -> SocketAddr {
88 self.store_host
89 }
90
91 #[inline]
92 pub fn with_born_host_v6_flag(&mut self) {
93 self.sys_flag |= MessageSysFlag::BORNHOST_V6_FLAG;
94 }
95
96 #[inline]
97 pub fn with_store_host_v6_flag(&mut self) {
98 self.sys_flag |= MessageSysFlag::STOREHOSTADDRESS_V6_FLAG;
99 }
100
101 #[inline]
102 pub fn body(&self) -> Option<bytes::Bytes> {
103 self.message.body()
104 }
105
106 #[inline]
107 pub fn sys_flag(&self) -> i32 {
108 self.sys_flag
109 }
110
111 #[inline]
112 pub fn body_crc(&self) -> u32 {
113 self.body_crc
114 }
115
116 #[inline]
117 pub fn queue_id(&self) -> i32 {
118 self.queue_id
119 }
120
121 #[inline]
122 pub fn flag(&self) -> i32 {
123 self.message.flag()
124 }
125
126 #[inline]
127 pub fn message_inner(&self) -> &Message {
128 &self.message
129 }
130
131 #[inline]
132 pub fn broker_name(&self) -> &str {
133 &self.broker_name
134 }
135
136 #[inline]
137 pub fn store_size(&self) -> i32 {
138 self.store_size
139 }
140
141 #[inline]
142 pub fn queue_offset(&self) -> i64 {
143 self.queue_offset
144 }
145
146 #[inline]
147 pub fn born_timestamp(&self) -> i64 {
148 self.born_timestamp
149 }
150
151 #[inline]
152 pub fn store_timestamp(&self) -> i64 {
153 self.store_timestamp
154 }
155
156 #[inline]
157 pub fn msg_id(&self) -> &CheetahString {
158 &self.msg_id
159 }
160
161 #[inline]
162 pub fn commit_log_offset(&self) -> i64 {
163 self.commit_log_offset
164 }
165
166 #[inline]
167 pub fn reconsume_times(&self) -> i32 {
168 self.reconsume_times
169 }
170
171 #[inline]
172 pub fn prepared_transaction_offset(&self) -> i64 {
173 self.prepared_transaction_offset
174 }
175 #[inline]
176 pub fn set_message_inner(&mut self, message_inner: Message) {
177 self.message = message_inner;
178 }
179 #[inline]
180 pub fn set_broker_name(&mut self, broker_name: CheetahString) {
181 self.broker_name = broker_name;
182 }
183 #[inline]
184 pub fn set_queue_id(&mut self, queue_id: i32) {
185 self.queue_id = queue_id;
186 }
187 #[inline]
188 pub fn set_store_size(&mut self, store_size: i32) {
189 self.store_size = store_size;
190 }
191 #[inline]
192 pub fn set_queue_offset(&mut self, queue_offset: i64) {
193 self.queue_offset = queue_offset;
194 }
195 #[inline]
196 pub fn set_sys_flag(&mut self, sys_flag: i32) {
197 self.sys_flag = sys_flag;
198 }
199 #[inline]
200 pub fn set_born_timestamp(&mut self, born_timestamp: i64) {
201 self.born_timestamp = born_timestamp;
202 }
203 #[inline]
204 pub fn set_born_host(&mut self, born_host: SocketAddr) {
205 self.born_host = born_host;
206 }
207 #[inline]
208 pub fn set_store_timestamp(&mut self, store_timestamp: i64) {
209 self.store_timestamp = store_timestamp;
210 }
211 #[inline]
212 pub fn set_store_host(&mut self, store_host: SocketAddr) {
213 self.store_host = store_host;
214 }
215 #[inline]
216 pub fn set_msg_id(&mut self, msg_id: CheetahString) {
217 self.msg_id = msg_id;
218 }
219 #[inline]
220 pub fn set_commit_log_offset(&mut self, commit_log_offset: i64) {
221 self.commit_log_offset = commit_log_offset;
222 }
223 #[inline]
224 pub fn set_body_crc(&mut self, body_crc: u32) {
225 self.body_crc = body_crc;
226 }
227 #[inline]
228 pub fn set_reconsume_times(&mut self, reconsume_times: i32) {
229 self.reconsume_times = reconsume_times;
230 }
231 #[inline]
232 pub fn set_prepared_transaction_offset(&mut self, prepared_transaction_offset: i64) {
233 self.prepared_transaction_offset = prepared_transaction_offset;
234 }
235 #[inline]
236 pub fn properties(&self) -> &HashMap<CheetahString, CheetahString> {
237 self.message.properties().as_map()
238 }
239 #[inline]
240 pub fn get_tags(&self) -> Option<CheetahString> {
241 self.message.get_tags()
242 }
243}
244
245impl Default for MessageExt {
246 fn default() -> Self {
247 Self {
248 message: Message::default(),
249 broker_name: CheetahString::default(),
250 queue_id: 0,
251 store_size: 0,
252 queue_offset: 0,
253 sys_flag: 0,
254 born_timestamp: 0,
255 born_host: SocketAddr::from(([127, 0, 0, 1], 10911)),
256 store_timestamp: 0,
257 store_host: SocketAddr::from(([127, 0, 0, 1], 10911)),
258 msg_id: CheetahString::default(),
259 commit_log_offset: 0,
260 body_crc: 0,
261 reconsume_times: 0,
262 prepared_transaction_offset: 0,
263 }
264 }
265}
266
267impl fmt::Display for MessageExt {
268 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
269 write!(
270 f,
271 "MessageExt{{topic='{}', queueId={}, queueOffset={}, flag={}, sysFlag={}, bodyLen={}, propertyCount={}, \
272 msgId='{}', reconsumeTimes={}}}",
273 self.topic(),
274 self.queue_id,
275 self.queue_offset,
276 self.flag(),
277 self.sys_flag,
278 self.message.body_slice().len(),
279 self.message.properties().len(),
280 self.msg_id,
281 self.reconsume_times
282 )
283 }
284}
285
286impl fmt::Debug for MessageExt {
287 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
288 f.debug_struct("MessageExt")
289 .field("topic", self.topic())
290 .field("queue_id", &self.queue_id)
291 .field("queue_offset", &self.queue_offset)
292 .field("flag", &self.flag())
293 .field("sys_flag", &self.sys_flag)
294 .field("body_len", &self.message.body_slice().len())
295 .field("property_count", &self.message.properties().len())
296 .field("msg_id", &self.msg_id)
297 .field("reconsume_times", &self.reconsume_times)
298 .finish()
299 }
300}
301impl MessageTrait for MessageExt {
302 fn put_property(&mut self, key: CheetahString, value: CheetahString) {
303 self.message.put_property(key, value);
304 }
305
306 fn clear_property(&mut self, name: &str) {
307 self.message.clear_property(name);
308 }
309
310 fn property(&self, name: &CheetahString) -> Option<CheetahString> {
311 self.message.get_property(name)
312 }
313
314 fn property_ref(&self, name: &CheetahString) -> Option<&CheetahString> {
315 self.message.property_ref(name)
316 }
317
318 fn topic(&self) -> &CheetahString {
319 self.message.topic()
320 }
321
322 fn set_topic(&mut self, topic: CheetahString) {
323 self.message.set_topic(topic);
324 }
325
326 fn get_flag(&self) -> i32 {
327 self.message.get_flag()
328 }
329
330 fn set_flag(&mut self, flag: i32) {
331 self.message.set_flag(flag);
332 }
333
334 fn get_body(&self) -> Option<&Bytes> {
335 self.message.get_body()
336 }
337
338 fn set_body(&mut self, body: Bytes) {
339 self.message.set_body(Some(body));
340 }
341
342 fn get_properties(&self) -> &HashMap<CheetahString, CheetahString> {
343 self.message.get_properties()
344 }
345
346 fn set_properties(&mut self, properties: HashMap<CheetahString, CheetahString>) {
347 self.message.set_properties(properties);
348 }
349
350 #[inline]
351 fn transaction_id(&self) -> Option<&CheetahString> {
352 MessageTrait::transaction_id(&self.message)
353 }
354
355 fn set_transaction_id(&mut self, transaction_id: CheetahString) {
356 self.message.set_transaction_id(transaction_id);
357 }
358
359 fn get_compressed_body_mut(&mut self) -> Option<&mut Bytes> {
360 self.message.get_compressed_body_mut()
361 }
362
363 fn get_compressed_body(&self) -> Option<&Bytes> {
364 self.message.get_compressed_body()
365 }
366
367 fn set_compressed_body_mut(&mut self, compressed_body: Bytes) {
368 self.message.set_compressed_body_mut(compressed_body);
369 }
370 #[inline]
371 fn take_body(&mut self) -> Option<Bytes> {
372 self.message.take_body()
373 }
374
375 fn as_any(&self) -> &dyn Any {
376 self
377 }
378
379 fn as_any_mut(&mut self) -> &mut dyn Any {
380 self
381 }
382}
383
384impl std::ops::Deref for MessageExt {
386 type Target = Message;
387
388 fn deref(&self) -> &Self::Target {
389 &self.message
390 }
391}
392
393impl std::ops::DerefMut for MessageExt {
394 fn deref_mut(&mut self) -> &mut Self::Target {
395 &mut self.message
396 }
397}
398
399impl From<MessageExt> for crate::common::message::message_envelope::MessageEnvelope {
401 fn from(ext: MessageExt) -> Self {
402 use crate::common::message::message_envelope::MessageEnvelope;
403 use crate::common::message::routing_context::RoutingContext;
404 use crate::common::message::storage_metadata::StorageMetadata;
405
406 let routing = RoutingContext::new(ext.born_host, ext.born_timestamp, ext.sys_flag);
407
408 let storage = StorageMetadata::new(
409 ext.broker_name,
410 ext.queue_id,
411 ext.queue_offset,
412 ext.commit_log_offset,
413 ext.store_timestamp,
414 ext.store_host,
415 ext.store_size,
416 );
417
418 MessageEnvelope::new(
419 ext.message,
420 routing,
421 storage,
422 ext.msg_id,
423 ext.body_crc,
424 ext.reconsume_times,
425 ext.prepared_transaction_offset,
426 )
427 }
428}
429
430impl From<crate::common::message::message_envelope::MessageEnvelope> for MessageExt {
432 fn from(envelope: crate::common::message::message_envelope::MessageEnvelope) -> Self {
433 Self {
434 message: envelope.message().clone(),
435 broker_name: CheetahString::from_slice(envelope.broker_name()),
436 queue_id: envelope.queue_id(),
437 store_size: envelope.store_size(),
438 queue_offset: envelope.queue_offset(),
439 sys_flag: envelope.sys_flag(),
440 born_timestamp: envelope.born_timestamp(),
441 born_host: envelope.born_host(),
442 store_timestamp: envelope.store_timestamp(),
443 store_host: envelope.store_host(),
444 msg_id: envelope.msg_id().clone(),
445 commit_log_offset: envelope.commit_log_offset(),
446 body_crc: envelope.body_crc(),
447 reconsume_times: envelope.reconsume_times(),
448 prepared_transaction_offset: envelope.prepared_transaction_offset(),
449 }
450 }
451}
452
453#[cfg(test)]
454mod tests {
455 use cheetah_string::CheetahString;
456
457 use super::*;
458 use crate::common::message::MessageTrait;
459
460 #[test]
461 fn message_ext_message_trait_transaction_id_returns_cheetah_string_ref() {
462 let mut message_ext = MessageExt::default();
463 message_ext.set_transaction_id(CheetahString::from_static_str("tx-123"));
464
465 let transaction_id = <MessageExt as MessageTrait>::transaction_id(&message_ext);
466
467 assert_eq!(transaction_id, Some(&CheetahString::from_static_str("tx-123")));
468 }
469
470 #[test]
471 fn message_ext_display_contains_only_safe_metadata() {
472 let mut message_ext = MessageExt::default();
473 message_ext.set_broker_name(CheetahString::from_static_str("BrokerA"));
474 message_ext.set_queue_id(3);
475 message_ext.set_store_size(128);
476 message_ext.set_queue_offset(42);
477 message_ext.set_sys_flag(1);
478 message_ext.set_born_timestamp(10);
479 message_ext.set_store_timestamp(20);
480 message_ext.set_msg_id(CheetahString::from_static_str("MSGID"));
481 message_ext.set_commit_log_offset(1000);
482 message_ext.set_body_crc(99);
483 message_ext.set_reconsume_times(2);
484 message_ext.set_prepared_transaction_offset(7);
485 message_ext.set_topic(CheetahString::from_static_str("TopicA"));
486 message_ext.set_body(Bytes::from_static(&[1, 255]));
487
488 assert_eq!(
489 message_ext.to_string(),
490 "MessageExt{topic='TopicA', queueId=3, queueOffset=42, flag=0, sysFlag=1, bodyLen=2, propertyCount=0, \
491 msgId='MSGID', reconsumeTimes=2}"
492 );
493 }
494}