Skip to main content

rocketmq_remoting/code/
request_code.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
15/// Macro to define RequestCode enum with automatic conversion implementations.
16/// This reduces code duplication and makes it easier to maintain.
17macro_rules! define_request_code {
18    (
19        $(#[$enum_meta:meta])*
20        pub enum $enum_name:ident {
21            $(
22                $(#[$variant_meta:meta])*
23                $variant:ident = $value:expr
24            ),* $(,)?
25        }
26    ) => {
27        $(#[$enum_meta])*
28        #[repr(i32)]
29        pub enum $enum_name {
30            $(
31                $(#[$variant_meta])*
32                $variant = $value,
33            )*
34        }
35
36        impl From<$enum_name> for i32 {
37            #[inline]
38            fn from(value: $enum_name) -> Self {
39                value as i32
40            }
41        }
42
43        impl From<i32> for $enum_name {
44            #[inline]
45            fn from(value: i32) -> Self {
46                match value {
47                    $($value => $enum_name::$variant,)*
48                    _ => $enum_name::Unknown,
49                }
50            }
51        }
52
53        impl $enum_name {
54            /// Convert to i32 value
55            #[inline]
56            pub const fn to_i32(self) -> i32 {
57                self as i32
58            }
59
60            /// Check if the request code is unknown
61            #[inline]
62            pub const fn is_unknown(&self) -> bool {
63                matches!(self, Self::Unknown)
64            }
65        }
66    };
67}
68
69define_request_code! {
70    #[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
71    pub enum RequestCode {
72        SendMessage = 10,
73        PullMessage = 11,
74        QueryMessage = 12,
75        QueryBrokerOffset = 13, // Not used in Java
76        QueryConsumerOffset = 14,
77        UpdateConsumerOffset = 15,
78        UpdateAndCreateTopic = 17,
79        UpdateAndCreateTopicList = 18,
80        GetAllTopicConfig = 21,
81        GetTopicConfigList = 22, // Not used in Java
82        GetTopicNameList = 23,   // Not used in Java
83        UpdateBrokerConfig = 25,
84        GetBrokerConfig = 26,
85        TriggerDeleteFiles = 27, // Not used in Java
86        GetBrokerRuntimeInfo = 28,
87        SearchOffsetByTimestamp = 29,
88        GetMaxOffset = 30,
89        GetMinOffset = 31,
90        GetEarliestMsgStoreTime = 32,
91        ViewMessageById = 33,
92        HeartBeat = 34,
93        UnregisterClient = 35,
94        ConsumerSendMsgBack = 36,
95        EndTransaction = 37,
96        GetConsumerListByGroup = 38,
97        CheckTransactionState = 39,
98        NotifyConsumerIdsChanged = 40,
99        LockBatchMq = 41,
100        UnlockBatchMq = 42,
101        GetAllConsumerOffset = 43,
102        GetAllDelayOffset = 45,
103        CheckClientConfig = 46,
104        GetClientConfig = 47, // Not used in Java
105        UpdateAndCreateAclConfig = 50,
106        DeleteAclConfig = 51,
107        GetBrokerClusterAclInfo = 52,
108        UpdateGlobalWhiteAddrsConfig = 53,
109        GetBrokerClusterAclConfig = 54, // Deprecated
110        GetTimerCheckPoint = 60,
111        GetTimerMetrics = 61,
112
113        PopMessage = 200050,
114        AckMessage = 200051,
115        BatchAckMessage = 200151,
116        PeekMessage = 200052,
117        ChangeMessageInvisibleTime = 200053,
118        Notification = 200054,
119        PollingInfo = 200055,
120        PopRollback = 200056,
121
122        PopLiteMessage = 200070,
123        LiteSubscriptionCtl = 200071,
124        AckLiteMessage = 200072,
125        NotifyUnsubscribeLite = 200073,
126        GetBrokerLiteInfo = 200074,
127        GetParentTopicInfo = 200075,
128        GetLiteTopicInfo = 200076,
129        GetLiteClientInfo = 200077,
130        GetLiteGroupInfo = 200078,
131        TriggerLiteDispatch = 200079,
132
133        PutKvConfig = 100,
134        GetKvConfig = 101,
135        DeleteKvConfig = 102,
136        RegisterBroker = 103,
137        UnregisterBroker = 104,
138        GetRouteinfoByTopic = 105,
139        GetBrokerClusterInfo = 106,
140        UpdateAndCreateSubscriptionGroup = 200,
141        GetAllSubscriptionGroupConfig = 201,
142        GetTopicStatsInfo = 202,
143        GetConsumerConnectionList = 203,
144        GetProducerConnectionList = 204,
145        WipeWritePermOfBroker = 205,
146        GetAllTopicListFromNameserver = 206,
147        DeleteSubscriptionGroup = 207,
148        GetConsumeStats = 208,
149
150        SuspendConsumer = 209,               // Not used in Java
151        ResumeConsumer = 210,                // Not used in Java
152        ResetConsumerOffsetInConsumer = 211, // Not used in Java
153        ResetConsumerOffsetInBroker = 212,   // Not used in Java
154        AdjustConsumerThreadPool = 213,      // Not used in Java
155        WhoConsumeTheMessage = 214,          // Not used in Java
156
157        DeleteTopicInBroker = 215,
158        DeleteTopicInNamesrv = 216,
159        RegisterTopicInNamesrv = 217,
160        GetKvlistByNamespace = 219,
161        ResetConsumerClientOffset = 220,
162        GetConsumerStatusFromClient = 221,
163        InvokeBrokerToResetOffset = 222,
164        InvokeBrokerToGetConsumerStatus = 223,
165        UpdateAndCreateSubscriptionGroupList = 225,
166
167        QueryTopicConsumeByWho = 300,
168        GetTopicsByCluster = 224,
169        QueryTopicsByConsumer = 343,
170        QuerySubscriptionByConsumer = 345,
171
172        RegisterFilterServer = 301,       // Not used in Java
173        RegisterMessageFilterClass = 302, // Not used in Java
174
175        QueryConsumeTimeSpan = 303,
176        GetSystemTopicListFromNs = 304,
177        GetSystemTopicListFromBroker = 305,
178        CleanExpiredConsumequeue = 306,
179        GetConsumerRunningInfo = 307,
180        QueryCorrectionOffset = 308,
181        ConsumeMessageDirectly = 309,
182        SendMessageV2 = 310,
183        GetUnitTopicList = 311,
184        GetHasUnitSubTopicList = 312,
185        GetHasUnitSubUnunitTopicList = 313,
186        CloneGroupOffset = 314,
187        ViewBrokerStatsData = 315,
188        CleanUnusedTopic = 316,
189        GetBrokerConsumeStats = 317,
190        UpdateNamesrvConfig = 318,
191        GetNamesrvConfig = 319,
192        SendBatchMessage = 320,
193        QueryConsumeQueue = 321,
194        QueryDataVersion = 322,
195        ResumeCheckHalfMessage = 323,
196        SendReplyMessage = 324,
197        SendReplyMessageV2 = 325,
198        PushReplyMessageToClient = 326,
199        AddWritePermOfBroker = 327,
200        GetTopicConfig = 351,
201        GetSubscriptionGroupConfig = 352,
202        UpdateAndGetGroupForbidden = 353,
203        CheckRocksdbCqWriteProgress = 354,
204        ExportRocksdbConfigToJson = 355,
205
206        LitePullMessage = 361,
207        RecallMessage = 370,
208
209        QueryAssignment = 400,
210        SetMessageRequestMode = 401,
211        GetAllMessageRequestMode = 402,
212        UpdateAndCreateStaticTopic = 513,
213        GetBrokerMemberGroup = 901,
214        AddBroker = 902,
215        RemoveBroker = 903,
216        BrokerHeartbeat = 904,
217        NotifyMinBrokerIdChange = 905,
218        ExchangeBrokerHaInfo = 906,
219        GetBrokerHaStatus = 907,
220        ResetMasterFlushOffset = 908,
221        GetAllProducerInfo = 328,
222        DeleteExpiredCommitlog = 329,
223
224        UpdateColdDataFlowCtrConfig = 2001,
225        RemoveColdDataFlowCtrConfig = 2002,
226        GetColdDataFlowCtrInfo = 2003,
227        SetCommitlogReadMode = 2004,
228
229        // Controller codes
230        ControllerAlterSyncStateSet = 1001,
231        ControllerElectMaster = 1002,
232        ControllerRegisterBroker = 1003,
233        ControllerGetReplicaInfo = 1004,
234        ControllerGetMetadataInfo = 1005,
235        ControllerGetSyncStateData = 1006,
236        GetBrokerEpochCache = 1007,
237        NotifyBrokerRoleChanged = 1008,
238        UpdateControllerConfig = 1009,
239        GetControllerConfig = 1010,
240
241        CleanBrokerData = 1011,
242        ControllerGetNextBrokerId = 1012,
243        ControllerApplyBrokerId = 1013,
244        BrokerCloseChannelRequest = 1014,
245        CheckNotActiveBrokerRequest = 1015,
246        GetBrokerLiveInfoRequest = 1016,
247        GetSyncStateDataRequest = 1017,
248        RaftBrokerHeartBeatEventRequest = 1018,
249
250        // Auth codes
251        AuthCreateUser = 3001,
252        AuthUpdateUser = 3002,
253        AuthDeleteUser = 3003,
254        AuthGetUser = 3004,
255        AuthListUsers = 3005,
256        AuthCreateAcl = 3006,
257        AuthUpdateAcl = 3007,
258        AuthDeleteAcl = 3008,
259        AuthGetAcl = 3009,
260        AuthListAcl = 3010,
261
262        SwitchTimerEngine = 5001,
263
264        Unknown = -9999999,
265    }
266}
267
268#[cfg(test)]
269mod tests {
270    use super::*;
271
272    #[test]
273    fn test_request_code_to_i32() {
274        assert_eq!(RequestCode::SendMessage.to_i32(), 10);
275        assert_eq!(RequestCode::PullMessage.to_i32(), 11);
276        assert_eq!(RequestCode::HeartBeat.to_i32(), 34);
277        assert_eq!(RequestCode::PopMessage.to_i32(), 200050);
278        assert_eq!(RequestCode::ControllerAlterSyncStateSet.to_i32(), 1001);
279        assert_eq!(RequestCode::AuthCreateUser.to_i32(), 3001);
280        assert_eq!(RequestCode::Unknown.to_i32(), -9999999);
281    }
282
283    #[test]
284    fn test_i32_to_request_code() {
285        assert_eq!(RequestCode::from(10), RequestCode::SendMessage);
286        assert_eq!(RequestCode::from(11), RequestCode::PullMessage);
287        assert_eq!(RequestCode::from(34), RequestCode::HeartBeat);
288        assert_eq!(RequestCode::from(200050), RequestCode::PopMessage);
289        assert_eq!(RequestCode::from(1001), RequestCode::ControllerAlterSyncStateSet);
290        assert_eq!(RequestCode::from(3001), RequestCode::AuthCreateUser);
291        assert_eq!(RequestCode::from(-9999999), RequestCode::Unknown);
292    }
293
294    #[test]
295    fn test_unknown_code_conversion() {
296        // Any unknown i32 value should return Unknown
297        assert_eq!(RequestCode::from(99999), RequestCode::Unknown);
298        assert_eq!(RequestCode::from(-1), RequestCode::Unknown);
299        assert_eq!(RequestCode::from(0), RequestCode::Unknown);
300        assert_eq!(RequestCode::from(999), RequestCode::Unknown);
301    }
302
303    #[test]
304    fn test_is_unknown() {
305        assert!(RequestCode::Unknown.is_unknown());
306        assert!(!RequestCode::SendMessage.is_unknown());
307        assert!(!RequestCode::HeartBeat.is_unknown());
308        assert!(!RequestCode::PopMessage.is_unknown());
309
310        // Test with unknown code conversion
311        let unknown_code = RequestCode::from(12345);
312        assert!(unknown_code.is_unknown());
313    }
314
315    #[test]
316    fn test_request_code_from_trait() {
317        let code: i32 = RequestCode::SendMessage.into();
318        assert_eq!(code, 10);
319
320        let code: i32 = RequestCode::Unknown.into();
321        assert_eq!(code, -9999999);
322    }
323
324    #[test]
325    fn test_round_trip_conversion() {
326        // Test that converting to i32 and back gives the same value
327        let codes = vec![
328            RequestCode::SendMessage,
329            RequestCode::PullMessage,
330            RequestCode::QueryMessage,
331            RequestCode::HeartBeat,
332            RequestCode::PopMessage,
333            RequestCode::RegisterBroker,
334            RequestCode::ControllerElectMaster,
335            RequestCode::AuthCreateUser,
336            RequestCode::Unknown,
337        ];
338
339        for code in codes {
340            let i32_val = code.to_i32();
341            let converted_back = RequestCode::from(i32_val);
342            assert_eq!(code, converted_back, "Round trip failed for {:?}", code);
343        }
344    }
345
346    #[test]
347    fn test_derive_traits() {
348        // Test Debug
349        let code = RequestCode::SendMessage;
350        assert_eq!(format!("{:?}", code), "SendMessage");
351
352        // Test Clone and Copy
353        let code1 = RequestCode::HeartBeat;
354        let code2 = code1;
355        let code3 = code1;
356        assert_eq!(code1, code2);
357        assert_eq!(code1, code3);
358
359        // Test PartialEq and Eq
360        assert_eq!(RequestCode::SendMessage, RequestCode::SendMessage);
361        assert_ne!(RequestCode::SendMessage, RequestCode::PullMessage);
362
363        // Test Hash (by using in a HashSet)
364        use std::collections::HashSet;
365        let mut set = HashSet::new();
366        set.insert(RequestCode::SendMessage);
367        set.insert(RequestCode::SendMessage); // Duplicate
368        set.insert(RequestCode::PullMessage);
369        assert_eq!(set.len(), 2);
370    }
371
372    #[test]
373    fn test_special_codes() {
374        // Test Pop message range (200050-200055)
375        assert_eq!(RequestCode::from(200050), RequestCode::PopMessage);
376        assert_eq!(RequestCode::from(200051), RequestCode::AckMessage);
377        assert_eq!(RequestCode::from(200151), RequestCode::BatchAckMessage);
378        assert_eq!(RequestCode::from(200052), RequestCode::PeekMessage);
379        assert_eq!(RequestCode::from(200053), RequestCode::ChangeMessageInvisibleTime);
380        assert_eq!(RequestCode::from(200054), RequestCode::Notification);
381        assert_eq!(RequestCode::from(200055), RequestCode::PollingInfo);
382
383        // Test Controller codes (1001-1018)
384        assert_eq!(RequestCode::from(1001), RequestCode::ControllerAlterSyncStateSet);
385        assert_eq!(RequestCode::from(1018), RequestCode::RaftBrokerHeartBeatEventRequest);
386
387        // Test Auth codes (3001-3010)
388        assert_eq!(RequestCode::from(3001), RequestCode::AuthCreateUser);
389        assert_eq!(RequestCode::from(3010), RequestCode::AuthListAcl);
390
391        // Test Cold data flow codes (2001-2004)
392        assert_eq!(RequestCode::from(2001), RequestCode::UpdateColdDataFlowCtrConfig);
393        assert_eq!(RequestCode::from(2004), RequestCode::SetCommitlogReadMode);
394    }
395
396    #[test]
397    fn test_const_fn_to_i32() {
398        // Verify that to_i32 is const and can be used in const context
399        const CODE: i32 = RequestCode::SendMessage.to_i32();
400        assert_eq!(CODE, 10);
401    }
402
403    #[test]
404    fn test_repr_i32_size() {
405        // Verify that RequestCode has the same size as i32
406        use std::mem::size_of;
407        assert_eq!(size_of::<RequestCode>(), size_of::<i32>());
408    }
409}