rocketmq_client_rust/implementation/mq_client_api_impl/
route.rs1use super::route_error::route_lookup_error;
16use super::*;
17
18pub struct RouteClient<'a> {
19 api: &'a MQClientAPIImpl,
20}
21
22impl RouteClient<'_> {
23 pub async fn topic_route_info(
24 &self,
25 topic: &CheetahString,
26 timeout_millis: u64,
27 ) -> crate::ClientResult<Option<TopicRouteData>> {
28 self.api
29 .get_topic_route_info_from_name_server(topic, timeout_millis)
30 .await
31 }
32}
33
34impl MQClientAPIImpl {
35 #[must_use]
36 pub fn route_client(&self) -> RouteClient<'_> {
37 RouteClient { api: self }
38 }
39}
40
41impl MQClientAPIImpl {
42 #[inline]
43 pub async fn get_default_topic_route_info_from_name_server(
44 &self,
45 timeout_millis: u64,
46 ) -> crate::ClientResult<Option<TopicRouteData>> {
47 self.get_topic_route_info_from_name_server_detail(
48 TopicValidator::AUTO_CREATE_TOPIC_KEY_TOPIC,
49 timeout_millis,
50 false,
51 )
52 .await
53 }
54
55 #[inline]
56 pub async fn get_topic_route_info_from_name_server(
57 &self,
58 topic: &str,
59 timeout_millis: u64,
60 ) -> crate::ClientResult<Option<TopicRouteData>> {
61 self.get_topic_route_info_from_name_server_detail(topic, timeout_millis, true)
62 .await
63 }
64
65 #[inline]
66 pub async fn get_topic_route_info_from_name_server_detail(
67 &self,
68 topic: &str,
69 timeout_millis: u64,
70 allow_topic_not_exist: bool,
71 ) -> crate::ClientResult<Option<TopicRouteData>> {
72 let deadline = RequestDeadline::from_timeout_millis(timeout_millis);
73 self.get_topic_route_info_once(topic, deadline, allow_topic_not_exist)
74 .await
75 .map_err(route_lookup_error)
76 }
77
78 pub(crate) async fn get_topic_route_info_once(
79 &self,
80 topic: &str,
81 deadline: RequestDeadline,
82 allow_topic_not_exist: bool,
83 ) -> Result<Option<TopicRouteData>, RetryInput> {
84 let request_header = GetRouteInfoRequestHeader {
85 topic: CheetahString::from_slice(topic),
86 accept_standard_json_only: None,
87 topic_request_header: None,
88 };
89 let request = self.create_request_command(RequestCode::GetRouteinfoByTopic, request_header);
90 let outcome = self
91 .remoting_client
92 .invoke_request_with_deadline(None, request, deadline)
93 .await
94 .map_err(RetryInput::Transport)?;
95 match outcome {
96 OutboundRequestOutcome::Response(mut result) => {
97 let code = result.code();
98 let response_code = ResponseCode::from(code);
99 match response_code {
100 ResponseCode::Success => {
101 let body = result.take_body();
102 if let Some(body_inner) = body {
103 let route_data = TopicRouteData::decode(body_inner.as_ref()).map_err(RetryInput::from)?;
104 return Ok(Some(route_data));
105 }
106 }
107 ResponseCode::TopicNotExist => {
108 if allow_topic_not_exist {
109 warn!("get Topic [{}] RouteInfoFromNameServer is not exist value", topic);
110 return Ok(None);
111 }
112 }
113 _ => {
114 return Err(RetryInput::Response {
115 code,
116 retry_after: None,
117 terminal_error: mq_client_err!(
118 code,
119 result.remark().cloned().unwrap_or_default().to_string()
120 ),
121 });
122 }
123 }
124 Err(RetryInput::Response {
125 code,
126 retry_after: None,
127 terminal_error: mq_client_err!(code, result.remark().cloned().unwrap_or_default().to_string()),
128 })
129 }
130 OutboundRequestOutcome::Rejected(rejection) => Err(RetryInput::Rejected(rejection)),
131 OutboundRequestOutcome::Contract(contract) => Err(RetryInput::Contract(contract)),
132 }
133 }
134
135 pub(crate) async fn get_default_topic_route_info_once(
136 &self,
137 deadline: RequestDeadline,
138 ) -> Result<Option<TopicRouteData>, RetryInput> {
139 self.get_topic_route_info_once(TopicValidator::AUTO_CREATE_TOPIC_KEY_TOPIC, deadline, false)
140 .await
141 }
142
143 pub fn get_name_server_address_list(&self) -> Vec<CheetahString> {
144 self.remoting_client.get_name_server_address_list()
145 }
146}