Skip to main content

rocketmq_protocol/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)]
78pub 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);
196        // Edge case - unknown code defaults to SystemError
197    }
198
199    #[test]
200    fn test_remoting_sys_response_code_is_success() {
201        assert!(RemotingSysResponseCode::Success.is_success());
202        assert!(!RemotingSysResponseCode::SystemError.is_success());
203        assert!(!RemotingSysResponseCode::SystemBusy.is_success());
204    }
205
206    #[test]
207    fn test_remoting_sys_response_code_is_error() {
208        assert!(!RemotingSysResponseCode::Success.is_error());
209        assert!(RemotingSysResponseCode::SystemError.is_error());
210        assert!(RemotingSysResponseCode::SystemBusy.is_error());
211        assert!(RemotingSysResponseCode::NoPermission.is_error());
212    }
213
214    #[test]
215    fn test_response_code_to_i32() {
216        assert_eq!(ResponseCode::Success.to_i32(), 0);
217        assert_eq!(ResponseCode::SystemError.to_i32(), 1);
218        assert_eq!(ResponseCode::FlushDiskTimeout.to_i32(), 10);
219        assert_eq!(ResponseCode::RpcUnknown.to_i32(), -1000);
220        assert_eq!(ResponseCode::ControllerFencedMasterEpoch.to_i32(), 2000);
221    }
222
223    #[test]
224    fn response_code_from_i32() {
225        assert_eq!(ResponseCode::from(0), ResponseCode::Success);
226        assert_eq!(ResponseCode::from(1), ResponseCode::SystemError);
227        assert_eq!(ResponseCode::from(2), ResponseCode::SystemBusy);
228        assert_eq!(ResponseCode::from(3), ResponseCode::RequestCodeNotSupported);
229        assert_eq!(ResponseCode::from(4), ResponseCode::TransactionFailed);
230        assert_eq!(ResponseCode::from(10), ResponseCode::FlushDiskTimeout);
231        assert_eq!(ResponseCode::from(11), ResponseCode::SlaveNotAvailable);
232        assert_eq!(ResponseCode::from(12), ResponseCode::FlushSlaveTimeout);
233        assert_eq!(ResponseCode::from(13), ResponseCode::MessageIllegal);
234        assert_eq!(ResponseCode::from(14), ResponseCode::ServiceNotAvailable);
235        assert_eq!(ResponseCode::from(15), ResponseCode::VersionNotSupported);
236        assert_eq!(ResponseCode::from(16), ResponseCode::NoPermission);
237        assert_eq!(ResponseCode::from(17), ResponseCode::TopicNotExist);
238        assert_eq!(ResponseCode::from(18), ResponseCode::TopicExistAlready);
239        assert_eq!(ResponseCode::from(19), ResponseCode::PullNotFound);
240        assert_eq!(ResponseCode::from(20), ResponseCode::PullRetryImmediately);
241        assert_eq!(ResponseCode::from(21), ResponseCode::PullOffsetMoved);
242        assert_eq!(ResponseCode::from(22), ResponseCode::QueryNotFound);
243        assert_eq!(ResponseCode::from(23), ResponseCode::SubscriptionParseFailed);
244        assert_eq!(ResponseCode::from(24), ResponseCode::SubscriptionNotExist);
245        assert_eq!(ResponseCode::from(25), ResponseCode::SubscriptionNotLatest);
246        assert_eq!(ResponseCode::from(26), ResponseCode::SubscriptionGroupNotExist);
247        assert_eq!(ResponseCode::from(27), ResponseCode::FilterDataNotExist);
248        assert_eq!(ResponseCode::from(28), ResponseCode::FilterDataNotLatest);
249        assert_eq!(ResponseCode::from(200), ResponseCode::TransactionShouldCommit);
250        assert_eq!(ResponseCode::from(201), ResponseCode::TransactionShouldRollback);
251        assert_eq!(ResponseCode::from(202), ResponseCode::TransactionStateUnknow);
252        assert_eq!(ResponseCode::from(203), ResponseCode::TransactionStateGroupWrong);
253        assert_eq!(ResponseCode::from(204), ResponseCode::NoBuyerId);
254        assert_eq!(ResponseCode::from(205), ResponseCode::NotInCurrentUnit);
255        assert_eq!(ResponseCode::from(206), ResponseCode::ConsumerNotOnline);
256        assert_eq!(ResponseCode::from(207), ResponseCode::ConsumeMsgTimeout);
257        assert_eq!(ResponseCode::from(208), ResponseCode::NoMessage);
258        assert_eq!(ResponseCode::from(209), ResponseCode::PollingFull);
259        assert_eq!(ResponseCode::from(210), ResponseCode::PollingTimeout);
260        assert_eq!(ResponseCode::from(211), ResponseCode::BrokerNotExist);
261        assert_eq!(ResponseCode::from(212), ResponseCode::BrokerDispatchNotComplete);
262        assert_eq!(ResponseCode::from(213), ResponseCode::BroadcastConsumption);
263        assert_eq!(ResponseCode::from(215), ResponseCode::FlowControl);
264        assert_eq!(ResponseCode::from(501), ResponseCode::NotLeaderForQueue);
265        assert_eq!(ResponseCode::from(604), ResponseCode::IllegalOperation);
266        assert_eq!(ResponseCode::from(-1000), ResponseCode::RpcUnknown);
267        assert_eq!(ResponseCode::from(-1002), ResponseCode::RpcAddrIsNull);
268        assert_eq!(ResponseCode::from(-1004), ResponseCode::RpcSendToChannelFailed);
269        assert_eq!(ResponseCode::from(-1006), ResponseCode::RpcTimeOut);
270        assert_eq!(ResponseCode::from(1500), ResponseCode::GoAway);
271        assert_eq!(ResponseCode::from(2000), ResponseCode::ControllerFencedMasterEpoch);
272        assert_eq!(
273            ResponseCode::from(2001),
274            ResponseCode::ControllerFencedSyncStateSetEpoch
275        );
276        assert_eq!(ResponseCode::from(2002), ResponseCode::ControllerInvalidMaster);
277        assert_eq!(ResponseCode::from(2003), ResponseCode::ControllerInvalidReplicas);
278        assert_eq!(ResponseCode::from(2004), ResponseCode::ControllerMasterNotAvailable);
279        assert_eq!(ResponseCode::from(2005), ResponseCode::ControllerInvalidRequest);
280        assert_eq!(ResponseCode::from(2006), ResponseCode::ControllerBrokerNotAlive);
281        assert_eq!(ResponseCode::from(2007), ResponseCode::ControllerNotLeader);
282        assert_eq!(ResponseCode::from(2008), ResponseCode::ControllerBrokerMetadataNotExist);
283        assert_eq!(
284            ResponseCode::from(2009),
285            ResponseCode::ControllerInvalidCleanBrokerMetadata
286        );
287        assert_eq!(
288            ResponseCode::from(2010),
289            ResponseCode::ControllerBrokerNeedToBeRegistered
290        );
291        assert_eq!(ResponseCode::from(2011), ResponseCode::ControllerMasterStillExist);
292        assert_eq!(ResponseCode::from(2012), ResponseCode::ControllerElectMasterFailed);
293        assert_eq!(
294            ResponseCode::from(2013),
295            ResponseCode::ControllerAlterSyncStateSetFailed
296        );
297        assert_eq!(ResponseCode::from(2014), ResponseCode::ControllerBrokerIdInvalid);
298        assert_eq!(ResponseCode::from(2015), ResponseCode::ControllerJraftInternalError);
299        assert_eq!(
300            ResponseCode::from(2016),
301            ResponseCode::ControllerBrokerLiveInfoNotExists
302        );
303        assert_eq!(ResponseCode::from(2017), ResponseCode::LmqQuotaExceeded);
304        assert_eq!(ResponseCode::from(2018), ResponseCode::LiteSubscriptionQuotaExceeded);
305        assert_eq!(ResponseCode::from(3001), ResponseCode::UserNotExist);
306        assert_eq!(ResponseCode::from(3002), ResponseCode::PolicyNotExist);
307        assert_eq!(ResponseCode::from(9999), ResponseCode::SystemError); // Edge case - unknown
308                                                                         // defaults to SystemError
309    }
310
311    #[test]
312    fn test_response_code_is_success() {
313        assert!(ResponseCode::Success.is_success());
314        assert!(!ResponseCode::SystemError.is_success());
315        assert!(!ResponseCode::FlushDiskTimeout.is_success());
316        assert!(!ResponseCode::RpcUnknown.is_success());
317    }
318
319    #[test]
320    fn test_response_code_is_error() {
321        assert!(!ResponseCode::Success.is_error());
322        assert!(ResponseCode::SystemError.is_error());
323        assert!(ResponseCode::SystemBusy.is_error());
324        assert!(ResponseCode::TopicNotExist.is_error());
325        assert!(ResponseCode::RpcTimeOut.is_error());
326    }
327
328    #[test]
329    fn test_response_code_round_trip() {
330        let codes = vec![
331            ResponseCode::Success,
332            ResponseCode::SystemError,
333            ResponseCode::FlushDiskTimeout,
334            ResponseCode::NoPermission,
335            ResponseCode::TransactionShouldCommit,
336            ResponseCode::RpcUnknown,
337            ResponseCode::ControllerNotLeader,
338        ];
339
340        for code in codes {
341            let i32_val = code.to_i32();
342            let converted_back = ResponseCode::from(i32_val);
343            assert_eq!(code, converted_back, "Round trip failed for {:?}", code);
344        }
345    }
346
347    #[test]
348    fn test_response_code_from_trait() {
349        let code: i32 = ResponseCode::Success.into();
350        assert_eq!(code, 0);
351
352        let code: i32 = ResponseCode::SystemError.into();
353        assert_eq!(code, 1);
354
355        let code: i32 = ResponseCode::RpcUnknown.into();
356        assert_eq!(code, -1000);
357    }
358
359    #[test]
360    fn test_response_code_const_fn() {
361        const SUCCESS_CODE: i32 = ResponseCode::Success.to_i32();
362        assert_eq!(SUCCESS_CODE, 0);
363
364        const ERROR_CODE: i32 = ResponseCode::SystemError.to_i32();
365        assert_eq!(ERROR_CODE, 1);
366    }
367
368    #[test]
369    fn test_response_code_repr_i32_size() {
370        use std::mem::size_of;
371        assert_eq!(size_of::<ResponseCode>(), size_of::<i32>());
372        assert_eq!(size_of::<RemotingSysResponseCode>(), size_of::<i32>());
373    }
374
375    #[test]
376    fn test_negative_response_codes() {
377        // Test RPC error codes (negative values)
378        assert_eq!(ResponseCode::from(-1000), ResponseCode::RpcUnknown);
379        assert_eq!(ResponseCode::from(-1002), ResponseCode::RpcAddrIsNull);
380        assert_eq!(ResponseCode::from(-1004), ResponseCode::RpcSendToChannelFailed);
381        assert_eq!(ResponseCode::from(-1006), ResponseCode::RpcTimeOut);
382
383        assert_eq!(ResponseCode::RpcUnknown.to_i32(), -1000);
384        assert_eq!(ResponseCode::RpcAddrIsNull.to_i32(), -1002);
385    }
386
387    #[test]
388    fn test_controller_response_codes() {
389        // Test Controller error codes (2000-2018)
390        assert_eq!(ResponseCode::from(2000), ResponseCode::ControllerFencedMasterEpoch);
391        assert_eq!(ResponseCode::from(2007), ResponseCode::ControllerNotLeader);
392        assert_eq!(ResponseCode::from(2014), ResponseCode::ControllerBrokerIdInvalid);
393        assert_eq!(ResponseCode::from(2015), ResponseCode::ControllerJraftInternalError);
394        assert_eq!(
395            ResponseCode::from(2016),
396            ResponseCode::ControllerBrokerLiveInfoNotExists
397        );
398        assert_eq!(ResponseCode::from(2017), ResponseCode::LmqQuotaExceeded);
399
400        assert_eq!(ResponseCode::ControllerFencedMasterEpoch.to_i32(), 2000);
401        assert_eq!(ResponseCode::ControllerNotLeader.to_i32(), 2007);
402        assert_eq!(ResponseCode::ControllerBrokerIdInvalid.to_i32(), 2014);
403        assert_eq!(ResponseCode::ControllerJraftInternalError.to_i32(), 2015);
404        assert_eq!(ResponseCode::ControllerBrokerLiveInfoNotExists.to_i32(), 2016);
405        assert_eq!(ResponseCode::LmqQuotaExceeded.to_i32(), 2017);
406    }
407
408    #[test]
409    fn test_auth_response_codes() {
410        assert_eq!(ResponseCode::from(3001), ResponseCode::UserNotExist);
411        assert_eq!(ResponseCode::from(3002), ResponseCode::PolicyNotExist);
412
413        assert_eq!(ResponseCode::UserNotExist.to_i32(), 3001);
414        assert_eq!(ResponseCode::PolicyNotExist.to_i32(), 3002);
415    }
416}