openstack_sdk_load_balancer/v2/healthmonitor/
create.rs1use derive_builder::Builder;
53use http::{HeaderMap, HeaderName, HeaderValue};
54
55use openstack_sdk_core::api::rest_endpoint_prelude::*;
56
57use serde::Deserialize;
58use serde::Serialize;
59use std::borrow::Cow;
60
61#[derive(Debug, Deserialize, Clone, Serialize)]
62pub enum HttpMethod {
63 #[serde(rename = "CONNECT")]
64 Connect,
65 #[serde(rename = "DELETE")]
66 Delete,
67 #[serde(rename = "GET")]
68 Get,
69 #[serde(rename = "HEAD")]
70 Head,
71 #[serde(rename = "OPTIONS")]
72 Options,
73 #[serde(rename = "PATCH")]
74 Patch,
75 #[serde(rename = "POST")]
76 Post,
77 #[serde(rename = "PUT")]
78 Put,
79 #[serde(rename = "TRACE")]
80 Trace,
81}
82
83#[derive(Debug, Deserialize, Clone, Serialize)]
84pub enum Type {
85 #[serde(rename = "HTTP")]
86 Http,
87 #[serde(rename = "HTTPS")]
88 Https,
89 #[serde(rename = "PING")]
90 Ping,
91 #[serde(rename = "SCTP")]
92 Sctp,
93 #[serde(rename = "TCP")]
94 Tcp,
95 #[serde(rename = "TLS-HELLO")]
96 TlsHello,
97 #[serde(rename = "UDP-CONNECT")]
98 UdpConnect,
99}
100
101#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
103#[builder(setter(strip_option))]
104pub struct Healthmonitor<'a> {
105 #[serde(skip_serializing_if = "Option::is_none")]
108 #[builder(default, setter(into))]
109 pub(crate) admin_state_up: Option<bool>,
110
111 #[serde()]
113 #[builder(setter(into))]
114 pub(crate) delay: i32,
115
116 #[serde(skip_serializing_if = "Option::is_none")]
121 #[builder(default, setter(into))]
122 pub(crate) domain_name: Option<Cow<'a, str>>,
123
124 #[serde(skip_serializing_if = "Option::is_none")]
133 #[builder(default, setter(into))]
134 pub(crate) expected_codes: Option<Cow<'a, str>>,
135
136 #[serde(skip_serializing_if = "Option::is_none")]
140 #[builder(default)]
141 pub(crate) http_method: Option<HttpMethod>,
142
143 #[serde(skip_serializing_if = "Option::is_none")]
147 #[builder(default, setter(into))]
148 pub(crate) http_version: Option<f32>,
149
150 #[serde()]
153 #[builder(setter(into))]
154 pub(crate) max_retries: i32,
155
156 #[serde(skip_serializing_if = "Option::is_none")]
160 #[builder(default, setter(into))]
161 pub(crate) max_retries_down: Option<i32>,
162
163 #[serde(skip_serializing_if = "Option::is_none")]
165 #[builder(default, setter(into))]
166 pub(crate) name: Option<Cow<'a, str>>,
167
168 #[serde()]
170 #[builder(setter(into))]
171 pub(crate) pool_id: Cow<'a, str>,
172
173 #[serde(skip_serializing_if = "Option::is_none")]
175 #[builder(default, setter(into))]
176 pub(crate) project_id: Option<Cow<'a, str>>,
177
178 #[serde(skip_serializing_if = "Option::is_none")]
182 #[builder(default, setter(into))]
183 pub(crate) tags: Option<Vec<Cow<'a, str>>>,
184
185 #[serde(skip_serializing_if = "Option::is_none")]
186 #[builder(default, setter(into))]
187 pub(crate) tenant_id: Option<Cow<'a, str>>,
188
189 #[serde()]
192 #[builder(setter(into))]
193 pub(crate) timeout: i32,
194
195 #[serde(rename = "type")]
198 #[builder()]
199 pub(crate) _type: Type,
200
201 #[serde(skip_serializing_if = "Option::is_none")]
205 #[builder(default, setter(into))]
206 pub(crate) url_path: Option<Cow<'a, str>>,
207}
208
209#[derive(Builder, Debug, Clone)]
210#[builder(setter(strip_option))]
211pub struct Request<'a> {
212 #[builder(setter(into))]
214 pub(crate) healthmonitor: Healthmonitor<'a>,
215
216 #[builder(setter(name = "_headers"), default, private)]
217 _headers: Option<HeaderMap>,
218}
219impl<'a> Request<'a> {
220 pub fn builder() -> RequestBuilder<'a> {
222 RequestBuilder::default()
223 }
224}
225
226impl<'a> RequestBuilder<'a> {
227 pub fn header<K, V>(&mut self, header_name: K, header_value: V) -> &mut Self
229 where
230 K: Into<HeaderName>,
231 V: Into<HeaderValue>,
232 {
233 self._headers
234 .get_or_insert(None)
235 .get_or_insert_with(HeaderMap::new)
236 .insert(header_name.into(), header_value.into());
237 self
238 }
239
240 pub fn headers<I, T>(&mut self, iter: I) -> &mut Self
242 where
243 I: Iterator<Item = T>,
244 T: Into<(Option<HeaderName>, HeaderValue)>,
245 {
246 self._headers
247 .get_or_insert(None)
248 .get_or_insert_with(HeaderMap::new)
249 .extend(iter.map(Into::into));
250 self
251 }
252}
253
254impl RestEndpoint for Request<'_> {
255 fn method(&self) -> http::Method {
256 http::Method::POST
257 }
258
259 fn endpoint(&self) -> Cow<'static, str> {
260 "lbaas/healthmonitors".to_string().into()
261 }
262
263 fn parameters(&self) -> QueryParams<'_> {
264 QueryParams::default()
265 }
266
267 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
268 let mut params = JsonBodyParams::default();
269
270 params.push("healthmonitor", serde_json::to_value(&self.healthmonitor)?);
271
272 params.into_body()
273 }
274
275 fn service_type(&self) -> ServiceType {
276 ServiceType::LoadBalancer
277 }
278
279 fn response_key(&self) -> Option<Cow<'static, str>> {
280 Some("healthmonitor".into())
281 }
282
283 fn request_headers(&self) -> Option<&HeaderMap> {
285 self._headers.as_ref()
286 }
287
288 fn api_version(&self) -> Option<ApiVersion> {
290 Some(ApiVersion::new(2, 0))
291 }
292}
293
294#[cfg(test)]
295mod tests {
296 use super::*;
297 use http::{HeaderName, HeaderValue};
298 use httpmock::MockServer;
299 #[cfg(feature = "sync")]
300 use openstack_sdk_core::api::Query;
301 use openstack_sdk_core::test::client::FakeOpenStackClient;
302 use openstack_sdk_core::types::ServiceType;
303 use serde_json::json;
304
305 #[test]
306 fn test_service_type() {
307 assert_eq!(
308 Request::builder()
309 .healthmonitor(
310 HealthmonitorBuilder::default()
311 ._type(Type::Http)
312 .delay(123)
313 .max_retries(123)
314 .pool_id("foo")
315 .timeout(123)
316 .build()
317 .unwrap()
318 )
319 .build()
320 .unwrap()
321 .service_type(),
322 ServiceType::LoadBalancer
323 );
324 }
325
326 #[test]
327 fn test_response_key() {
328 assert_eq!(
329 Request::builder()
330 .healthmonitor(
331 HealthmonitorBuilder::default()
332 ._type(Type::Http)
333 .delay(123)
334 .max_retries(123)
335 .pool_id("foo")
336 .timeout(123)
337 .build()
338 .unwrap()
339 )
340 .build()
341 .unwrap()
342 .response_key()
343 .unwrap(),
344 "healthmonitor"
345 );
346 }
347
348 #[cfg(feature = "sync")]
349 #[test]
350 fn endpoint() {
351 let server = MockServer::start();
352 let client = FakeOpenStackClient::new(server.base_url());
353 let mock = server.mock(|when, then| {
354 when.method(httpmock::Method::POST)
355 .path("/lbaas/healthmonitors".to_string());
356
357 then.status(200)
358 .header("content-type", "application/json")
359 .json_body(json!({ "healthmonitor": {} }));
360 });
361
362 let endpoint = Request::builder()
363 .healthmonitor(
364 HealthmonitorBuilder::default()
365 ._type(Type::Http)
366 .delay(123)
367 .max_retries(123)
368 .pool_id("foo")
369 .timeout(123)
370 .build()
371 .unwrap(),
372 )
373 .build()
374 .unwrap();
375 let _: serde_json::Value = endpoint.query(&client).unwrap();
376 mock.assert();
377 }
378
379 #[cfg(feature = "sync")]
380 #[test]
381 fn endpoint_headers() {
382 let server = MockServer::start();
383 let client = FakeOpenStackClient::new(server.base_url());
384 let mock = server.mock(|when, then| {
385 when.method(httpmock::Method::POST)
386 .path("/lbaas/healthmonitors".to_string())
387 .header("foo", "bar")
388 .header("not_foo", "not_bar");
389 then.status(200)
390 .header("content-type", "application/json")
391 .json_body(json!({ "healthmonitor": {} }));
392 });
393
394 let endpoint = Request::builder()
395 .healthmonitor(
396 HealthmonitorBuilder::default()
397 ._type(Type::Http)
398 .delay(123)
399 .max_retries(123)
400 .pool_id("foo")
401 .timeout(123)
402 .build()
403 .unwrap(),
404 )
405 .headers(
406 [(
407 Some(HeaderName::from_static("foo")),
408 HeaderValue::from_static("bar"),
409 )]
410 .into_iter(),
411 )
412 .header(
413 HeaderName::from_static("not_foo"),
414 HeaderValue::from_static("not_bar"),
415 )
416 .build()
417 .unwrap();
418 let _: serde_json::Value = endpoint.query(&client).unwrap();
419 mock.assert();
420 }
421}