openstack_sdk/api/compute/v2/aggregate/
set_metadata.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5//     http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12//
13// SPDX-License-Identifier: Apache-2.0
14//
15// WARNING: This file is automatically generated from OpenAPI schema using
16// `openstack-codegenerator`.
17
18use 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)]
29#[builder(setter(strip_option))]
30pub struct SetMetadata<'a> {
31    #[serde()]
32    #[builder(private, setter(into, name = "_metadata"))]
33    pub(crate) metadata: BTreeMap<Cow<'a, str>, Option<Cow<'a, str>>>,
34}
35
36impl<'a> SetMetadataBuilder<'a> {
37    pub fn metadata<I, K, V>(&mut self, iter: I) -> &mut Self
38    where
39        I: Iterator<Item = (K, V)>,
40        K: Into<Cow<'a, str>>,
41        V: Into<Option<Cow<'a, str>>>,
42    {
43        self.metadata
44            .get_or_insert_with(BTreeMap::new)
45            .extend(iter.map(|(k, v)| (k.into(), v.into())));
46        self
47    }
48}
49
50#[derive(Builder, Debug, Clone)]
51#[builder(setter(strip_option))]
52pub struct Request<'a> {
53    #[builder(setter(into))]
54    pub(crate) set_metadata: SetMetadata<'a>,
55
56    /// id parameter for /v2.1/os-aggregates/{id}/action API
57    #[builder(default, setter(into))]
58    id: Cow<'a, str>,
59
60    #[builder(setter(name = "_headers"), default, private)]
61    _headers: Option<HeaderMap>,
62}
63impl<'a> Request<'a> {
64    /// Create a builder for the endpoint.
65    pub fn builder() -> RequestBuilder<'a> {
66        RequestBuilder::default()
67    }
68}
69
70impl RequestBuilder<'_> {
71    /// Add a single header to the Aggregate.
72    pub fn header(&mut self, header_name: &'static str, header_value: &'static str) -> &mut Self
73where {
74        self._headers
75            .get_or_insert(None)
76            .get_or_insert_with(HeaderMap::new)
77            .insert(header_name, HeaderValue::from_static(header_value));
78        self
79    }
80
81    /// Add multiple headers.
82    pub fn headers<I, T>(&mut self, iter: I) -> &mut Self
83    where
84        I: Iterator<Item = T>,
85        T: Into<(Option<HeaderName>, HeaderValue)>,
86    {
87        self._headers
88            .get_or_insert(None)
89            .get_or_insert_with(HeaderMap::new)
90            .extend(iter.map(Into::into));
91        self
92    }
93}
94
95impl RestEndpoint for Request<'_> {
96    fn method(&self) -> http::Method {
97        http::Method::POST
98    }
99
100    fn endpoint(&self) -> Cow<'static, str> {
101        format!("os-aggregates/{id}/action", id = self.id.as_ref(),).into()
102    }
103
104    fn parameters(&self) -> QueryParams {
105        QueryParams::default()
106    }
107
108    fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
109        let mut params = JsonBodyParams::default();
110
111        params.push("set_metadata", serde_json::to_value(&self.set_metadata)?);
112
113        params.into_body()
114    }
115
116    fn service_type(&self) -> ServiceType {
117        ServiceType::Compute
118    }
119
120    fn response_key(&self) -> Option<Cow<'static, str>> {
121        Some("aggregate".into())
122    }
123
124    /// Returns headers to be set into the request
125    fn request_headers(&self) -> Option<&HeaderMap> {
126        self._headers.as_ref()
127    }
128
129    /// Returns required API version
130    fn api_version(&self) -> Option<ApiVersion> {
131        Some(ApiVersion::new(2, 1))
132    }
133}
134
135#[cfg(test)]
136mod tests {
137    use super::*;
138    #[cfg(feature = "sync")]
139    use crate::api::Query;
140    use crate::test::client::FakeOpenStackClient;
141    use crate::types::ServiceType;
142    use http::{HeaderName, HeaderValue};
143    use httpmock::MockServer;
144    use serde_json::json;
145
146    #[test]
147    fn test_service_type() {
148        assert_eq!(
149            Request::builder()
150                .set_metadata(
151                    SetMetadataBuilder::default()
152                        .metadata(
153                            BTreeMap::<String, Option<String>>::new()
154                                .into_iter()
155                                .map(|(k, v)| (k, v.map(Into::into)))
156                        )
157                        .build()
158                        .unwrap()
159                )
160                .build()
161                .unwrap()
162                .service_type(),
163            ServiceType::Compute
164        );
165    }
166
167    #[test]
168    fn test_response_key() {
169        assert_eq!(
170            Request::builder()
171                .set_metadata(
172                    SetMetadataBuilder::default()
173                        .metadata(
174                            BTreeMap::<String, Option<String>>::new()
175                                .into_iter()
176                                .map(|(k, v)| (k, v.map(Into::into)))
177                        )
178                        .build()
179                        .unwrap()
180                )
181                .build()
182                .unwrap()
183                .response_key()
184                .unwrap(),
185            "aggregate"
186        );
187    }
188
189    #[cfg(feature = "sync")]
190    #[test]
191    fn endpoint() {
192        let server = MockServer::start();
193        let client = FakeOpenStackClient::new(server.base_url());
194        let mock = server.mock(|when, then| {
195            when.method(httpmock::Method::POST)
196                .path(format!("/os-aggregates/{id}/action", id = "id",));
197
198            then.status(200)
199                .header("content-type", "application/json")
200                .json_body(json!({ "aggregate": {} }));
201        });
202
203        let endpoint = Request::builder()
204            .id("id")
205            .set_metadata(
206                SetMetadataBuilder::default()
207                    .metadata(
208                        BTreeMap::<String, Option<String>>::new()
209                            .into_iter()
210                            .map(|(k, v)| (k, v.map(Into::into))),
211                    )
212                    .build()
213                    .unwrap(),
214            )
215            .build()
216            .unwrap();
217        let _: serde_json::Value = endpoint.query(&client).unwrap();
218        mock.assert();
219    }
220
221    #[cfg(feature = "sync")]
222    #[test]
223    fn endpoint_headers() {
224        let server = MockServer::start();
225        let client = FakeOpenStackClient::new(server.base_url());
226        let mock = server.mock(|when, then| {
227            when.method(httpmock::Method::POST)
228                .path(format!("/os-aggregates/{id}/action", id = "id",))
229                .header("foo", "bar")
230                .header("not_foo", "not_bar");
231            then.status(200)
232                .header("content-type", "application/json")
233                .json_body(json!({ "aggregate": {} }));
234        });
235
236        let endpoint = Request::builder()
237            .id("id")
238            .set_metadata(
239                SetMetadataBuilder::default()
240                    .metadata(
241                        BTreeMap::<String, Option<String>>::new()
242                            .into_iter()
243                            .map(|(k, v)| (k, v.map(Into::into))),
244                    )
245                    .build()
246                    .unwrap(),
247            )
248            .headers(
249                [(
250                    Some(HeaderName::from_static("foo")),
251                    HeaderValue::from_static("bar"),
252                )]
253                .into_iter(),
254            )
255            .header("not_foo", "not_bar")
256            .build()
257            .unwrap();
258        let _: serde_json::Value = endpoint.query(&client).unwrap();
259        mock.assert();
260    }
261}