rnacos/naming/
api_model.rs

1use crate::now_millis_i64;
2
3use super::model::{Instance, ServiceDetailDto, ServiceKey};
4use super::NamingUtils;
5use crate::common::option_utils::OptionUtils;
6use chrono::Local;
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9use std::sync::Arc;
10
11#[derive(Debug, Serialize, Deserialize, Default)]
12#[serde(rename_all = "camelCase")]
13pub struct QueryListResult {
14    pub name: String,
15    pub clusters: String,
16    pub cache_millis: u64,
17    pub hosts: Vec<InstanceVO>,
18    pub last_ref_time: Option<i64>,
19    pub checksum: Option<String>,
20    #[serde(rename = "useSpecifiedURL")]
21    pub use_specified_url: Option<bool>,
22    pub env: Option<String>,
23    pub protect_threshold: Option<f32>,
24    pub reach_local_site_call_threshold: Option<bool>,
25    pub dom: Option<Arc<String>>,
26    pub metadata: Option<HashMap<String, String>>,
27}
28
29impl QueryListResult {
30    pub fn get_instance_list_string(
31        clusters: String,
32        key: &ServiceKey,
33        v: Vec<Arc<Instance>>,
34    ) -> String {
35        let now = now_millis_i64();
36        let result = Self {
37            name: key.get_join_service_name(),
38            cache_millis: 10000u64,
39            last_ref_time: Some(now),
40            checksum: Some(now.to_string()),
41            use_specified_url: Some(false),
42            clusters,
43            env: Some("".to_owned()),
44            hosts: v
45                .into_iter()
46                .map(|e| InstanceVO::from_instance(&e))
47                .collect::<Vec<_>>(),
48            dom: Some(key.service_name.to_owned()),
49            ..Default::default()
50        };
51        serde_json::to_string(&result).unwrap()
52    }
53
54    pub fn get_ref_instance_list_string(
55        clusters: String,
56        key: &ServiceKey,
57        v: Vec<&Arc<Instance>>,
58    ) -> String {
59        let now = Local::now().timestamp_millis();
60        let result = QueryListResult {
61            name: key.get_join_service_name(),
62            cache_millis: 10000u64,
63            last_ref_time: Some(now - 1000),
64            checksum: Some(now.to_string()),
65            use_specified_url: Some(false),
66            clusters,
67            env: Some("".to_owned()),
68            hosts: v
69                .into_iter()
70                .map(|e| InstanceVO::from_instance(e))
71                .collect::<Vec<_>>(),
72            dom: Some(key.service_name.to_owned()),
73            ..Default::default()
74        };
75        serde_json::to_string(&result).unwrap()
76    }
77}
78
79#[derive(Debug, Serialize, Deserialize, Default)]
80#[serde(rename_all = "camelCase")]
81pub struct InstanceVO {
82    pub service: Arc<String>,
83    pub ip: Arc<String>,
84    pub port: u32,
85    pub cluster_name: String,
86    pub weight: f32,
87    pub healthy: bool,
88    pub instance_id: Arc<String>,
89    pub metadata: Arc<HashMap<String, String>>,
90    pub marked: Option<bool>,
91    pub enabled: Option<bool>,
92    pub service_name: Option<Arc<String>>,
93    pub ephemeral: Option<bool>,
94}
95
96impl InstanceVO {
97    pub fn from_instance(instance: &Instance) -> Self {
98        Self {
99            service: instance.group_service.clone(),
100            ip: instance.ip.clone(),
101            port: instance.port,
102            cluster_name: instance.cluster_name.to_owned(),
103            weight: instance.weight,
104            healthy: instance.healthy,
105            instance_id: instance.id.clone(),
106            metadata: instance.metadata.clone(),
107            marked: Some(true),
108            enabled: Some(instance.enabled),
109            //service_name: Some(instance.service_name.clone()),
110            service_name: Some(instance.group_service.clone()),
111            ephemeral: Some(instance.ephemeral),
112        }
113    }
114}
115
116#[derive(Debug, Serialize, Deserialize, Default)]
117#[serde(rename_all = "camelCase")]
118pub struct ServiceQueryOptListRequest {
119    pub page_no: Option<usize>,
120    pub page_size: Option<usize>,
121    pub namespace_id: Option<String>,
122    pub group_name: Option<String>,
123    pub service_name: Option<String>,
124}
125
126#[derive(Debug, Serialize, Deserialize, Default)]
127#[serde(rename_all = "camelCase")]
128pub struct ServiceInfoParam {
129    pub namespace_id: Option<String>,
130    pub group_name: Option<String>,
131    pub service_name: Option<String>,
132    pub protect_threshold: Option<f32>,
133    pub metadata: Option<String>,
134    pub selector: Option<String>,
135}
136
137impl ServiceInfoParam {
138    pub(crate) fn merge(self, b: Self) -> Self {
139        Self {
140            namespace_id: OptionUtils::select(self.namespace_id, b.namespace_id),
141            group_name: OptionUtils::select(self.group_name, b.group_name),
142            service_name: OptionUtils::select(self.service_name, b.service_name),
143            protect_threshold: OptionUtils::select(self.protect_threshold, b.protect_threshold),
144            metadata: OptionUtils::select(self.metadata, b.metadata),
145            selector: OptionUtils::select(self.selector, b.selector),
146        }
147    }
148
149    pub(crate) fn build_service_info(self) -> anyhow::Result<ServiceDetailDto> {
150        if let Some(service_name) = self.service_name {
151            if service_name.is_empty() {
152                return Err(anyhow::anyhow!("service_name is valid"));
153            }
154            let metadata = if let Some(metadata_str) = self.metadata {
155                match NamingUtils::parse_metadata(&metadata_str) {
156                    Ok(metadata) => Some(Arc::new(metadata)),
157                    Err(_) => None,
158                }
159            } else {
160                None
161            };
162
163            Ok(ServiceDetailDto {
164                namespace_id: Arc::new(NamingUtils::default_namespace(
165                    self.namespace_id.unwrap_or_default(),
166                )),
167                service_name: Arc::new(service_name),
168                group_name: Arc::new(NamingUtils::default_group(
169                    self.group_name.unwrap_or_default(),
170                )),
171                metadata,
172                protect_threshold: self.protect_threshold,
173                ..Default::default()
174            })
175        } else {
176            Err(anyhow::anyhow!("service_name is empty"))
177        }
178    }
179}