Skip to main content

rocketmq_client_rust/
legacy.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#![allow(deprecated)]
16
17use cheetah_string::CheetahString;
18use rocketmq_common::common::message::message_ext::MessageExt;
19use rocketmq_common::common::message::message_queue::MessageQueue;
20use rocketmq_error::RocketMQError;
21use rocketmq_error::RocketMQResult;
22
23use crate::producer::local_transaction_state::LocalTransactionState;
24
25const MODERN_LITE_PULL_CONSUMER: &str = "DefaultLitePullConsumer";
26const MODERN_TRANSACTION_LISTENER: &str = "TransactionListener";
27const MODERN_TRACE_HOOKS: &str = "RocketMQ trace hooks";
28
29fn unsupported_legacy_api(api: &str, replacement: &str) -> RocketMQError {
30    RocketMQError::illegal_argument(format!(
31        "{api} is deprecated in the RocketMQ Java client and is not supported by rocketmq-client-rust; use \
32         {replacement} instead"
33    ))
34}
35
36fn unsupported_impl_api(api: &str) -> RocketMQError {
37    RocketMQError::illegal_argument(format!(
38        "{api} is a RocketMQ Java impl-package type and is not part of the rocketmq-client-rust public API"
39    ))
40}
41
42#[deprecated(
43    since = "0.9.0",
44    note = "Java DefaultMQPullConsumer is deprecated; use DefaultLitePullConsumer"
45)]
46#[derive(Debug, Clone, Default)]
47pub struct DefaultMQPullConsumer {
48    consumer_group: Option<CheetahString>,
49}
50
51impl DefaultMQPullConsumer {
52    pub fn new() -> Self {
53        Self::default()
54    }
55
56    pub fn with_consumer_group(consumer_group: impl Into<CheetahString>) -> Self {
57        Self {
58            consumer_group: Some(consumer_group.into()),
59        }
60    }
61
62    pub fn consumer_group(&self) -> Option<&CheetahString> {
63        self.consumer_group.as_ref()
64    }
65
66    pub fn start(&self) -> RocketMQResult<()> {
67        Err(unsupported_legacy_api(
68            "DefaultMQPullConsumer",
69            MODERN_LITE_PULL_CONSUMER,
70        ))
71    }
72
73    pub fn shutdown(&self) -> RocketMQResult<()> {
74        Err(unsupported_legacy_api(
75            "DefaultMQPullConsumer",
76            MODERN_LITE_PULL_CONSUMER,
77        ))
78    }
79
80    pub fn default_mq_pull_consumer_impl(&self) -> RocketMQResult<DefaultMQPullConsumerImpl> {
81        Err(unsupported_legacy_api(
82            "DefaultMQPullConsumerImpl",
83            MODERN_LITE_PULL_CONSUMER,
84        ))
85    }
86}
87
88#[deprecated(since = "0.9.0", note = "Java MQPullConsumer is deprecated; use LitePullConsumer")]
89pub trait MQPullConsumer {
90    fn start(&self) -> RocketMQResult<()> {
91        Err(unsupported_legacy_api("MQPullConsumer", MODERN_LITE_PULL_CONSUMER))
92    }
93
94    fn shutdown(&self) -> RocketMQResult<()> {
95        Err(unsupported_legacy_api("MQPullConsumer", MODERN_LITE_PULL_CONSUMER))
96    }
97}
98
99impl MQPullConsumer for DefaultMQPullConsumer {}
100
101#[deprecated(
102    since = "0.9.0",
103    note = "Java DefaultMQPullConsumerImpl is deprecated; use DefaultLitePullConsumer"
104)]
105#[derive(Debug, Clone, Default)]
106pub struct DefaultMQPullConsumerImpl;
107
108impl DefaultMQPullConsumerImpl {
109    pub fn new() -> RocketMQResult<Self> {
110        Err(unsupported_legacy_api(
111            "DefaultMQPullConsumerImpl",
112            MODERN_LITE_PULL_CONSUMER,
113        ))
114    }
115
116    pub fn rebalance_impl(&self) -> RocketMQResult<RebalancePullImpl> {
117        Err(unsupported_legacy_api("RebalancePullImpl", MODERN_LITE_PULL_CONSUMER))
118    }
119}
120
121#[deprecated(
122    since = "0.9.0",
123    note = "Java MQPullConsumerScheduleService is deprecated; use DefaultLitePullConsumer"
124)]
125#[derive(Debug, Clone)]
126pub struct MQPullConsumerScheduleService {
127    consumer_group: CheetahString,
128}
129
130impl MQPullConsumerScheduleService {
131    pub fn new(consumer_group: impl Into<CheetahString>) -> Self {
132        Self {
133            consumer_group: consumer_group.into(),
134        }
135    }
136
137    pub fn consumer_group(&self) -> &CheetahString {
138        &self.consumer_group
139    }
140
141    pub fn start(&self) -> RocketMQResult<()> {
142        Err(unsupported_legacy_api(
143            "MQPullConsumerScheduleService",
144            MODERN_LITE_PULL_CONSUMER,
145        ))
146    }
147
148    pub fn shutdown(&self) -> RocketMQResult<()> {
149        Err(unsupported_legacy_api(
150            "MQPullConsumerScheduleService",
151            MODERN_LITE_PULL_CONSUMER,
152        ))
153    }
154
155    pub fn register_pull_task_callback<C>(
156        &mut self,
157        _topic: impl Into<CheetahString>,
158        _callback: C,
159    ) -> RocketMQResult<()>
160    where
161        C: PullTaskCallback,
162    {
163        Err(unsupported_legacy_api("PullTaskCallback", MODERN_LITE_PULL_CONSUMER))
164    }
165}
166
167#[deprecated(
168    since = "0.9.0",
169    note = "Java PullTaskCallback is deprecated with MQPullConsumerScheduleService"
170)]
171pub trait PullTaskCallback {
172    fn do_pull_task(&self, _message_queue: &MessageQueue, _context: &mut PullTaskContext) -> RocketMQResult<()> {
173        Err(unsupported_legacy_api("PullTaskCallback", MODERN_LITE_PULL_CONSUMER))
174    }
175}
176
177#[deprecated(
178    since = "0.9.0",
179    note = "Java PullTaskContext is deprecated with MQPullConsumerScheduleService"
180)]
181#[derive(Debug, Clone)]
182pub struct PullTaskContext {
183    pull_next_delay_time_millis: i32,
184}
185
186impl Default for PullTaskContext {
187    fn default() -> Self {
188        Self {
189            pull_next_delay_time_millis: 200,
190        }
191    }
192}
193
194impl PullTaskContext {
195    pub fn new() -> Self {
196        Self::default()
197    }
198
199    pub fn pull_next_delay_time_millis(&self) -> i32 {
200        self.pull_next_delay_time_millis
201    }
202
203    pub fn get_pull_next_delay_time_millis(&self) -> i32 {
204        self.pull_next_delay_time_millis()
205    }
206
207    pub fn set_pull_next_delay_time_millis(&mut self, pull_next_delay_time_millis: i32) {
208        self.pull_next_delay_time_millis = pull_next_delay_time_millis;
209    }
210
211    pub fn get_pull_consumer(&self) -> RocketMQResult<DefaultMQPullConsumer> {
212        Err(unsupported_legacy_api("MQPullConsumer", MODERN_LITE_PULL_CONSUMER))
213    }
214
215    pub fn set_pull_consumer<C>(&mut self, _pull_consumer: C) -> RocketMQResult<()>
216    where
217        C: MQPullConsumer,
218    {
219        Err(unsupported_legacy_api("MQPullConsumer", MODERN_LITE_PULL_CONSUMER))
220    }
221}
222
223#[deprecated(
224    since = "0.9.0",
225    note = "Java PullTaskImpl is deprecated; use DefaultLitePullConsumer"
226)]
227#[derive(Debug, Clone, Default)]
228pub struct PullTaskImpl {
229    message_queue: Option<MessageQueue>,
230}
231
232impl PullTaskImpl {
233    pub fn new(message_queue: MessageQueue) -> Self {
234        Self {
235            message_queue: Some(message_queue),
236        }
237    }
238
239    pub fn message_queue(&self) -> Option<&MessageQueue> {
240        self.message_queue.as_ref()
241    }
242
243    pub fn run(&self) -> RocketMQResult<()> {
244        Err(unsupported_legacy_api("PullTaskImpl", MODERN_LITE_PULL_CONSUMER))
245    }
246}
247
248#[deprecated(
249    since = "0.9.0",
250    note = "Java RebalancePullImpl is deprecated with DefaultMQPullConsumer"
251)]
252#[derive(Debug, Clone, Default)]
253pub struct RebalancePullImpl;
254
255impl RebalancePullImpl {
256    pub fn new() -> RocketMQResult<Self> {
257        Err(unsupported_legacy_api("RebalancePullImpl", MODERN_LITE_PULL_CONSUMER))
258    }
259}
260
261#[deprecated(since = "0.9.0", note = "Java MQHelper depends on DefaultMQPullConsumer")]
262#[derive(Debug, Clone, Default)]
263pub struct MQHelper;
264
265impl MQHelper {
266    pub fn reset_offset_by_timestamp(
267        _message_model: impl Into<CheetahString>,
268        _consumer_group: impl Into<CheetahString>,
269        _topic: impl Into<CheetahString>,
270        _timestamp: u64,
271    ) -> RocketMQResult<()> {
272        Err(unsupported_legacy_api("MQHelper", MODERN_LITE_PULL_CONSUMER))
273    }
274}
275
276#[deprecated(
277    since = "0.9.0",
278    note = "Java TransactionCheckListener is deprecated; use TransactionListener"
279)]
280pub trait TransactionCheckListener {
281    fn check_local_transaction_state(&self, _message: &MessageExt) -> RocketMQResult<LocalTransactionState> {
282        Err(unsupported_legacy_api(
283            "TransactionCheckListener",
284            MODERN_TRANSACTION_LISTENER,
285        ))
286    }
287}
288
289#[deprecated(
290    since = "0.9.0",
291    note = "Java OpenTracing hooks are not part of the modern RocketMQ client trace API"
292)]
293#[derive(Debug, Clone, Default)]
294pub struct SendMessageOpenTracingHookImpl;
295
296impl SendMessageOpenTracingHookImpl {
297    pub fn new<T>(_tracer: T) -> Self {
298        Self
299    }
300
301    pub fn hook_name(&self) -> &'static str {
302        "SendMessageOpenTracingHook"
303    }
304
305    pub fn unsupported(&self) -> RocketMQResult<()> {
306        Err(unsupported_legacy_api(
307            "SendMessageOpenTracingHookImpl",
308            MODERN_TRACE_HOOKS,
309        ))
310    }
311}
312
313#[deprecated(
314    since = "0.9.0",
315    note = "Java OpenTracing hooks are not part of the modern RocketMQ client trace API"
316)]
317#[derive(Debug, Clone, Default)]
318pub struct ConsumeMessageOpenTracingHookImpl;
319
320impl ConsumeMessageOpenTracingHookImpl {
321    pub fn new<T>(_tracer: T) -> Self {
322        Self
323    }
324
325    pub fn hook_name(&self) -> &'static str {
326        "ConsumeMessageOpenTracingHook"
327    }
328
329    pub fn unsupported(&self) -> RocketMQResult<()> {
330        Err(unsupported_legacy_api(
331            "ConsumeMessageOpenTracingHookImpl",
332            MODERN_TRACE_HOOKS,
333        ))
334    }
335}
336
337#[deprecated(
338    since = "0.9.0",
339    note = "Java OpenTracing hooks are not part of the modern RocketMQ client trace API"
340)]
341#[derive(Debug, Clone, Default)]
342pub struct EndTransactionOpenTracingHookImpl;
343
344impl EndTransactionOpenTracingHookImpl {
345    pub fn new<T>(_tracer: T) -> Self {
346        Self
347    }
348
349    pub fn hook_name(&self) -> &'static str {
350        "EndTransactionOpenTracingHook"
351    }
352
353    pub fn unsupported(&self) -> RocketMQResult<()> {
354        Err(unsupported_legacy_api(
355            "EndTransactionOpenTracingHookImpl",
356            MODERN_TRACE_HOOKS,
357        ))
358    }
359}
360
361#[derive(Debug, Clone, Default)]
362pub struct DoNothingClientRemotingProcessor;
363
364impl DoNothingClientRemotingProcessor {
365    pub fn new() -> Self {
366        Self
367    }
368
369    pub fn process_request(&self) -> Option<()> {
370        None
371    }
372}
373
374#[derive(Debug, Clone, Default)]
375pub struct RebalanceImpl;
376
377impl RebalanceImpl {
378    pub fn new() -> RocketMQResult<Self> {
379        Err(unsupported_impl_api("RebalanceImpl"))
380    }
381
382    pub fn do_rebalance(&self) -> RocketMQResult<()> {
383        Err(unsupported_impl_api("RebalanceImpl"))
384    }
385}
386
387#[derive(Debug, Clone, Default)]
388pub struct ConsumeRequest;
389
390impl ConsumeRequest {
391    pub fn new() -> Self {
392        Self
393    }
394
395    pub fn run(&self) -> RocketMQResult<()> {
396        Err(unsupported_impl_api("ConsumeRequest"))
397    }
398}
399
400#[cfg(test)]
401#[allow(deprecated)]
402mod tests {
403    use super::*;
404
405    #[test]
406    fn legacy_pull_consumer_returns_typed_unsupported_error() {
407        let consumer = DefaultMQPullConsumer::with_consumer_group("LegacyGroup");
408
409        assert_eq!(
410            consumer.consumer_group().map(|group| group.as_str()),
411            Some("LegacyGroup")
412        );
413        let error = consumer.start().expect_err("deprecated pull consumer should not start");
414
415        assert!(error.to_string().contains("DefaultMQPullConsumer"));
416        assert!(error.to_string().contains("DefaultLitePullConsumer"));
417    }
418
419    #[test]
420    fn pull_task_context_preserves_java_default_delay() {
421        let mut context = PullTaskContext::new();
422
423        assert_eq!(context.get_pull_next_delay_time_millis(), 200);
424        context.set_pull_next_delay_time_millis(500);
425        assert_eq!(context.pull_next_delay_time_millis(), 500);
426    }
427
428    #[test]
429    fn legacy_schedule_service_register_callback_returns_typed_error() {
430        struct Callback;
431        impl PullTaskCallback for Callback {}
432
433        let mut service = MQPullConsumerScheduleService::new("LegacyGroup");
434        let error = service
435            .register_pull_task_callback("TopicA", Callback)
436            .expect_err("deprecated schedule service should reject callbacks");
437
438        assert!(error.to_string().contains("PullTaskCallback"));
439        assert!(error.to_string().contains("DefaultLitePullConsumer"));
440    }
441
442    #[test]
443    fn legacy_open_tracing_hooks_keep_java_hook_names() {
444        assert_eq!(
445            SendMessageOpenTracingHookImpl::new(()).hook_name(),
446            "SendMessageOpenTracingHook"
447        );
448        assert_eq!(
449            ConsumeMessageOpenTracingHookImpl::new(()).hook_name(),
450            "ConsumeMessageOpenTracingHook"
451        );
452        assert_eq!(
453            EndTransactionOpenTracingHookImpl::new(()).hook_name(),
454            "EndTransactionOpenTracingHook"
455        );
456    }
457
458    #[test]
459    fn transaction_check_listener_returns_typed_unsupported_error() {
460        struct Listener;
461        impl TransactionCheckListener for Listener {}
462
463        let error = Listener
464            .check_local_transaction_state(&MessageExt::default())
465            .expect_err("deprecated transaction listener should reject checks");
466
467        assert!(error.to_string().contains("TransactionCheckListener"));
468        assert!(error.to_string().contains("TransactionListener"));
469    }
470
471    #[test]
472    fn impl_package_markers_do_not_panic() {
473        assert!(DoNothingClientRemotingProcessor::new().process_request().is_none());
474
475        let rebalance_error = RebalanceImpl::new().expect_err("impl-package RebalanceImpl should be unsupported");
476        assert!(rebalance_error.to_string().contains("impl-package type"));
477
478        let consume_error = ConsumeRequest::new()
479            .run()
480            .expect_err("impl-package ConsumeRequest should be unsupported");
481        assert!(consume_error.to_string().contains("ConsumeRequest"));
482    }
483}