apisix_admin_client/models/
admin_upstream_requests.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use strum_macros::{Display, EnumString};
4use crate::models::generate_identifier;
5use crate::{Result};
6use crate::models::common::ApisixTimeout;
7
8#[serde_with::skip_serializing_none]
9#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
10pub struct UpstreamBuilder {
11 pub id: Option<String>,
12 pub retries: Option<i32>,
13 pub retry_timeout: Option<i32>,
14 pub timeout: Option<ApisixTimeout>,
15 pub nodes: Option<Value>,
16 pub service_name: Option<String>,
17 pub discovery_type: Option<String>,
18 #[serde(rename = "type")]
19 pub type_field: Option<UpstreamType>,
20 pub name: Option<String>,
21 pub desc: Option<String>,
22 pub scheme: Option<UpstreamSchema>,
23}
24
25impl UpstreamBuilder {
26 pub fn new() -> Self {
27 UpstreamRequest::default().into()
28 }
29
30 pub fn with_id(mut self, id: String) -> Self {
33 self.id = Some(id);
34 self
35 }
36
37 pub fn with_u_type(mut self, u_type: UpstreamType) -> Self {
40 self.type_field = Some(u_type);
41 self
42 }
43
44 pub fn with_nodes(mut self, nodes: Value) -> Self {
55 self.nodes = Some(nodes);
56 self
57 }
58
59 pub fn with_service_name(mut self, service_name: String) -> Self {
63 self.service_name = Some(service_name);
64 self.discovery_type = Some("eureka".to_string()); self.nodes = None; self
67 }
68
69 pub fn with_discovery_type(mut self, discovery_type: String) -> Self {
72 self.discovery_type = Some(discovery_type);
73 self
74 }
75
76 pub fn with_retries(mut self, retries: i32) -> Self {
80 self.retries = Some(retries);
81 self
82 }
83
84 pub fn with_retry_timeout(mut self, retry_timeout: i32) -> Self {
86 self.retry_timeout = Some(retry_timeout);
87 self
88 }
89
90 pub fn with_timeout(mut self, timeout: ApisixTimeout) -> Self {
95 self.timeout = Some(timeout);
96 self
97 }
98
99 pub fn with_name(mut self, name: String) -> Self {
101 self.name = Some(name);
102 self
103 }
104
105 pub fn with_desc(mut self, desc: String) -> Self {
107 self.desc = Some(desc);
108 self
109 }
110
111 pub fn with_schema(mut self, scheme: UpstreamSchema) -> Self {
116 self.scheme = Some(scheme);
117 self
118 }
119
120 pub fn build(&self) -> Result<UpstreamRequest> {
121 Ok(UpstreamRequest {
122 id: self.id.clone(),
123 retries: self.retries,
124 retry_timeout: self.retry_timeout,
125 timeout: self.timeout.clone(),
126 nodes: self.nodes.clone(),
127 service_name: self.service_name.clone(),
128 discovery_type: self.discovery_type.clone(),
129 type_field: self.type_field.clone(),
130 name: self.name.clone(),
131 desc: self.desc.clone(),
132 scheme: self.scheme.clone(),
133 })
134 }
135
136}
137
138#[serde_with::skip_serializing_none]
140#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
141pub struct UpstreamRequest {
142 pub id: Option<String>,
143 pub retries: Option<i32>,
144 pub retry_timeout: Option<i32>,
145 pub timeout: Option<ApisixTimeout>,
146 pub nodes: Option<Value>,
147 pub service_name: Option<String>,
148 pub discovery_type: Option<String>,
149 #[serde(rename = "type")]
150 pub type_field: Option<UpstreamType>,
151 pub name: Option<String>,
152 pub desc: Option<String>,
153 pub scheme: Option<UpstreamSchema>,
154}
155
156impl Default for UpstreamRequest {
157 fn default() -> Self {
158 let nodes = r#"
159 {
160 "localhost:9000": 1
161 }"#;
162 let nodes = serde_json::from_str(nodes).unwrap();
163 UpstreamRequest {
164 id: Some(generate_identifier()),
165 retries: Some(0_i32), retry_timeout: Some(0_i32),
167 timeout: None,
168 nodes: Some(nodes),
169 service_name: None,
170 discovery_type: None,
171 type_field: None,
172 name: None,
173 desc: None,
174 scheme: Some(UpstreamSchema::http),
175 }
176 }
177}
178
179impl From<UpstreamRequest> for UpstreamBuilder {
180 fn from(upstream: UpstreamRequest) -> Self {
181 UpstreamBuilder {
182 id: upstream.id,
183 retries: upstream.retries,
184 retry_timeout: upstream.retry_timeout,
185 timeout: upstream.timeout,
186 nodes: upstream.nodes,
187 service_name: upstream.service_name,
188 discovery_type: upstream.discovery_type,
189 type_field: upstream.type_field,
190 name: upstream.name,
191 desc: upstream.desc,
192 scheme: upstream.scheme,
193 }
194 }
195}
196
197#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Display, EnumString)]
198#[allow(non_camel_case_types)]
199#[strum(ascii_case_insensitive)]
200#[non_exhaustive]
201pub enum UpstreamType {
202 roundrobin,
203 chash,
204 ewma,
205 least_conn,
206}
207
208#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Display, EnumString)]
209#[allow(non_camel_case_types)]
210#[strum(ascii_case_insensitive)]
211#[non_exhaustive]
212pub enum UpstreamTypeChashAuxiliary {
213 vars,
214 header,
215 cookie,
216 consumer,
217}
218
219impl From<String> for UpstreamTypeChashAuxiliary {
220 fn from(value: String) -> Self {
221 match value.to_uppercase().as_str() {
222 "VARS" => UpstreamTypeChashAuxiliary::vars,
223 "HEADER" => UpstreamTypeChashAuxiliary::header,
224 "COOKIE" => UpstreamTypeChashAuxiliary::cookie,
225 "CONSUMER" => UpstreamTypeChashAuxiliary::consumer,
226 _ => UpstreamTypeChashAuxiliary::vars
227 }
228 }
229}
230
231#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Display, EnumString)]
232#[allow(non_camel_case_types)]
233#[strum(ascii_case_insensitive)]
234#[non_exhaustive]
235pub enum UpstreamSchema {
236 http,
237 https,
238 grpc,
239 grpcs,
240 tcp,
241 udp,
242 tls
243}
244
245#[cfg(test)]
247mod tests {
248 use serde_json::{to_string, to_string_pretty};
249 use super::*;
250 use tracing::{error, info};
251 use tracing_test::traced_test;
252 use crate::models::admin_upstream_requests::UpstreamType;
253
254 #[traced_test]
255 #[tokio::test]
256 async fn test_generate_upstream_request() {
257 let nodes = r#"
258 {
259 "localhost:9000": 1
260 }"#;
261 let nodes = serde_json::from_str(nodes).unwrap();
262
263 let upstream_req = UpstreamBuilder::new()
264 .with_id("test_upstream".to_string())
265 .with_name("Test Upstream".to_string())
266 .with_desc("Test Upstream Description".to_string())
267 .with_schema(UpstreamSchema::https)
268 .with_u_type(UpstreamType::roundrobin)
269 .with_nodes(nodes)
270 .with_retries(3)
271 .with_retry_timeout(5)
272 .with_timeout(ApisixTimeout { connect: Some(0.5), send: Some(0.5), read: Some(0.5) })
273 .build().unwrap();
274 info!("Upstream Request: {:?}", to_string(&upstream_req));
275 assert!(true)
276 }
277}
278