Skip to main content

rocketmq_model/common/message/
message_ext_broker_inner.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::any::Any;
16use std::collections::HashMap;
17use std::fmt;
18use std::fmt::Debug;
19use std::fmt::Formatter;
20use std::net::SocketAddr;
21
22use bytes::Bytes;
23use cheetah_string::CheetahString;
24
25use crate::codec::message_properties_to_string;
26use crate::common::hasher::string_hasher::JavaStringHasher;
27use crate::common::message::message_ext::MessageExt;
28use crate::common::message::MessageTrait;
29use crate::common::message::MessageVersion;
30use crate::common::TopicFilterType;
31use crate::MessageUtils;
32
33#[derive(Default)]
34pub struct MessageExtBrokerInner {
35    pub message_ext_inner: MessageExt,
36    pub properties_string: CheetahString,
37    pub tags_code: i64,
38    pub encoded_buff: Option<bytes::BytesMut>,
39    pub encode_completed: bool,
40    pub version: MessageVersion,
41}
42
43impl MessageExtBrokerInner {
44    #[inline]
45    pub fn delete_property(&mut self, name: impl Into<CheetahString>) {
46        let name = name.into();
47        self.message_ext_inner.message.clear_property(name.as_str());
48        self.properties_string =
49            MessageUtils::delete_property_to_cheetah_string(&self.properties_string, name.as_str());
50    }
51
52    #[inline]
53    pub fn with_version(&mut self, version: MessageVersion) {
54        self.version = version;
55    }
56
57    #[inline]
58    pub fn version(&self) -> MessageVersion {
59        self.version
60    }
61
62    #[inline]
63    pub fn topic(&self) -> &CheetahString {
64        self.message_ext_inner.topic()
65    }
66
67    #[inline]
68    pub fn get_topic(&self) -> &CheetahString {
69        self.message_ext_inner.topic()
70    }
71
72    #[inline]
73    pub fn born_host(&self) -> SocketAddr {
74        self.message_ext_inner.born_host()
75    }
76
77    #[inline]
78    pub fn store_host(&self) -> SocketAddr {
79        self.message_ext_inner.store_host()
80    }
81
82    #[inline]
83    pub fn with_born_host_v6_flag(&mut self) {
84        self.message_ext_inner.with_born_host_v6_flag()
85    }
86
87    #[inline]
88    pub fn with_store_host_v6_flag(&mut self) {
89        self.message_ext_inner.with_store_host_v6_flag()
90    }
91
92    #[inline]
93    pub fn body(&self) -> Option<bytes::Bytes> {
94        self.message_ext_inner.body()
95    }
96
97    #[inline]
98    pub fn sys_flag(&self) -> i32 {
99        self.message_ext_inner.sys_flag()
100    }
101
102    #[inline]
103    pub fn body_crc(&self) -> u32 {
104        self.message_ext_inner.body_crc()
105    }
106
107    #[inline]
108    pub fn queue_id(&self) -> i32 {
109        self.message_ext_inner.queue_id()
110    }
111
112    #[inline]
113    pub fn flag(&self) -> i32 {
114        self.message_ext_inner.flag()
115    }
116
117    #[inline]
118    pub fn born_timestamp(&self) -> i64 {
119        self.message_ext_inner.born_timestamp()
120    }
121
122    #[inline]
123    pub fn store_timestamp(&self) -> i64 {
124        self.message_ext_inner.store_timestamp()
125    }
126
127    #[inline]
128    pub fn born_host_bytes(&self) -> bytes::Bytes {
129        self.message_ext_inner.born_host_bytes()
130    }
131
132    #[inline]
133    pub fn store_host_bytes(&self) -> bytes::Bytes {
134        self.message_ext_inner.born_store_bytes()
135    }
136
137    #[inline]
138    pub fn reconsume_times(&self) -> i32 {
139        self.message_ext_inner.reconsume_times()
140    }
141
142    #[inline]
143    pub fn prepared_transaction_offset(&self) -> i64 {
144        self.message_ext_inner.prepared_transaction_offset()
145    }
146
147    #[inline]
148    pub fn property(&self, name: &str) -> Option<CheetahString> {
149        self.message_ext_inner.properties().get(name).cloned()
150    }
151
152    #[inline]
153    pub fn properties_string(&self) -> &str {
154        self.properties_string.as_str()
155    }
156
157    #[inline]
158    pub fn queue_offset(&self) -> i64 {
159        self.message_ext_inner.queue_offset()
160    }
161
162    #[inline]
163    pub fn tags_string2tags_code(_filter: &TopicFilterType, tags: &str) -> i64 {
164        if tags.is_empty() {
165            return 0;
166        }
167        JavaStringHasher::hash_str(tags) as i64
168    }
169
170    #[inline]
171    pub fn tags_string_to_tags_code(tags: &str) -> i64 {
172        if tags.is_empty() {
173            return 0;
174        }
175        JavaStringHasher::hash_str(tags) as i64
176    }
177
178    #[inline]
179    pub fn get_tags(&self) -> Option<CheetahString> {
180        self.message_ext_inner.get_tags()
181    }
182
183    #[inline]
184    pub fn get_transaction_id(&self) -> Option<&CheetahString> {
185        self.message_ext_inner.get_transaction_id()
186    }
187
188    #[inline]
189    pub fn is_wait_store_msg_ok(&self) -> bool {
190        self.message_ext_inner.message.is_wait_store_msg_ok()
191    }
192
193    #[inline]
194    pub fn body_len(&self) -> usize {
195        self.message_ext_inner.message.body_slice().len()
196    }
197}
198
199impl fmt::Display for MessageExtBrokerInner {
200    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201        write!(
202            f,
203            "MessageExtBrokerInner{{topic='{}', queueId={}, queueOffset={}, flag={}, sysFlag={}, bodyLen={}, \
204             propertyCount={}, msgId='{}', encodeCompleted={}, version={}}}",
205            self.topic(),
206            self.queue_id(),
207            self.queue_offset(),
208            self.flag(),
209            self.sys_flag(),
210            self.body_len(),
211            self.message_ext_inner.message.properties().len(),
212            self.message_ext_inner.msg_id(),
213            self.encode_completed,
214            self.version,
215        )
216    }
217}
218
219impl Debug for MessageExtBrokerInner {
220    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
221        f.debug_struct("MessageExtBrokerInner")
222            .field("topic", self.topic())
223            .field("queue_id", &self.queue_id())
224            .field("queue_offset", &self.queue_offset())
225            .field("flag", &self.flag())
226            .field("sys_flag", &self.sys_flag())
227            .field("body_len", &self.body_len())
228            .field("property_count", &self.message_ext_inner.message.properties().len())
229            .field("msg_id", self.message_ext_inner.msg_id())
230            .field("encode_completed", &self.encode_completed)
231            .field("version", &self.version)
232            .finish()
233    }
234}
235
236impl MessageTrait for MessageExtBrokerInner {
237    #[inline]
238    fn put_property(&mut self, key: CheetahString, value: CheetahString) {
239        self.message_ext_inner.put_property(key, value);
240        self.properties_string = message_properties_to_string(self.message_ext_inner.get_properties());
241    }
242
243    #[inline]
244    fn clear_property(&mut self, name: &str) {
245        self.delete_property(name);
246    }
247
248    #[inline]
249    fn property(&self, name: &CheetahString) -> Option<CheetahString> {
250        self.message_ext_inner.property(name)
251    }
252
253    fn property_ref(&self, name: &CheetahString) -> Option<&CheetahString> {
254        self.message_ext_inner.property_ref(name)
255    }
256
257    #[inline]
258    fn topic(&self) -> &CheetahString {
259        self.message_ext_inner.topic()
260    }
261
262    #[inline]
263    fn set_topic(&mut self, topic: CheetahString) {
264        self.message_ext_inner.set_topic(topic);
265    }
266
267    #[inline]
268    fn get_flag(&self) -> i32 {
269        self.message_ext_inner.get_flag()
270    }
271
272    #[inline]
273    fn set_flag(&mut self, flag: i32) {
274        self.message_ext_inner.set_flag(flag);
275    }
276
277    #[inline]
278    fn get_body(&self) -> Option<&Bytes> {
279        self.message_ext_inner.get_body()
280    }
281
282    #[inline]
283    fn set_body(&mut self, body: Bytes) {
284        self.message_ext_inner.set_body(body);
285    }
286
287    #[inline]
288    fn get_properties(&self) -> &HashMap<CheetahString, CheetahString> {
289        self.message_ext_inner.get_properties()
290    }
291
292    #[inline]
293    fn set_properties(&mut self, properties: HashMap<CheetahString, CheetahString>) {
294        self.message_ext_inner.set_properties(properties.clone());
295        self.properties_string = message_properties_to_string(&properties);
296    }
297
298    #[inline]
299    fn transaction_id(&self) -> Option<&CheetahString> {
300        self.message_ext_inner.transaction_id()
301    }
302
303    #[inline]
304    fn set_transaction_id(&mut self, transaction_id: CheetahString) {
305        self.message_ext_inner.set_transaction_id(transaction_id);
306    }
307
308    #[inline]
309    fn get_compressed_body_mut(&mut self) -> Option<&mut Bytes> {
310        self.message_ext_inner.get_compressed_body_mut()
311    }
312
313    #[inline]
314    fn get_compressed_body(&self) -> Option<&Bytes> {
315        self.message_ext_inner.get_compressed_body()
316    }
317
318    #[inline]
319    fn set_compressed_body_mut(&mut self, compressed_body: Bytes) {
320        self.message_ext_inner.set_compressed_body_mut(compressed_body);
321    }
322
323    #[inline]
324    fn take_body(&mut self) -> Option<Bytes> {
325        self.message_ext_inner.take_body()
326    }
327
328    #[inline]
329    fn as_any(&self) -> &dyn Any {
330        self
331    }
332
333    #[inline]
334    fn as_any_mut(&mut self) -> &mut dyn Any {
335        self
336    }
337}
338
339// Conversion to new BrokerMessage type
340impl From<MessageExtBrokerInner> for crate::common::message::broker_message::BrokerMessage {
341    fn from(inner: MessageExtBrokerInner) -> Self {
342        use crate::common::message::broker_message::BrokerMessage;
343        use crate::common::message::message_envelope::MessageEnvelope;
344
345        let envelope = MessageEnvelope::from(inner.message_ext_inner);
346
347        BrokerMessage::new(envelope, inner.tags_code, inner.properties_string, inner.version)
348    }
349}
350
351// Conversion from new BrokerMessage type
352impl From<crate::common::message::broker_message::BrokerMessage> for MessageExtBrokerInner {
353    fn from(broker_msg: crate::common::message::broker_message::BrokerMessage) -> Self {
354        use crate::common::message::message_ext::MessageExt;
355
356        let message_ext_inner = MessageExt::from(broker_msg.envelope().clone());
357
358        Self {
359            message_ext_inner,
360            properties_string: CheetahString::from_slice(broker_msg.properties_string()),
361            tags_code: broker_msg.tags_code(),
362            encoded_buff: broker_msg.encoded_buff().cloned(),
363            encode_completed: broker_msg.is_encode_completed(),
364            version: broker_msg.version(),
365        }
366    }
367}
368
369#[cfg(test)]
370mod tests {
371    use std::collections::HashMap;
372
373    use super::MessageExtBrokerInner;
374    use crate::codec::string_to_message_properties;
375    use crate::common::message::MessageTrait;
376    use cheetah_string::CheetahString;
377
378    #[test]
379    fn message_ext_broker_inner_get_transaction_id_delegates_to_inner_message() {
380        let mut message = MessageExtBrokerInner::default();
381        MessageTrait::set_transaction_id(&mut message, CheetahString::from("tx-123"));
382
383        assert_eq!(message.get_transaction_id(), Some(&CheetahString::from("tx-123")));
384    }
385
386    #[test]
387    fn message_ext_broker_inner_put_property_updates_properties_string() {
388        let mut message = MessageExtBrokerInner::default();
389
390        message.put_property(CheetahString::from("k"), CheetahString::from("v"));
391
392        let decoded = string_to_message_properties(Some(&CheetahString::from(message.properties_string())));
393        assert_eq!(decoded.get("k").map(CheetahString::as_str), Some("v"));
394    }
395
396    #[test]
397    fn message_ext_broker_inner_set_properties_updates_properties_string() {
398        let mut message = MessageExtBrokerInner::default();
399        let properties = HashMap::from([(CheetahString::from("k"), CheetahString::from("v"))]);
400
401        message.set_properties(properties);
402
403        let decoded = string_to_message_properties(Some(&CheetahString::from(message.properties_string())));
404        assert_eq!(decoded.get("k").map(CheetahString::as_str), Some("v"));
405    }
406
407    #[test]
408    fn message_ext_broker_inner_body_len_returns_zero_for_empty_body() {
409        let message = MessageExtBrokerInner::default();
410
411        assert_eq!(message.body_len(), 0);
412    }
413}