1#![allow(unused_imports, unused_assignments, unused_variables)]
2use crate::common::option_utils::OptionUtils;
3use crate::naming::model::{Instance, ServiceKey};
4use crate::naming::service::SubscriberInfoDto;
5use crate::naming::NamingUtils;
6use crate::utils::get_bool_from_string;
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9use std::net::SocketAddr;
10use std::sync::Arc;
11
12#[derive(Debug, Serialize, Deserialize)]
13#[serde(rename_all = "camelCase")]
14pub struct InstanceWebParams {
15 pub ip: Option<String>,
16 pub port: Option<u32>,
17 pub namespace_id: Option<String>,
18 pub weight: Option<f32>,
19 pub enabled: Option<String>,
20 pub healthy: Option<String>,
21 pub ephemeral: Option<String>,
22 pub metadata: Option<String>,
23 pub cluster_name: Option<String>,
24 pub service_name: Option<String>,
25 pub group_name: Option<String>,
26}
27
28impl InstanceWebParams {
29 pub(crate) fn merge(self, o: Self) -> Self {
30 Self {
31 ip: OptionUtils::select(self.ip, o.ip),
32 port: OptionUtils::select(self.port, o.port),
33 namespace_id: OptionUtils::select(self.namespace_id, o.namespace_id),
34 weight: OptionUtils::select(self.weight, o.weight),
35 enabled: OptionUtils::select(self.enabled, o.enabled),
36 healthy: OptionUtils::select(self.healthy, o.healthy),
37 ephemeral: OptionUtils::select(self.ephemeral, o.ephemeral),
38 metadata: OptionUtils::select(self.metadata, o.metadata),
39 cluster_name: OptionUtils::select(self.cluster_name, o.cluster_name),
40 service_name: OptionUtils::select(self.service_name, o.service_name),
41 group_name: OptionUtils::select(self.group_name, o.group_name),
42 }
43 }
44
45 pub(crate) fn convert_to_instance(self) -> Result<Instance, String> {
46 let ip = if let Some(ip) = self.ip {
47 Arc::new(ip)
48 } else {
49 return Err("the instance ip is None".to_string());
50 };
51 let port = if let Some(port) = self.port {
52 port
53 } else {
54 return Err("the instance port is None".to_string());
55 };
56 let mut instance = Instance {
57 ip,
58 port,
59 weight: self.weight.unwrap_or(1f32),
60 enabled: get_bool_from_string(&self.enabled, true),
61 healthy: true,
62 ephemeral: get_bool_from_string(&self.ephemeral, true),
63 cluster_name: NamingUtils::default_cluster(
64 self.cluster_name
65 .as_ref()
66 .unwrap_or(&"".to_owned())
67 .to_owned(),
68 ),
69 namespace_id: Arc::new(NamingUtils::default_namespace(
70 self.namespace_id
71 .as_ref()
72 .unwrap_or(&"".to_owned())
73 .to_owned(),
74 )),
75 ..Default::default()
76 };
77
78 let grouped_name = self.service_name.unwrap_or_default();
79 if let Some((group_name, service_name)) =
80 NamingUtils::split_group_and_service_name(&grouped_name)
81 {
82 instance.service_name = Arc::new(service_name);
83 instance.group_name = Arc::new(group_name);
84 } else {
85 return Err("serviceName is invalid!".to_owned());
86 }
87 if let Some(group_name) = self.group_name {
88 if !group_name.is_empty() {
89 instance.group_name = Arc::new(group_name);
90 }
91 }
92 let metadata_str = self
93 .metadata
94 .as_ref()
95 .unwrap_or(&"{}".to_owned())
96 .to_owned();
97 if let Ok(metadata) = NamingUtils::parse_metadata(&metadata_str) {
98 instance.metadata = Arc::new(metadata);
99 };
100 instance.generate_key();
101 Ok(instance)
102 }
103}
104
105#[derive(Debug, Serialize, Deserialize)]
106#[serde(rename_all = "camelCase")]
107pub struct InstanceWebQueryListParams {
108 pub namespace_id: Option<String>,
109 pub service_name: Option<String>,
110 pub group_name: Option<String>,
111 pub clusters: Option<String>,
112 pub healthy_only: Option<String>,
113 #[serde(rename = "clientIP")]
114 pub client_ip: Option<String>,
115 pub udp_port: Option<String>,
116}
117
118impl InstanceWebQueryListParams {
119 pub(crate) fn to_clusters_key(&self) -> Result<(ServiceKey, String), String> {
120 let mut service_name = "".to_owned();
121 let mut group_name = "".to_owned();
122 let grouped_name = self.service_name.clone().unwrap_or_default();
123 if let Some((_group_name, _service_name)) =
124 NamingUtils::split_group_and_service_name(&grouped_name)
125 {
126 service_name = _service_name;
127 group_name = _group_name;
128 } else {
129 return Err("serviceName is invalid!".to_owned());
130 }
131 if let Some(_group_name) = self.group_name.as_ref() {
132 if !_group_name.is_empty() {
133 _group_name.clone_into(&mut group_name)
134 }
135 }
136 let namespace_id = NamingUtils::default_namespace(
137 self.namespace_id
138 .as_ref()
139 .unwrap_or(&"".to_owned())
140 .to_owned(),
141 );
142 let key = ServiceKey::new(&namespace_id, &group_name, &service_name);
143
144 Ok((
152 key,
153 self.clusters.as_ref().unwrap_or(&"".to_owned()).to_owned(),
154 ))
155 }
156
157 pub(crate) fn get_addr(&self) -> Option<SocketAddr> {
158 let port: Option<u16> = self
159 .udp_port
160 .as_ref()
161 .map(|e| e.parse().unwrap_or_default());
162 if let Some(port) = &port {
163 if *port == 0u16 {
164 return None;
165 }
166 if let Some(ip_str) = &self.client_ip {
167 if let Ok(ip) = ip_str.parse() {
168 return Some(SocketAddr::new(ip, *port));
169 }
170 }
171 }
172 None
173 }
174}
175
176#[derive(Debug, Serialize, Deserialize, Default)]
177#[serde(rename_all = "camelCase")]
178pub struct BeatRequest {
179 pub namespace_id: Option<String>,
180 pub service_name: Option<String>,
181 pub cluster_name: Option<String>,
182 pub group_name: Option<String>,
183 pub ephemeral: Option<String>,
184 pub beat: Option<String>,
185 pub ip: Option<String>,
186 pub port: Option<u32>,
187}
188
189impl BeatRequest {
190 pub(crate) fn merge(self, o: Self) -> Self {
191 Self {
192 namespace_id: OptionUtils::select(self.namespace_id, o.namespace_id),
193 cluster_name: OptionUtils::select(self.cluster_name, o.cluster_name),
194 service_name: OptionUtils::select(self.service_name, o.service_name),
195 group_name: OptionUtils::select(self.group_name, o.group_name),
196 ephemeral: OptionUtils::select(self.ephemeral, o.ephemeral),
197 beat: OptionUtils::select(self.beat, o.beat),
198 ip: OptionUtils::select(self.ip, o.ip),
199 port: OptionUtils::select(self.port, o.port),
200 }
201 }
202
203 pub fn convert_to_instance(self) -> anyhow::Result<Instance> {
252 let mut beat_info = self.get_beat_info()?;
253 let use_beat = self.beat.as_ref().is_some_and(|s| !s.is_empty());
254 if !use_beat {
255 beat_info.ip = self.ip;
256 beat_info.port = self.port;
257 }
258 if beat_info.ip.is_none() || beat_info.port.is_none() {
259 return Err(anyhow::anyhow!("ip or port is empty".to_owned()));
260 }
261 let service_name_option = beat_info.service_name.clone();
262 let mut instance = beat_info.convert_to_instance();
263 if service_name_option.is_none() {
264 if let Some(grouped_name) = self.service_name {
265 if let Some((group_name, service_name)) =
266 NamingUtils::split_group_and_service_name(&grouped_name)
267 {
268 instance.service_name = Arc::new(service_name);
269 instance.group_name = Arc::new(group_name);
270 }
271 } else {
272 return Err(anyhow::anyhow!("service name is empty".to_owned()));
273 }
274 if let Some(group_name) = self.group_name {
275 if !group_name.is_empty() {
276 instance.group_name = Arc::new(group_name);
277 }
278 }
279 }
280 instance.ephemeral = get_bool_from_string(&self.ephemeral, true);
281 instance.cluster_name = NamingUtils::default_cluster(self.cluster_name.unwrap_or_default());
282 instance.namespace_id = Arc::new(NamingUtils::default_namespace(
283 self.namespace_id.unwrap_or_default(),
284 ));
285 instance.generate_key();
286 Ok(instance)
287 }
288
289 fn get_beat_info(&self) -> anyhow::Result<BeatInfo> {
290 let beat_str = self.beat.clone().unwrap_or_default();
291 if let Some(beat_str) = self.beat.as_ref() {
292 let v = serde_json::from_str::<BeatInfo>(beat_str)?;
293 Ok(v)
294 } else {
295 Ok(BeatInfo::default())
296 }
297 }
298}
299
300#[derive(Debug, Serialize, Deserialize, Default)]
301#[serde(rename_all = "camelCase")]
302pub struct BeatInfo {
303 pub cluster: Option<String>,
304 pub ip: Option<String>,
305 pub port: Option<u32>,
306 pub metadata: Option<HashMap<String, String>>,
307 pub period: Option<i64>,
308 pub scheduled: Option<bool>,
309 pub service_name: Option<String>,
310 pub stopped: Option<bool>,
311 pub weight: Option<f32>,
312}
313
314impl BeatInfo {
315 pub fn convert_to_instance(self) -> Instance {
316 let mut instance = Instance {
317 ip: Arc::new(self.ip.unwrap_or("unknown".to_string())),
318 port: self.port.unwrap_or(1),
319 cluster_name: NamingUtils::default_cluster(
320 self.cluster.as_ref().unwrap_or(&"".to_owned()).to_owned(),
321 ),
322 ..Default::default()
323 };
324 if let Some(grouped_name) = self.service_name.as_ref() {
325 if let Some((group_name, service_name)) =
326 NamingUtils::split_group_and_service_name(grouped_name)
327 {
328 instance.service_name = Arc::new(service_name);
329 instance.group_name = Arc::new(group_name);
330 }
331 }
332 if let Some(metadata) = self.metadata {
333 instance.metadata = Arc::new(metadata);
334 }
335 instance
337 }
338}
339
340#[derive(Debug, Serialize, Deserialize, Default)]
341#[serde(rename_all = "camelCase")]
342pub struct ServiceQueryListRequest {
343 pub page_no: Option<usize>,
344 pub page_size: Option<usize>,
345 pub namespace_id: Option<String>,
346 pub group_name: Option<String>,
347 pub service_name: Option<String>,
348}
349
350#[derive(Debug, Serialize, Deserialize, Default)]
351pub struct ServiceQueryListResponce {
352 pub count: usize,
353 pub doms: Vec<Arc<String>>,
354}
355
356#[derive(Debug, Serialize, Deserialize, Default)]
357pub struct ServiceQuerySubscribersListResponce {
358 pub count: usize,
359 pub subscribers: Vec<SubscriberInfoDto>,
360}