Skip to main content

rocketmq_remoting/code/
response_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 response code enums with automatic conversion implementations.
16/// This reduces code duplication and makes maintenance easier.
17macro_rules! define_response_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        default = $default:ident
27    ) => {
28        $(#[$enum_meta])*
29        #[repr(i32)]
30        pub enum $enum_name {
31            $(
32                $(#[$variant_meta])*
33                $variant = $value,
34            )*
35        }
36
37        impl From<$enum_name> for i32 {
38            #[inline]
39            fn from(value: $enum_name) -> Self {
40                value as i32
41            }
42        }
43
44        impl From<i32> for $enum_name {
45            #[inline]
46            fn from(value: i32) -> Self {
47                match value {
48                    $($value => $enum_name::$variant,)*
49                    _ => $enum_name::$default,
50                }
51            }
52        }
53
54        impl $enum_name {
55            /// Convert to i32 value
56            #[inline]
57            pub const fn to_i32(self) -> i32 {
58                self as i32
59            }
60
61            /// Check if this is a success response
62            #[inline]
63            pub const fn is_success(&self) -> bool {
64                matches!(self, Self::Success)
65            }
66
67            /// Check if this is an error response
68            #[inline]
69            pub const fn is_error(&self) -> bool {
70                !self.is_success()
71            }
72        }
73    };
74}
75
76define_response_code! {
77    #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
78    pub enum RemotingSysResponseCode {
79        Success = 0,
80        SystemError = 1,
81        SystemBusy = 2,
82        RequestCodeNotSupported = 3,
83        TransactionFailed = 4,
84        NoPermission = 16,
85    },
86    default = SystemError
87}
88
89define_response_code! {
90    #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
91    pub enum ResponseCode {
92        Success = 0,
93        SystemError = 1,
94        SystemBusy = 2,
95        RequestCodeNotSupported = 3,
96        TransactionFailed = 4,
97        FlushDiskTimeout = 10,
98        SlaveNotAvailable = 11,
99        FlushSlaveTimeout = 12,
100        MessageIllegal = 13,
101        ServiceNotAvailable = 14,
102        VersionNotSupported = 15,
103        NoPermission = 16,
104        TopicNotExist = 17,
105        TopicExistAlready = 18,
106        PullNotFound = 19,
107        PullRetryImmediately = 20,
108        PullOffsetMoved = 21,
109        QueryNotFound = 22,
110        SubscriptionParseFailed = 23,
111        SubscriptionNotExist = 24,
112        SubscriptionNotLatest = 25,
113        SubscriptionGroupNotExist = 26,
114        FilterDataNotExist = 27,
115        FilterDataNotLatest = 28,
116        InvalidParameter =29,
117        TransactionShouldCommit = 200,
118        TransactionShouldRollback = 201,
119        TransactionStateUnknow = 202,
120        TransactionStateGroupWrong = 203,
121        NoBuyerId = 204,
122        NotInCurrentUnit = 205,
123        ConsumerNotOnline = 206,
124        ConsumeMsgTimeout = 207,
125        NoMessage = 208,
126        /*UpdateAndCreateAclConfigFailed = 209,
127        DeleteAclConfigFailed = 210,
128        UpdateGlobalWhiteAddrsConfigFailed = 211,*/
129        PollingFull = 209,
130        PollingTimeout = 210,
131        BrokerNotExist = 211,
132        BrokerDispatchNotComplete = 212,
133        BroadcastConsumption = 213,
134        FlowControl = 215,
135        NotLeaderForQueue = 501,
136        IllegalOperation = 604,
137        RpcUnknown = -1000,
138        RpcAddrIsNull = -1002,
139        RpcSendToChannelFailed = -1004,
140        RpcTimeOut = -1006,
141        GoAway = 1500,
142        ControllerFencedMasterEpoch = 2000,
143        ControllerFencedSyncStateSetEpoch = 2001,
144        ControllerInvalidMaster = 2002,
145        ControllerInvalidReplicas = 2003,
146        ControllerMasterNotAvailable = 2004,
147        ControllerInvalidRequest = 2005,
148        ControllerBrokerNotAlive = 2006,
149        ControllerNotLeader = 2007,
150        ControllerBrokerMetadataNotExist = 2008,
151        ControllerInvalidCleanBrokerMetadata = 2009,
152        ControllerBrokerNeedToBeRegistered = 2010,
153        ControllerMasterStillExist = 2011,
154        ControllerElectMasterFailed = 2012,
155        ControllerAlterSyncStateSetFailed = 2013,
156        ControllerBrokerIdInvalid = 2014,
157        ControllerJraftInternalError = 2015,
158        ControllerBrokerLiveInfoNotExists = 2016,
159        LmqQuotaExceeded = 2017,
160        LiteSubscriptionQuotaExceeded = 2018,
161        UserNotExist = 3001,
162        PolicyNotExist = 3002,
163    },
164    default = SystemError
165}
166
167#[cfg(test)]
168mod tests {
169    use super::*;
170
171    #[test]
172    fn test_remoting_sys_response_code_to_i32() {
173        assert_eq!(RemotingSysResponseCode::Success.to_i32(), 0);
174        assert_eq!(RemotingSysResponseCode::SystemError.to_i32(), 1);
175        assert_eq!(RemotingSysResponseCode::SystemBusy.to_i32(), 2);
176        assert_eq!(RemotingSysResponseCode::RequestCodeNotSupported.to_i32(), 3);
177        assert_eq!(RemotingSysResponseCode::TransactionFailed.to_i32(), 4);
178        assert_eq!(RemotingSysResponseCode::NoPermission.to_i32(), 16);
179    }
180
181    #[test]
182    fn remoting_sys_response_code_from_i32() {
183        assert_eq!(RemotingSysResponseCode::from(0), RemotingSysResponseCode::Success);
184        assert_eq!(RemotingSysResponseCode::from(1), RemotingSysResponseCode::SystemError);
185        assert_eq!(RemotingSysResponseCode::from(2), RemotingSysResponseCode::SystemBusy);
186        assert_eq!(
187            RemotingSysResponseCode::from(3),
188            RemotingSysResponseCode::RequestCodeNotSupported
189        );
190        assert_eq!(
191            RemotingSysResponseCode::from(4),
192            RemotingSysResponseCode::TransactionFailed
193        );
194        assert_eq!(RemotingSysResponseCode::from(16), RemotingSysResponseCode::NoPermission);
195        assert_eq!(RemotingSysResponseCode::from(999), RemotingSysResponseCode::SystemError); // Edge case - unknown code defaults to SystemError
196    }
197
198    #[test]
199    fn test_remoting_sys_response_code_is_success() {
200        assert!(RemotingSysResponseCode::Success.is_success());
201        assert!(!RemotingSysResponseCode::SystemError.is_success());
202        assert!(!RemotingSysResponseCode::SystemBusy.is_success());
203    }
204
205    #[test]
206    fn test_remoting_sys_response_code_is_error() {
207        assert!(!RemotingSysResponseCode::Success.is_error());
208        assert!(RemotingSysResponseCode::SystemError.is_error());
209        assert!(RemotingSysResponseCode::SystemBusy.is_error());
210        assert!(RemotingSysResponseCode::NoPermission.is_error());
211    }
212
213    #[test]
214    fn test_response_code_to_i32() {
215        assert_eq!(ResponseCode::Success.to_i32(), 0);
216        assert_eq!(ResponseCode::SystemError.to_i32(), 1);
217        assert_eq!(ResponseCode::FlushDiskTimeout.to_i32(), 10);
218        assert_eq!(ResponseCode::RpcUnknown.to_i32(), -1000);
219        assert_eq!(ResponseCode::ControllerFencedMasterEpoch.to_i32(), 2000);
220    }
221
222    #[test]
223    fn response_code_from_i32() {
224        assert_eq!(ResponseCode::from(0), ResponseCode::Success);
225        assert_eq!(ResponseCode::from(1), ResponseCode::SystemError);
226        assert_eq!(ResponseCode::from(2), ResponseCode::SystemBusy);
227        assert_eq!(ResponseCode::from(3), ResponseCode::RequestCodeNotSupported);
228        assert_eq!(ResponseCode::from(4), ResponseCode::TransactionFailed);
229        assert_eq!(ResponseCode::from(10), ResponseCode::FlushDiskTimeout);
230        assert_eq!(ResponseCode::from(11), ResponseCode::SlaveNotAvailable);
231        assert_eq!(ResponseCode::from(12), ResponseCode::FlushSlaveTimeout);
232        assert_eq!(ResponseCode::from(13), ResponseCode::MessageIllegal);
233        assert_eq!(ResponseCode::from(14), ResponseCode::ServiceNotAvailable);
234        assert_eq!(ResponseCode::from(15), ResponseCode::VersionNotSupported);
235        assert_eq!(ResponseCode::from(16), ResponseCode::NoPermission);
236        assert_eq!(ResponseCode::from(17), ResponseCode::TopicNotExist);
237        assert_eq!(ResponseCode::from(18), ResponseCode::TopicExistAlready);
238        assert_eq!(ResponseCode::from(19), ResponseCode::PullNotFound);
239        assert_eq!(ResponseCode::from(20), ResponseCode::PullRetryImmediately);
240        assert_eq!(ResponseCode::from(21), ResponseCode::PullOffsetMoved);
241        assert_eq!(ResponseCode::from(22), ResponseCode::QueryNotFound);
242        assert_eq!(ResponseCode::from(23), ResponseCode::SubscriptionParseFailed);
243        assert_eq!(ResponseCode::from(24), ResponseCode::SubscriptionNotExist);
244        assert_eq!(ResponseCode::from(25), ResponseCode::SubscriptionNotLatest);
245        assert_eq!(ResponseCode::from(26), ResponseCode::SubscriptionGroupNotExist);
246        assert_eq!(ResponseCode::from(27), ResponseCode::FilterDataNotExist);
247        assert_eq!(ResponseCode::from(28), ResponseCode::FilterDataNotLatest);
248        assert_eq!(ResponseCode::from(200), ResponseCode::TransactionShouldCommit);
249        assert_eq!(ResponseCode::from(201), ResponseCode::TransactionShouldRollback);
250        assert_eq!(ResponseCode::from(202), ResponseCode::TransactionStateUnknow);
251        assert_eq!(ResponseCode::from(203), ResponseCode::TransactionStateGroupWrong);
252        assert_eq!(ResponseCode::from(204), ResponseCode::NoBuyerId);
253        assert_eq!(ResponseCode::from(205), ResponseCode::NotInCurrentUnit);
254        assert_eq!(ResponseCode::from(206), ResponseCode::ConsumerNotOnline);
255        assert_eq!(ResponseCode::from(207), ResponseCode::ConsumeMsgTimeout);
256        assert_eq!(ResponseCode::from(208), ResponseCode::NoMessage);
257        assert_eq!(ResponseCode::from(209), ResponseCode::PollingFull);
258        assert_eq!(ResponseCode::from(210), ResponseCode::PollingTimeout);
259        assert_eq!(ResponseCode::from(211), ResponseCode::BrokerNotExist);
260        assert_eq!(ResponseCode::from(212), ResponseCode::BrokerDispatchNotComplete);
261        assert_eq!(ResponseCode::from(213), ResponseCode::BroadcastConsumption);
262        assert_eq!(ResponseCode::from(215), ResponseCode::FlowControl);
263        assert_eq!(ResponseCode::from(501), ResponseCode::NotLeaderForQueue);
264        assert_eq!(ResponseCode::from(604), ResponseCode::IllegalOperation);
265        assert_eq!(ResponseCode::from(-1000), ResponseCode::RpcUnknown);
266        assert_eq!(ResponseCode::from(-1002), ResponseCode::RpcAddrIsNull);
267        assert_eq!(ResponseCode::from(-1004), ResponseCode::RpcSendToChannelFailed);
268        assert_eq!(ResponseCode::from(-1006), ResponseCode::RpcTimeOut);
269        assert_eq!(ResponseCode::from(1500), ResponseCode::GoAway);
270        assert_eq!(ResponseCode::from(2000), ResponseCode::ControllerFencedMasterEpoch);
271        assert_eq!(
272            ResponseCode::from(2001),
273            ResponseCode::ControllerFencedSyncStateSetEpoch
274        );
275        assert_eq!(ResponseCode::from(2002), ResponseCode::ControllerInvalidMaster);
276        assert_eq!(ResponseCode::from(2003), ResponseCode::ControllerInvalidReplicas);
277        assert_eq!(ResponseCode::from(2004), ResponseCode::ControllerMasterNotAvailable);
278        assert_eq!(ResponseCode::from(2005), ResponseCode::ControllerInvalidRequest);
279        assert_eq!(ResponseCode::from(2006), ResponseCode::ControllerBrokerNotAlive);
280        assert_eq!(ResponseCode::from(2007), ResponseCode::ControllerNotLeader);
281        assert_eq!(ResponseCode::from(2008), ResponseCode::ControllerBrokerMetadataNotExist);
282        assert_eq!(
283            ResponseCode::from(2009),
284            ResponseCode::ControllerInvalidCleanBrokerMetadata
285        );
286        assert_eq!(
287            ResponseCode::from(2010),
288            ResponseCode::ControllerBrokerNeedToBeRegistered
289        );
290        assert_eq!(ResponseCode::from(2011), ResponseCode::ControllerMasterStillExist);
291        assert_eq!(ResponseCode::from(2012), ResponseCode::ControllerElectMasterFailed);
292        assert_eq!(
293            ResponseCode::from(2013),
294            ResponseCode::ControllerAlterSyncStateSetFailed
295        );
296        assert_eq!(ResponseCode::from(2014), ResponseCode::ControllerBrokerIdInvalid);
297        assert_eq!(ResponseCode::from(2015), ResponseCode::ControllerJraftInternalError);
298        assert_eq!(
299            ResponseCode::from(2016),
300            ResponseCode::ControllerBrokerLiveInfoNotExists
301        );
302        assert_eq!(ResponseCode::from(2017), ResponseCode::LmqQuotaExceeded);
303        assert_eq!(ResponseCode::from(2018), ResponseCode::LiteSubscriptionQuotaExceeded);
304        assert_eq!(ResponseCode::from(3001), ResponseCode::UserNotExist);
305        assert_eq!(ResponseCode::from(3002), ResponseCode::PolicyNotExist);
306        assert_eq!(ResponseCode::from(9999), ResponseCode::SystemError); // Edge case - unknown
307                                                                         // defaults to SystemError
308    }
309
310    #[test]
311    fn test_response_code_is_success() {
312        assert!(ResponseCode::Success.is_success());
313        assert!(!ResponseCode::SystemError.is_success());
314        assert!(!ResponseCode::FlushDiskTimeout.is_success());
315        assert!(!ResponseCode::RpcUnknown.is_success());
316    }
317
318    #[test]
319    fn test_response_code_is_error() {
320        assert!(!ResponseCode::Success.is_error());
321        assert!(ResponseCode::SystemError.is_error());
322        assert!(ResponseCode::SystemBusy.is_error());
323        assert!(ResponseCode::TopicNotExist.is_error());
324        assert!(ResponseCode::RpcTimeOut.is_error());
325    }
326
327    #[test]
328    fn test_response_code_round_trip() {
329        let codes = vec![
330            ResponseCode::Success,
331            ResponseCode::SystemError,
332            ResponseCode::FlushDiskTimeout,
333            ResponseCode::NoPermission,
334            ResponseCode::TransactionShouldCommit,
335            ResponseCode::RpcUnknown,
336            ResponseCode::ControllerNotLeader,
337        ];
338
339        for code in codes {
340            let i32_val = code.to_i32();
341            let converted_back = ResponseCode::from(i32_val);
342            assert_eq!(code, converted_back, "Round trip failed for {:?}", code);
343        }
344    }
345
346    #[test]
347    fn test_response_code_from_trait() {
348        let code: i32 = ResponseCode::Success.into();
349        assert_eq!(code, 0);
350
351        let code: i32 = ResponseCode::SystemError.into();
352        assert_eq!(code, 1);
353
354        let code: i32 = ResponseCode::RpcUnknown.into();
355        assert_eq!(code, -1000);
356    }
357
358    #[test]
359    fn test_response_code_const_fn() {
360        const SUCCESS_CODE: i32 = ResponseCode::Success.to_i32();
361        assert_eq!(SUCCESS_CODE, 0);
362
363        const ERROR_CODE: i32 = ResponseCode::SystemError.to_i32();
364        assert_eq!(ERROR_CODE, 1);
365    }
366
367    #[test]
368    fn test_response_code_derive_traits() {
369        // Test Debug
370        let code = ResponseCode::Success;
371        assert_eq!(format!("{:?}", code), "Success");
372
373        // Test Clone and Copy
374        let code1 = ResponseCode::SystemError;
375        let code2 = code1;
376        assert_eq!(code1, code2);
377
378        // Test PartialEq and Eq
379        assert_eq!(ResponseCode::Success, ResponseCode::Success);
380        assert_ne!(ResponseCode::Success, ResponseCode::SystemError);
381
382        // Test Hash
383        use std::collections::HashSet;
384        let mut set = HashSet::new();
385        set.insert(ResponseCode::Success);
386        set.insert(ResponseCode::Success); // Duplicate
387        set.insert(ResponseCode::SystemError);
388        assert_eq!(set.len(), 2);
389    }
390
391    #[test]
392    fn test_response_code_repr_i32_size() {
393        use std::mem::size_of;
394        assert_eq!(size_of::<ResponseCode>(), size_of::<i32>());
395        assert_eq!(size_of::<RemotingSysResponseCode>(), size_of::<i32>());
396    }
397
398    #[test]
399    fn test_negative_response_codes() {
400        // Test RPC error codes (negative values)
401        assert_eq!(ResponseCode::from(-1000), ResponseCode::RpcUnknown);
402        assert_eq!(ResponseCode::from(-1002), ResponseCode::RpcAddrIsNull);
403        assert_eq!(ResponseCode::from(-1004), ResponseCode::RpcSendToChannelFailed);
404        assert_eq!(ResponseCode::from(-1006), ResponseCode::RpcTimeOut);
405
406        assert_eq!(ResponseCode::RpcUnknown.to_i32(), -1000);
407        assert_eq!(ResponseCode::RpcAddrIsNull.to_i32(), -1002);
408    }
409
410    #[test]
411    fn test_controller_response_codes() {
412        // Test Controller error codes (2000-2018)
413        assert_eq!(ResponseCode::from(2000), ResponseCode::ControllerFencedMasterEpoch);
414        assert_eq!(ResponseCode::from(2007), ResponseCode::ControllerNotLeader);
415        assert_eq!(ResponseCode::from(2014), ResponseCode::ControllerBrokerIdInvalid);
416        assert_eq!(ResponseCode::from(2015), ResponseCode::ControllerJraftInternalError);
417        assert_eq!(
418            ResponseCode::from(2016),
419            ResponseCode::ControllerBrokerLiveInfoNotExists
420        );
421        assert_eq!(ResponseCode::from(2017), ResponseCode::LmqQuotaExceeded);
422
423        assert_eq!(ResponseCode::ControllerFencedMasterEpoch.to_i32(), 2000);
424        assert_eq!(ResponseCode::ControllerNotLeader.to_i32(), 2007);
425        assert_eq!(ResponseCode::ControllerBrokerIdInvalid.to_i32(), 2014);
426        assert_eq!(ResponseCode::ControllerJraftInternalError.to_i32(), 2015);
427        assert_eq!(ResponseCode::ControllerBrokerLiveInfoNotExists.to_i32(), 2016);
428        assert_eq!(ResponseCode::LmqQuotaExceeded.to_i32(), 2017);
429    }
430
431    #[test]
432    fn test_auth_response_codes() {
433        assert_eq!(ResponseCode::from(3001), ResponseCode::UserNotExist);
434        assert_eq!(ResponseCode::from(3002), ResponseCode::PolicyNotExist);
435
436        assert_eq!(ResponseCode::UserNotExist.to_i32(), 3001);
437        assert_eq!(ResponseCode::PolicyNotExist.to_i32(), 3002);
438    }
439}