rnacos/openapi/naming/
model.rs

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        /*
145        let mut clusters = vec![];
146        if let Some(cluster_str) = self.clusters.as_ref() {
147            clusters = cluster_str.split(",").into_iter()
148                .filter(|e|{e.len()>0}).map(|e|{e.to_owned()}).collect::<Vec<_>>();
149        }
150        */
151        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    /*
204    pub fn convert_to_instance_old(self) -> Result<Instance, String> {
205        let beat = match self.beat {
206            Some(v) => v,
207            None => {
208                return Err("beat value is empty".to_string());
209            }
210        };
211        let beat_info = match serde_json::from_str::<BeatInfo>(&beat) {
212            Ok(v) => v,
213            Err(err) => {
214                return Err(err.to_string());
215            }
216        };
217        let service_name_option = beat_info.service_name.clone();
218        let mut instance = beat_info.convert_to_instance();
219        if service_name_option.is_none() {
220            let grouped_name = self.service_name.unwrap();
221            if let Some((group_name, service_name)) =
222                NamingUtils::split_group_and_service_name(&grouped_name)
223            {
224                instance.service_name = Arc::new(service_name);
225                instance.group_name = Arc::new(group_name);
226            }
227            if let Some(group_name) = self.group_name.as_ref() {
228                if !group_name.is_empty() {
229                    instance.group_name = Arc::new(group_name.to_owned());
230                }
231            }
232        }
233        instance.ephemeral = get_bool_from_string(&self.ephemeral, true);
234        instance.cluster_name = NamingUtils::default_cluster(
235            self.cluster_name
236                .as_ref()
237                .unwrap_or(&"".to_owned())
238                .to_owned(),
239        );
240        instance.namespace_id = Arc::new(NamingUtils::default_namespace(
241            self.namespace_id
242                .as_ref()
243                .unwrap_or(&"".to_owned())
244                .to_owned(),
245        ));
246        instance.generate_key();
247        Ok(instance)
248    }
249    */
250
251    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.generate_key();
336        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}