Skip to main content

rocketmq_protocol/protocol/header/message_operation_header/
send_message_response_header.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 cheetah_string::CheetahString;
16use rocketmq_macros::RequestHeaderCodec;
17use serde::Deserialize;
18use serde::Serialize;
19
20use crate::protocol::command_custom_header::CommandCustomHeader;
21use crate::protocol::command_custom_header::FromMap;
22use crate::protocol::command_custom_header::HeaderMap;
23#[allow(
24    deprecated,
25    reason = "imports the legacy trait only to provide its compatibility adapter"
26)]
27use crate::protocol::FastCodesHeader;
28
29#[derive(Debug, Serialize, Deserialize, Default, RequestHeaderCodec)]
30#[header(
31    type_id = "rocketmq_protocol::protocol::header::message_operation_header::send_message_response_header::SendMessageResponseHeader",
32    java_class = "org.apache.rocketmq.remoting.protocol.header.SendMessageResponseHeader",
33    fast
34)]
35#[serde(rename_all = "camelCase")]
36pub struct SendMessageResponseHeader {
37    #[header(required)]
38    msg_id: CheetahString,
39    #[header(required)]
40    queue_id: i32,
41    #[header(required)]
42    queue_offset: i64,
43    transaction_id: Option<CheetahString>,
44    batch_uniq_id: Option<CheetahString>,
45    #[serde(skip_serializing_if = "Option::is_none")]
46    recall_handle: Option<CheetahString>,
47}
48
49impl SendMessageResponseHeader {
50    pub fn new(
51        msg_id: CheetahString,
52        queue_id: i32,
53        queue_offset: i64,
54        transaction_id: Option<CheetahString>,
55        batch_uniq_id: Option<CheetahString>,
56        recall_handle: Option<CheetahString>,
57    ) -> Self {
58        SendMessageResponseHeader {
59            msg_id,
60            queue_id,
61            queue_offset,
62            transaction_id,
63            batch_uniq_id,
64            recall_handle,
65        }
66    }
67
68    pub fn msg_id(&self) -> &CheetahString {
69        &self.msg_id
70    }
71
72    pub fn queue_id(&self) -> i32 {
73        self.queue_id
74    }
75
76    pub fn queue_offset(&self) -> i64 {
77        self.queue_offset
78    }
79
80    pub fn transaction_id(&self) -> Option<&str> {
81        self.transaction_id.as_deref()
82    }
83
84    pub fn batch_uniq_id(&self) -> Option<&str> {
85        self.batch_uniq_id.as_deref()
86    }
87
88    pub fn recall_handle(&self) -> Option<&str> {
89        self.recall_handle.as_deref()
90    }
91
92    pub fn set_msg_id(&mut self, msg_id: impl Into<CheetahString>) {
93        self.msg_id = msg_id.into();
94    }
95
96    pub fn set_queue_id(&mut self, queue_id: i32) {
97        self.queue_id = queue_id;
98    }
99
100    pub fn set_queue_offset(&mut self, queue_offset: i64) {
101        self.queue_offset = queue_offset;
102    }
103
104    pub fn set_transaction_id(&mut self, transaction_id: Option<CheetahString>) {
105        self.transaction_id = transaction_id;
106    }
107
108    pub fn set_batch_uniq_id(&mut self, batch_uniq_id: Option<CheetahString>) {
109        self.batch_uniq_id = batch_uniq_id;
110    }
111
112    pub fn set_recall_handle(&mut self, recall_handle: Option<CheetahString>) {
113        self.recall_handle = recall_handle;
114    }
115}
116
117#[allow(deprecated, reason = "source-compatible adapter for the legacy public trait")]
118impl FastCodesHeader for SendMessageResponseHeader {
119    fn encode_fast(&mut self, out: &mut bytes::BytesMut) {
120        let _ = CommandCustomHeader::encode_direct_binary(self, out);
121    }
122
123    fn decode_fast(&mut self, fields: &HeaderMap) {
124        if let Ok(decoded) = <Self as FromMap>::from(fields) {
125            *self = decoded;
126        }
127    }
128}
129
130#[cfg(test)]
131mod tests {
132    use super::*;
133
134    #[test]
135    fn send_message_response_header_serialization_and_deserialization() {
136        let mut header = SendMessageResponseHeader::default();
137        header.set_msg_id("msg123");
138        header.set_queue_id(1);
139        header.set_queue_offset(100);
140        header.set_transaction_id(Some(CheetahString::from("tx456")));
141        header.set_batch_uniq_id(Some(CheetahString::from("batch789")));
142        header.set_recall_handle(Some(CheetahString::from("recall-handle")));
143
144        let json = serde_json::to_string(&header).unwrap();
145        assert_eq!(
146            json,
147            r#"{"msgId":"msg123","queueId":1,"queueOffset":100,"transactionId":"tx456","batchUniqId":"batch789","recallHandle":"recall-handle"}"#
148        );
149
150        let header: SendMessageResponseHeader = serde_json::from_str(&json).unwrap();
151        assert_eq!(header.msg_id(), "msg123");
152        assert_eq!(header.queue_id(), 1);
153        assert_eq!(header.queue_offset(), 100);
154        assert_eq!(header.transaction_id(), Some("tx456"));
155        assert_eq!(header.batch_uniq_id(), Some("batch789"));
156        assert_eq!(header.recall_handle(), Some("recall-handle"));
157    }
158
159    #[test]
160    #[allow(
161        deprecated,
162        reason = "verifies the source-compatible legacy adapter delegates to the generated codec"
163    )]
164    fn send_message_response_header_encode_decode_fast() {
165        let mut header = SendMessageResponseHeader::new(
166            CheetahString::from("msg123"),
167            1,
168            100,
169            Some(CheetahString::from("tx456")),
170            Some(CheetahString::from("batch789")),
171            Some(CheetahString::from("recall-handle")),
172        );
173        assert_eq!(header.msg_id(), "msg123");
174        assert_eq!(header.queue_id(), 1);
175        assert_eq!(header.queue_offset(), 100);
176        assert_eq!(header.transaction_id(), Some("tx456"));
177        assert_eq!(header.batch_uniq_id(), Some("batch789"));
178        assert_eq!(header.recall_handle(), Some("recall-handle"));
179
180        let mut out = bytes::BytesMut::new();
181        FastCodesHeader::encode_fast(&mut header, &mut out);
182        assert!(!out.is_empty());
183
184        let mut fields = std::collections::HashMap::new();
185        fields.insert(CheetahString::from("msgId"), CheetahString::from("msg123"));
186        fields.insert(CheetahString::from("queueId"), CheetahString::from("1"));
187        fields.insert(CheetahString::from("queueOffset"), CheetahString::from("100"));
188        fields.insert(CheetahString::from("transactionId"), CheetahString::from("tx456"));
189        fields.insert(CheetahString::from("batchUniqId"), CheetahString::from("batch789"));
190        fields.insert(
191            CheetahString::from("recallHandle"),
192            CheetahString::from("recall-handle"),
193        );
194
195        let mut header = SendMessageResponseHeader::default();
196        FastCodesHeader::decode_fast(&mut header, &fields);
197
198        assert_eq!(header.msg_id(), "msg123");
199        assert_eq!(header.queue_id(), 1);
200        assert_eq!(header.queue_offset(), 100);
201        assert_eq!(header.transaction_id(), Some("tx456"));
202        assert_eq!(header.batch_uniq_id(), Some("batch789"));
203        assert_eq!(header.recall_handle(), Some("recall-handle"));
204    }
205
206    #[test]
207    #[allow(
208        deprecated,
209        reason = "verifies the source-compatible legacy adapter delegates to the generated codec"
210    )]
211    fn send_message_response_header_fast_encode_writes_signed_numeric_fields() {
212        let mut header = SendMessageResponseHeader::new(CheetahString::from("msg123"), -1, -42, None, None, None);
213        let mut out = bytes::BytesMut::new();
214
215        FastCodesHeader::encode_fast(&mut header, &mut out);
216
217        let encoded = String::from_utf8(out.to_vec()).unwrap();
218        assert!(encoded.contains("queueId"));
219        assert!(encoded.contains("-1"));
220        assert!(encoded.contains("queueOffset"));
221        assert!(encoded.contains("-42"));
222    }
223}