rocketmq_client_rust/admin/
default_mq_admin_ext.rs1use std::ops::Deref;
16use std::ops::DerefMut;
17use std::sync::Arc;
18use std::time::Duration;
19
20use cheetah_string::CheetahString;
21use rocketmq_transport::api::RPCHook;
22
23use crate::admin::default_mq_admin_ext_impl::DefaultMQAdminExtImpl;
24#[cfg(all(feature = "admin-read", not(feature = "admin-mutation")))]
25use crate::admin::mq_admin_read_ext::MQAdminReadExt;
26use crate::base::client_config::ClientConfig;
27use crate::runtime::ClientRuntime;
28use crate::session::ClientSession;
29use crate::session::ClientSessionProvider;
30
31const ADMIN_EXT_GROUP: &str = "admin_ext_group";
32const DEFAULT_TIMEOUT_MILLIS: u64 = 5000;
33
34pub struct DefaultMQAdminExt {
41 session: ClientSession,
42 default_mqadmin_ext_impl: DefaultMQAdminExtImpl,
43}
44
45impl DefaultMQAdminExt {
46 fn build(
47 client_runtime: Arc<ClientRuntime>,
48 client_config: ClientConfig,
49 admin_ext_group: CheetahString,
50 timeout_millis: Duration,
51 rpc_hook: Option<Arc<dyn RPCHook>>,
52 ) -> Self {
53 let default_mqadmin_ext_impl = DefaultMQAdminExtImpl::new(
54 Arc::clone(&client_runtime),
55 rpc_hook,
56 timeout_millis,
57 client_config,
58 admin_ext_group,
59 );
60
61 Self {
62 session: ClientSession::new(client_runtime),
63 default_mqadmin_ext_impl,
64 }
65 }
66
67 pub fn new(client_runtime: Arc<ClientRuntime>) -> Self {
68 Self::with_admin_ext_group(client_runtime, ADMIN_EXT_GROUP)
69 }
70
71 pub fn client_runtime(&self) -> Arc<ClientRuntime> {
73 self.session.runtime()
74 }
75
76 pub fn with_timeout(client_runtime: Arc<ClientRuntime>, timeout_millis: Duration) -> Self {
77 let client_config = ClientConfig::new();
78 Self::build(
79 client_runtime,
80 client_config,
81 CheetahString::from_static_str(ADMIN_EXT_GROUP),
82 timeout_millis,
83 None,
84 )
85 }
86
87 pub fn with_rpc_hook(client_runtime: Arc<ClientRuntime>, rpc_hook: Arc<dyn RPCHook>) -> Self {
88 Self::with_rpc_hook_and_timeout(client_runtime, rpc_hook, Duration::from_millis(DEFAULT_TIMEOUT_MILLIS))
89 }
90
91 pub fn with_rpc_hook_and_timeout(
92 client_runtime: Arc<ClientRuntime>,
93 rpc_hook: Arc<dyn RPCHook>,
94 timeout_millis: Duration,
95 ) -> Self {
96 let client_config = ClientConfig::new();
97 Self::build(
98 client_runtime,
99 client_config,
100 CheetahString::from_static_str(ADMIN_EXT_GROUP),
101 timeout_millis,
102 Some(rpc_hook),
103 )
104 }
105
106 pub fn with_admin_ext_group(client_runtime: Arc<ClientRuntime>, admin_ext_group: impl Into<CheetahString>) -> Self {
107 let client_config = ClientConfig::new();
108 Self::build(
109 client_runtime,
110 client_config,
111 admin_ext_group.into(),
112 Duration::from_millis(DEFAULT_TIMEOUT_MILLIS),
113 None,
114 )
115 }
116
117 pub fn with_admin_ext_group_and_timeout(
118 client_runtime: Arc<ClientRuntime>,
119 admin_ext_group: impl Into<CheetahString>,
120 timeout_millis: Duration,
121 ) -> Self {
122 let client_config = ClientConfig::new();
123 Self::build(
124 client_runtime,
125 client_config,
126 admin_ext_group.into(),
127 timeout_millis,
128 None,
129 )
130 }
131
132 pub fn with_admin_ext_group_and_rpc_hook(
133 client_runtime: Arc<ClientRuntime>,
134 admin_ext_group: impl Into<CheetahString>,
135 rpc_hook: Arc<dyn RPCHook>,
136 ) -> Self {
137 let client_config = ClientConfig::new();
138 Self::build(
139 client_runtime,
140 client_config,
141 admin_ext_group.into(),
142 Duration::from_millis(DEFAULT_TIMEOUT_MILLIS),
143 Some(rpc_hook),
144 )
145 }
146
147 pub fn with_admin_ext_group_rpc_hook_and_timeout(
148 client_runtime: Arc<ClientRuntime>,
149 admin_ext_group: impl Into<CheetahString>,
150 rpc_hook: Arc<dyn RPCHook>,
151 timeout_millis: Duration,
152 ) -> Self {
153 let client_config = ClientConfig::new();
154 Self::build(
155 client_runtime,
156 client_config,
157 admin_ext_group.into(),
158 timeout_millis,
159 Some(rpc_hook),
160 )
161 }
162
163 pub fn set_namesrv_addr(&mut self, name_serv_addr: impl Into<CheetahString>) {
164 self.default_mqadmin_ext_impl
165 .client_config_mut()
166 .set_namesrv_addr(name_serv_addr.into());
167 }
168
169 #[inline]
170 pub fn is_use_tls(&self) -> bool {
171 self.default_mqadmin_ext_impl.is_use_tls()
172 }
173
174 #[inline]
175 pub fn set_use_tls(&mut self, use_tls: bool) {
176 self.default_mqadmin_ext_impl.set_use_tls(use_tls);
177 }
178
179 #[inline]
180 pub fn client_config(&self) -> &ClientConfig {
181 self.default_mqadmin_ext_impl.client_config()
182 }
183
184 #[inline]
185 pub fn client_config_mut(&mut self) -> &mut ClientConfig {
186 self.default_mqadmin_ext_impl.client_config_mut()
187 }
188
189 #[inline]
190 pub fn inner(&self) -> &DefaultMQAdminExtImpl {
191 &self.default_mqadmin_ext_impl
192 }
193
194 #[inline]
195 pub fn inner_mut(&mut self) -> &mut DefaultMQAdminExtImpl {
196 &mut self.default_mqadmin_ext_impl
197 }
198
199 #[inline]
200 pub fn has_inner(&self) -> bool {
201 self.default_mqadmin_ext_impl.has_inner()
202 }
203
204 #[cfg(any(feature = "admin-read", feature = "admin-mutation"))]
205 pub async fn start(&mut self) -> crate::ClientResult<()> {
206 #[cfg(feature = "admin-mutation")]
207 {
208 return self.default_mqadmin_ext_impl.start_admin().await;
209 }
210 #[cfg(all(feature = "admin-read", not(feature = "admin-mutation")))]
211 {
212 MQAdminReadExt::start(self).await
213 }
214 }
215
216 #[cfg(any(feature = "admin-read", feature = "admin-mutation"))]
217 pub async fn shutdown(&mut self) {
218 #[cfg(feature = "admin-mutation")]
219 {
220 self.default_mqadmin_ext_impl.shutdown_admin().await;
221 }
222 #[cfg(all(feature = "admin-read", not(feature = "admin-mutation")))]
223 {
224 MQAdminReadExt::shutdown(self).await;
225 }
226 }
227}
228
229impl ClientSessionProvider for DefaultMQAdminExt {
230 fn client_session(&self) -> Option<&ClientSession> {
231 Some(&self.session)
232 }
233}
234
235impl AsRef<DefaultMQAdminExtImpl> for DefaultMQAdminExt {
236 fn as_ref(&self) -> &DefaultMQAdminExtImpl {
237 &self.default_mqadmin_ext_impl
238 }
239}
240
241impl AsMut<DefaultMQAdminExtImpl> for DefaultMQAdminExt {
242 fn as_mut(&mut self) -> &mut DefaultMQAdminExtImpl {
243 &mut self.default_mqadmin_ext_impl
244 }
245}
246
247impl Deref for DefaultMQAdminExt {
248 type Target = DefaultMQAdminExtImpl;
249
250 fn deref(&self) -> &Self::Target {
251 &self.default_mqadmin_ext_impl
252 }
253}
254
255impl DerefMut for DefaultMQAdminExt {
256 fn deref_mut(&mut self) -> &mut Self::Target {
257 &mut self.default_mqadmin_ext_impl
258 }
259}
260
261#[cfg(all(test, feature = "admin-full"))]
262mod tests {
263 use std::time::Duration;
264
265 use cheetah_string::CheetahString;
266
267 use crate::admin::capability::RouteAdmin;
268
269 use super::DefaultMQAdminExt;
270
271 fn test_runtime() -> std::sync::Arc<crate::runtime::ClientRuntime> {
272 crate::runtime::test_client_runtime("default-admin-ext-test")
273 }
274
275 #[test]
276 fn constructors_initialize_owned_inner_impl() {
277 let default_admin = DefaultMQAdminExt::new(test_runtime());
278 assert!(default_admin.has_inner());
279 assert!(default_admin.inner().has_inner());
280
281 let timed_admin = DefaultMQAdminExt::with_timeout(test_runtime(), Duration::from_secs(3));
282 assert!(timed_admin.has_inner());
283
284 let grouped_admin = DefaultMQAdminExt::with_admin_ext_group(test_runtime(), "admin-public-api-test");
285 assert!(grouped_admin.has_inner());
286
287 let grouped_timed_admin = DefaultMQAdminExt::with_admin_ext_group_and_timeout(
288 test_runtime(),
289 "admin-public-api-test",
290 Duration::from_secs(3),
291 );
292 assert!(grouped_timed_admin.has_inner());
293 }
294
295 #[test]
296 fn namesrv_addr_updates_shared_client_config_before_start() {
297 let mut admin = DefaultMQAdminExt::new(test_runtime());
298 admin.set_namesrv_addr("127.0.0.1:9876");
299
300 assert_eq!(
301 admin.client_config().get_namesrv_addr().as_deref(),
302 Some("127.0.0.1:9876")
303 );
304 }
305
306 #[test]
307 fn use_tls_updates_shared_admin_client_config_before_start() {
308 let mut admin = DefaultMQAdminExt::new(test_runtime());
309
310 assert!(!admin.is_use_tls());
311 assert!(!admin.inner().is_use_tls());
312
313 admin.set_use_tls(true);
314
315 assert!(admin.is_use_tls());
316 assert!(admin.client_config().is_use_tls());
317 assert!(admin.inner().is_use_tls());
318 }
319
320 #[tokio::test]
321 async fn deref_exposes_impl_admin_trait_methods_without_panicking() {
322 let admin = DefaultMQAdminExt::new(test_runtime());
323
324 let error = admin
325 .get_kv_config(CheetahString::from("namespace"), CheetahString::from("key"))
326 .await
327 .expect_err("unstarted admin should return a typed error instead of panicking");
328
329 assert!(error.is(&rocketmq_error::CLIENT_LIFECYCLE_NOT_STARTED));
330 }
331}