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