openstack_sdk/api/compute/v2/server/
create_backup_21.rs1use derive_builder::Builder;
19use http::{HeaderMap, HeaderName, HeaderValue};
20
21use crate::api::rest_endpoint_prelude::*;
22
23use serde::Deserialize;
24use serde::Serialize;
25use std::borrow::Cow;
26use std::collections::BTreeMap;
27
28#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
30#[builder(setter(strip_option))]
31pub struct CreateBackup<'a> {
32 #[serde()]
34 #[builder(setter(into))]
35 pub(crate) backup_type: Cow<'a, str>,
36
37 #[serde(skip_serializing_if = "Option::is_none")]
40 #[builder(default, private, setter(into, name = "_metadata"))]
41 pub(crate) metadata: Option<BTreeMap<Cow<'a, str>, Cow<'a, str>>>,
42
43 #[serde()]
45 #[builder(setter(into))]
46 pub(crate) name: Cow<'a, str>,
47
48 #[serde()]
51 #[builder(setter(into))]
52 pub(crate) rotation: i32,
53}
54
55impl<'a> CreateBackupBuilder<'a> {
56 pub fn metadata<I, K, V>(&mut self, iter: I) -> &mut Self
59 where
60 I: Iterator<Item = (K, V)>,
61 K: Into<Cow<'a, str>>,
62 V: Into<Cow<'a, str>>,
63 {
64 self.metadata
65 .get_or_insert(None)
66 .get_or_insert_with(BTreeMap::new)
67 .extend(iter.map(|(k, v)| (k.into(), v.into())));
68 self
69 }
70}
71
72#[derive(Builder, Debug, Clone)]
73#[builder(setter(strip_option))]
74pub struct Request<'a> {
75 #[builder(setter(into))]
77 pub(crate) create_backup: CreateBackup<'a>,
78
79 #[builder(default, setter(into))]
81 id: Cow<'a, str>,
82
83 #[builder(setter(name = "_headers"), default, private)]
84 _headers: Option<HeaderMap>,
85}
86impl<'a> Request<'a> {
87 pub fn builder() -> RequestBuilder<'a> {
89 RequestBuilder::default()
90 }
91}
92
93impl RequestBuilder<'_> {
94 pub fn header(&mut self, header_name: &'static str, header_value: &'static str) -> &mut Self
96where {
97 self._headers
98 .get_or_insert(None)
99 .get_or_insert_with(HeaderMap::new)
100 .insert(header_name, HeaderValue::from_static(header_value));
101 self
102 }
103
104 pub fn headers<I, T>(&mut self, iter: I) -> &mut Self
106 where
107 I: Iterator<Item = T>,
108 T: Into<(Option<HeaderName>, HeaderValue)>,
109 {
110 self._headers
111 .get_or_insert(None)
112 .get_or_insert_with(HeaderMap::new)
113 .extend(iter.map(Into::into));
114 self
115 }
116}
117
118impl RestEndpoint for Request<'_> {
119 fn method(&self) -> http::Method {
120 http::Method::POST
121 }
122
123 fn endpoint(&self) -> Cow<'static, str> {
124 format!("servers/{id}/action", id = self.id.as_ref(),).into()
125 }
126
127 fn parameters(&self) -> QueryParams {
128 QueryParams::default()
129 }
130
131 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
132 let mut params = JsonBodyParams::default();
133
134 params.push("createBackup", serde_json::to_value(&self.create_backup)?);
135
136 params.into_body()
137 }
138
139 fn service_type(&self) -> ServiceType {
140 ServiceType::Compute
141 }
142
143 fn response_key(&self) -> Option<Cow<'static, str>> {
144 Some("server".into())
145 }
146
147 fn request_headers(&self) -> Option<&HeaderMap> {
149 self._headers.as_ref()
150 }
151
152 fn api_version(&self) -> Option<ApiVersion> {
154 Some(ApiVersion::new(2, 1))
155 }
156}
157
158#[cfg(test)]
159mod tests {
160 use super::*;
161 #[cfg(feature = "sync")]
162 use crate::api::Query;
163 use crate::test::client::FakeOpenStackClient;
164 use crate::types::ServiceType;
165 use http::{HeaderName, HeaderValue};
166 use httpmock::MockServer;
167 use serde_json::json;
168
169 #[test]
170 fn test_service_type() {
171 assert_eq!(
172 Request::builder()
173 .create_backup(
174 CreateBackupBuilder::default()
175 .backup_type("foo")
176 .name("foo")
177 .rotation(123)
178 .build()
179 .unwrap()
180 )
181 .build()
182 .unwrap()
183 .service_type(),
184 ServiceType::Compute
185 );
186 }
187
188 #[test]
189 fn test_response_key() {
190 assert_eq!(
191 Request::builder()
192 .create_backup(
193 CreateBackupBuilder::default()
194 .backup_type("foo")
195 .name("foo")
196 .rotation(123)
197 .build()
198 .unwrap()
199 )
200 .build()
201 .unwrap()
202 .response_key()
203 .unwrap(),
204 "server"
205 );
206 }
207
208 #[cfg(feature = "sync")]
209 #[test]
210 fn endpoint() {
211 let server = MockServer::start();
212 let client = FakeOpenStackClient::new(server.base_url());
213 let mock = server.mock(|when, then| {
214 when.method(httpmock::Method::POST)
215 .path(format!("/servers/{id}/action", id = "id",));
216
217 then.status(200)
218 .header("content-type", "application/json")
219 .json_body(json!({ "server": {} }));
220 });
221
222 let endpoint = Request::builder()
223 .id("id")
224 .create_backup(
225 CreateBackupBuilder::default()
226 .backup_type("foo")
227 .name("foo")
228 .rotation(123)
229 .build()
230 .unwrap(),
231 )
232 .build()
233 .unwrap();
234 let _: serde_json::Value = endpoint.query(&client).unwrap();
235 mock.assert();
236 }
237
238 #[cfg(feature = "sync")]
239 #[test]
240 fn endpoint_headers() {
241 let server = MockServer::start();
242 let client = FakeOpenStackClient::new(server.base_url());
243 let mock = server.mock(|when, then| {
244 when.method(httpmock::Method::POST)
245 .path(format!("/servers/{id}/action", id = "id",))
246 .header("foo", "bar")
247 .header("not_foo", "not_bar");
248 then.status(200)
249 .header("content-type", "application/json")
250 .json_body(json!({ "server": {} }));
251 });
252
253 let endpoint = Request::builder()
254 .id("id")
255 .create_backup(
256 CreateBackupBuilder::default()
257 .backup_type("foo")
258 .name("foo")
259 .rotation(123)
260 .build()
261 .unwrap(),
262 )
263 .headers(
264 [(
265 Some(HeaderName::from_static("foo")),
266 HeaderValue::from_static("bar"),
267 )]
268 .into_iter(),
269 )
270 .header("not_foo", "not_bar")
271 .build()
272 .unwrap();
273 let _: serde_json::Value = endpoint.query(&client).unwrap();
274 mock.assert();
275 }
276}