datadog_api_client/datadogV2/api/
api_api_management.rs

1// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
2// This product includes software developed at Datadog (https://www.datadoghq.com/).
3// Copyright 2019-Present Datadog, Inc.
4use crate::datadog;
5use log::warn;
6use reqwest::header::{HeaderMap, HeaderValue};
7use serde::{Deserialize, Serialize};
8
9/// CreateOpenAPIOptionalParams is a struct for passing parameters to the method [`APIManagementAPI::create_open_api`]
10#[non_exhaustive]
11#[derive(Clone, Default, Debug)]
12pub struct CreateOpenAPIOptionalParams {
13    /// Binary `OpenAPI` spec file
14    pub openapi_spec_file: Option<Vec<u8>>,
15}
16
17impl CreateOpenAPIOptionalParams {
18    /// Binary `OpenAPI` spec file
19    pub fn openapi_spec_file(mut self, value: Vec<u8>) -> Self {
20        self.openapi_spec_file = Some(value);
21        self
22    }
23}
24
25/// ListAPIsOptionalParams is a struct for passing parameters to the method [`APIManagementAPI::list_apis`]
26#[non_exhaustive]
27#[derive(Clone, Default, Debug)]
28pub struct ListAPIsOptionalParams {
29    /// Filter APIs by name
30    pub query: Option<String>,
31    /// Number of items per page.
32    pub page_limit: Option<i64>,
33    /// Offset for pagination.
34    pub page_offset: Option<i64>,
35}
36
37impl ListAPIsOptionalParams {
38    /// Filter APIs by name
39    pub fn query(mut self, value: String) -> Self {
40        self.query = Some(value);
41        self
42    }
43    /// Number of items per page.
44    pub fn page_limit(mut self, value: i64) -> Self {
45        self.page_limit = Some(value);
46        self
47    }
48    /// Offset for pagination.
49    pub fn page_offset(mut self, value: i64) -> Self {
50        self.page_offset = Some(value);
51        self
52    }
53}
54
55/// UpdateOpenAPIOptionalParams is a struct for passing parameters to the method [`APIManagementAPI::update_open_api`]
56#[non_exhaustive]
57#[derive(Clone, Default, Debug)]
58pub struct UpdateOpenAPIOptionalParams {
59    /// Binary `OpenAPI` spec file
60    pub openapi_spec_file: Option<Vec<u8>>,
61}
62
63impl UpdateOpenAPIOptionalParams {
64    /// Binary `OpenAPI` spec file
65    pub fn openapi_spec_file(mut self, value: Vec<u8>) -> Self {
66        self.openapi_spec_file = Some(value);
67        self
68    }
69}
70
71/// CreateOpenAPIError is a struct for typed errors of method [`APIManagementAPI::create_open_api`]
72#[derive(Debug, Clone, Serialize, Deserialize)]
73#[serde(untagged)]
74pub enum CreateOpenAPIError {
75    JSONAPIErrorResponse(crate::datadogV2::model::JSONAPIErrorResponse),
76    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
77    UnknownValue(serde_json::Value),
78}
79
80/// DeleteOpenAPIError is a struct for typed errors of method [`APIManagementAPI::delete_open_api`]
81#[derive(Debug, Clone, Serialize, Deserialize)]
82#[serde(untagged)]
83pub enum DeleteOpenAPIError {
84    JSONAPIErrorResponse(crate::datadogV2::model::JSONAPIErrorResponse),
85    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
86    UnknownValue(serde_json::Value),
87}
88
89/// GetOpenAPIError is a struct for typed errors of method [`APIManagementAPI::get_open_api`]
90#[derive(Debug, Clone, Serialize, Deserialize)]
91#[serde(untagged)]
92pub enum GetOpenAPIError {
93    JSONAPIErrorResponse(crate::datadogV2::model::JSONAPIErrorResponse),
94    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
95    UnknownValue(serde_json::Value),
96}
97
98/// ListAPIsError is a struct for typed errors of method [`APIManagementAPI::list_apis`]
99#[derive(Debug, Clone, Serialize, Deserialize)]
100#[serde(untagged)]
101pub enum ListAPIsError {
102    JSONAPIErrorResponse(crate::datadogV2::model::JSONAPIErrorResponse),
103    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
104    UnknownValue(serde_json::Value),
105}
106
107/// UpdateOpenAPIError is a struct for typed errors of method [`APIManagementAPI::update_open_api`]
108#[derive(Debug, Clone, Serialize, Deserialize)]
109#[serde(untagged)]
110pub enum UpdateOpenAPIError {
111    JSONAPIErrorResponse(crate::datadogV2::model::JSONAPIErrorResponse),
112    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
113    UnknownValue(serde_json::Value),
114}
115
116/// Configure your API endpoints through the Datadog API.
117#[derive(Debug, Clone)]
118pub struct APIManagementAPI {
119    config: datadog::Configuration,
120    client: reqwest_middleware::ClientWithMiddleware,
121}
122
123impl Default for APIManagementAPI {
124    fn default() -> Self {
125        Self::with_config(datadog::Configuration::default())
126    }
127}
128
129impl APIManagementAPI {
130    pub fn new() -> Self {
131        Self::default()
132    }
133    pub fn with_config(config: datadog::Configuration) -> Self {
134        let mut reqwest_client_builder = reqwest::Client::builder();
135
136        if let Some(proxy_url) = &config.proxy_url {
137            let proxy = reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL");
138            reqwest_client_builder = reqwest_client_builder.proxy(proxy);
139        }
140
141        let mut middleware_client_builder =
142            reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap());
143
144        if config.enable_retry {
145            struct RetryableStatus;
146            impl reqwest_retry::RetryableStrategy for RetryableStatus {
147                fn handle(
148                    &self,
149                    res: &Result<reqwest::Response, reqwest_middleware::Error>,
150                ) -> Option<reqwest_retry::Retryable> {
151                    match res {
152                        Ok(success) => reqwest_retry::default_on_request_success(success),
153                        Err(_) => None,
154                    }
155                }
156            }
157            let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder()
158                .build_with_max_retries(config.max_retries);
159
160            let retry_middleware =
161                reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy(
162                    backoff_policy,
163                    RetryableStatus,
164                );
165
166            middleware_client_builder = middleware_client_builder.with(retry_middleware);
167        }
168
169        let client = middleware_client_builder.build();
170
171        Self { config, client }
172    }
173
174    pub fn with_client_and_config(
175        config: datadog::Configuration,
176        client: reqwest_middleware::ClientWithMiddleware,
177    ) -> Self {
178        Self { config, client }
179    }
180
181    /// Create a new API from the [OpenAPI](<https://spec.openapis.org/oas/latest.html>) specification given.
182    /// See the [API Catalog documentation](<https://docs.datadoghq.com/api_catalog/add_metadata/>) for additional
183    /// information about the possible metadata.
184    /// It returns the created API ID.
185    pub async fn create_open_api(
186        &self,
187        params: CreateOpenAPIOptionalParams,
188    ) -> Result<crate::datadogV2::model::CreateOpenAPIResponse, datadog::Error<CreateOpenAPIError>>
189    {
190        match self.create_open_api_with_http_info(params).await {
191            Ok(response_content) => {
192                if let Some(e) = response_content.entity {
193                    Ok(e)
194                } else {
195                    Err(datadog::Error::Serde(serde::de::Error::custom(
196                        "response content was None",
197                    )))
198                }
199            }
200            Err(err) => Err(err),
201        }
202    }
203
204    /// Create a new API from the [OpenAPI](<https://spec.openapis.org/oas/latest.html>) specification given.
205    /// See the [API Catalog documentation](<https://docs.datadoghq.com/api_catalog/add_metadata/>) for additional
206    /// information about the possible metadata.
207    /// It returns the created API ID.
208    pub async fn create_open_api_with_http_info(
209        &self,
210        params: CreateOpenAPIOptionalParams,
211    ) -> Result<
212        datadog::ResponseContent<crate::datadogV2::model::CreateOpenAPIResponse>,
213        datadog::Error<CreateOpenAPIError>,
214    > {
215        let local_configuration = &self.config;
216        let operation_id = "v2.create_open_api";
217        if local_configuration.is_unstable_operation_enabled(operation_id) {
218            warn!("Using unstable operation {operation_id}");
219        } else {
220            let local_error = datadog::UnstableOperationDisabledError {
221                msg: "Operation 'v2.create_open_api' is not enabled".to_string(),
222            };
223            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
224        }
225
226        // unbox and build optional parameters
227        let openapi_spec_file = params.openapi_spec_file;
228
229        let local_client = &self.client;
230
231        let local_uri_str = format!(
232            "{}/api/v2/apicatalog/openapi",
233            local_configuration.get_operation_host(operation_id)
234        );
235        let mut local_req_builder =
236            local_client.request(reqwest::Method::POST, local_uri_str.as_str());
237
238        // build headers
239        let mut headers = HeaderMap::new();
240        headers.insert(
241            "Content-Type",
242            HeaderValue::from_static("multipart/form-data"),
243        );
244        headers.insert("Accept", HeaderValue::from_static("application/json"));
245
246        // build user agent
247        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
248            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
249            Err(e) => {
250                log::warn!("Failed to parse user agent header: {e}, falling back to default");
251                headers.insert(
252                    reqwest::header::USER_AGENT,
253                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
254                )
255            }
256        };
257
258        // build auth
259        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
260            headers.insert(
261                "DD-API-KEY",
262                HeaderValue::from_str(local_key.key.as_str())
263                    .expect("failed to parse DD-API-KEY header"),
264            );
265        };
266        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
267            headers.insert(
268                "DD-APPLICATION-KEY",
269                HeaderValue::from_str(local_key.key.as_str())
270                    .expect("failed to parse DD-APPLICATION-KEY header"),
271            );
272        };
273
274        // build form parameters
275        if let Some(openapi_spec_file) = openapi_spec_file {
276            let mut local_form = form_data_builder::FormData::new(Vec::new());
277            let cursor = std::io::Cursor::new(openapi_spec_file);
278            if let Err(e) = local_form.write_file(
279                "openapi_spec_file",
280                cursor,
281                Some("openapi_spec_file".as_ref()),
282                "application/octet-stream",
283            ) {
284                return Err(crate::datadog::Error::Io(e));
285            };
286            headers.insert(
287                "Content-Type",
288                local_form.content_type_header().parse().unwrap(),
289            );
290            let form_result = local_form.finish();
291            match form_result {
292                Ok(form) => local_req_builder = local_req_builder.body(form),
293                Err(e) => return Err(crate::datadog::Error::Io(e)),
294            };
295        };
296
297        local_req_builder = local_req_builder.headers(headers);
298        let local_req = local_req_builder.build()?;
299        log::debug!("request content: {:?}", local_req.body());
300        let local_resp = local_client.execute(local_req).await?;
301
302        let local_status = local_resp.status();
303        let local_content = local_resp.text().await?;
304        log::debug!("response content: {}", local_content);
305
306        if !local_status.is_client_error() && !local_status.is_server_error() {
307            match serde_json::from_str::<crate::datadogV2::model::CreateOpenAPIResponse>(
308                &local_content,
309            ) {
310                Ok(e) => {
311                    return Ok(datadog::ResponseContent {
312                        status: local_status,
313                        content: local_content,
314                        entity: Some(e),
315                    })
316                }
317                Err(e) => return Err(datadog::Error::Serde(e)),
318            };
319        } else {
320            let local_entity: Option<CreateOpenAPIError> =
321                serde_json::from_str(&local_content).ok();
322            let local_error = datadog::ResponseContent {
323                status: local_status,
324                content: local_content,
325                entity: local_entity,
326            };
327            Err(datadog::Error::ResponseError(local_error))
328        }
329    }
330
331    /// Delete a specific API by ID.
332    pub async fn delete_open_api(
333        &self,
334        id: uuid::Uuid,
335    ) -> Result<(), datadog::Error<DeleteOpenAPIError>> {
336        match self.delete_open_api_with_http_info(id).await {
337            Ok(_) => Ok(()),
338            Err(err) => Err(err),
339        }
340    }
341
342    /// Delete a specific API by ID.
343    pub async fn delete_open_api_with_http_info(
344        &self,
345        id: uuid::Uuid,
346    ) -> Result<datadog::ResponseContent<()>, datadog::Error<DeleteOpenAPIError>> {
347        let local_configuration = &self.config;
348        let operation_id = "v2.delete_open_api";
349        if local_configuration.is_unstable_operation_enabled(operation_id) {
350            warn!("Using unstable operation {operation_id}");
351        } else {
352            let local_error = datadog::UnstableOperationDisabledError {
353                msg: "Operation 'v2.delete_open_api' is not enabled".to_string(),
354            };
355            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
356        }
357
358        let local_client = &self.client;
359
360        let local_uri_str = format!(
361            "{}/api/v2/apicatalog/api/{id}",
362            local_configuration.get_operation_host(operation_id),
363            id = datadog::urlencode(id.to_string())
364        );
365        let mut local_req_builder =
366            local_client.request(reqwest::Method::DELETE, local_uri_str.as_str());
367
368        // build headers
369        let mut headers = HeaderMap::new();
370        headers.insert("Accept", HeaderValue::from_static("*/*"));
371
372        // build user agent
373        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
374            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
375            Err(e) => {
376                log::warn!("Failed to parse user agent header: {e}, falling back to default");
377                headers.insert(
378                    reqwest::header::USER_AGENT,
379                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
380                )
381            }
382        };
383
384        // build auth
385        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
386            headers.insert(
387                "DD-API-KEY",
388                HeaderValue::from_str(local_key.key.as_str())
389                    .expect("failed to parse DD-API-KEY header"),
390            );
391        };
392        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
393            headers.insert(
394                "DD-APPLICATION-KEY",
395                HeaderValue::from_str(local_key.key.as_str())
396                    .expect("failed to parse DD-APPLICATION-KEY header"),
397            );
398        };
399
400        local_req_builder = local_req_builder.headers(headers);
401        let local_req = local_req_builder.build()?;
402        log::debug!("request content: {:?}", local_req.body());
403        let local_resp = local_client.execute(local_req).await?;
404
405        let local_status = local_resp.status();
406        let local_content = local_resp.text().await?;
407        log::debug!("response content: {}", local_content);
408
409        if !local_status.is_client_error() && !local_status.is_server_error() {
410            Ok(datadog::ResponseContent {
411                status: local_status,
412                content: local_content,
413                entity: None,
414            })
415        } else {
416            let local_entity: Option<DeleteOpenAPIError> =
417                serde_json::from_str(&local_content).ok();
418            let local_error = datadog::ResponseContent {
419                status: local_status,
420                content: local_content,
421                entity: local_entity,
422            };
423            Err(datadog::Error::ResponseError(local_error))
424        }
425    }
426
427    /// Retrieve information about a specific API in [OpenAPI](<https://spec.openapis.org/oas/latest.html>) format file.
428    pub async fn get_open_api(
429        &self,
430        id: uuid::Uuid,
431    ) -> Result<Vec<u8>, datadog::Error<GetOpenAPIError>> {
432        match self.get_open_api_with_http_info(id).await {
433            Ok(response_content) => {
434                if let Some(e) = response_content.entity {
435                    Ok(e)
436                } else {
437                    Err(datadog::Error::Serde(serde::de::Error::custom(
438                        "response content was None",
439                    )))
440                }
441            }
442            Err(err) => Err(err),
443        }
444    }
445
446    /// Retrieve information about a specific API in [OpenAPI](<https://spec.openapis.org/oas/latest.html>) format file.
447    pub async fn get_open_api_with_http_info(
448        &self,
449        id: uuid::Uuid,
450    ) -> Result<datadog::ResponseContent<Vec<u8>>, datadog::Error<GetOpenAPIError>> {
451        let local_configuration = &self.config;
452        let operation_id = "v2.get_open_api";
453        if local_configuration.is_unstable_operation_enabled(operation_id) {
454            warn!("Using unstable operation {operation_id}");
455        } else {
456            let local_error = datadog::UnstableOperationDisabledError {
457                msg: "Operation 'v2.get_open_api' is not enabled".to_string(),
458            };
459            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
460        }
461
462        let local_client = &self.client;
463
464        let local_uri_str = format!(
465            "{}/api/v2/apicatalog/api/{id}/openapi",
466            local_configuration.get_operation_host(operation_id),
467            id = datadog::urlencode(id.to_string())
468        );
469        let mut local_req_builder =
470            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
471
472        // build headers
473        let mut headers = HeaderMap::new();
474        headers.insert("Accept", HeaderValue::from_static("application/json"));
475
476        // build user agent
477        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
478            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
479            Err(e) => {
480                log::warn!("Failed to parse user agent header: {e}, falling back to default");
481                headers.insert(
482                    reqwest::header::USER_AGENT,
483                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
484                )
485            }
486        };
487
488        // build auth
489        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
490            headers.insert(
491                "DD-API-KEY",
492                HeaderValue::from_str(local_key.key.as_str())
493                    .expect("failed to parse DD-API-KEY header"),
494            );
495        };
496        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
497            headers.insert(
498                "DD-APPLICATION-KEY",
499                HeaderValue::from_str(local_key.key.as_str())
500                    .expect("failed to parse DD-APPLICATION-KEY header"),
501            );
502        };
503
504        local_req_builder = local_req_builder.headers(headers);
505        let local_req = local_req_builder.build()?;
506        log::debug!("request content: {:?}", local_req.body());
507        let local_resp = local_client.execute(local_req).await?;
508
509        let local_status = local_resp.status();
510        let local_content = local_resp.text().await?;
511        log::debug!("response content: {}", local_content);
512
513        if !local_status.is_client_error() && !local_status.is_server_error() {
514            Ok(datadog::ResponseContent {
515                status: local_status,
516                content: local_content.clone(),
517                entity: Some(local_content.into_bytes()),
518            })
519        } else {
520            let local_entity: Option<GetOpenAPIError> = serde_json::from_str(&local_content).ok();
521            let local_error = datadog::ResponseContent {
522                status: local_status,
523                content: local_content,
524                entity: local_entity,
525            };
526            Err(datadog::Error::ResponseError(local_error))
527        }
528    }
529
530    /// List APIs and their IDs.
531    pub async fn list_apis(
532        &self,
533        params: ListAPIsOptionalParams,
534    ) -> Result<crate::datadogV2::model::ListAPIsResponse, datadog::Error<ListAPIsError>> {
535        match self.list_apis_with_http_info(params).await {
536            Ok(response_content) => {
537                if let Some(e) = response_content.entity {
538                    Ok(e)
539                } else {
540                    Err(datadog::Error::Serde(serde::de::Error::custom(
541                        "response content was None",
542                    )))
543                }
544            }
545            Err(err) => Err(err),
546        }
547    }
548
549    /// List APIs and their IDs.
550    pub async fn list_apis_with_http_info(
551        &self,
552        params: ListAPIsOptionalParams,
553    ) -> Result<
554        datadog::ResponseContent<crate::datadogV2::model::ListAPIsResponse>,
555        datadog::Error<ListAPIsError>,
556    > {
557        let local_configuration = &self.config;
558        let operation_id = "v2.list_apis";
559        if local_configuration.is_unstable_operation_enabled(operation_id) {
560            warn!("Using unstable operation {operation_id}");
561        } else {
562            let local_error = datadog::UnstableOperationDisabledError {
563                msg: "Operation 'v2.list_apis' is not enabled".to_string(),
564            };
565            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
566        }
567
568        // unbox and build optional parameters
569        let query = params.query;
570        let page_limit = params.page_limit;
571        let page_offset = params.page_offset;
572
573        let local_client = &self.client;
574
575        let local_uri_str = format!(
576            "{}/api/v2/apicatalog/api",
577            local_configuration.get_operation_host(operation_id)
578        );
579        let mut local_req_builder =
580            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
581
582        if let Some(ref local_query_param) = query {
583            local_req_builder =
584                local_req_builder.query(&[("query", &local_query_param.to_string())]);
585        };
586        if let Some(ref local_query_param) = page_limit {
587            local_req_builder =
588                local_req_builder.query(&[("page[limit]", &local_query_param.to_string())]);
589        };
590        if let Some(ref local_query_param) = page_offset {
591            local_req_builder =
592                local_req_builder.query(&[("page[offset]", &local_query_param.to_string())]);
593        };
594
595        // build headers
596        let mut headers = HeaderMap::new();
597        headers.insert("Accept", HeaderValue::from_static("application/json"));
598
599        // build user agent
600        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
601            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
602            Err(e) => {
603                log::warn!("Failed to parse user agent header: {e}, falling back to default");
604                headers.insert(
605                    reqwest::header::USER_AGENT,
606                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
607                )
608            }
609        };
610
611        // build auth
612        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
613            headers.insert(
614                "DD-API-KEY",
615                HeaderValue::from_str(local_key.key.as_str())
616                    .expect("failed to parse DD-API-KEY header"),
617            );
618        };
619        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
620            headers.insert(
621                "DD-APPLICATION-KEY",
622                HeaderValue::from_str(local_key.key.as_str())
623                    .expect("failed to parse DD-APPLICATION-KEY header"),
624            );
625        };
626
627        local_req_builder = local_req_builder.headers(headers);
628        let local_req = local_req_builder.build()?;
629        log::debug!("request content: {:?}", local_req.body());
630        let local_resp = local_client.execute(local_req).await?;
631
632        let local_status = local_resp.status();
633        let local_content = local_resp.text().await?;
634        log::debug!("response content: {}", local_content);
635
636        if !local_status.is_client_error() && !local_status.is_server_error() {
637            match serde_json::from_str::<crate::datadogV2::model::ListAPIsResponse>(&local_content)
638            {
639                Ok(e) => {
640                    return Ok(datadog::ResponseContent {
641                        status: local_status,
642                        content: local_content,
643                        entity: Some(e),
644                    })
645                }
646                Err(e) => return Err(datadog::Error::Serde(e)),
647            };
648        } else {
649            let local_entity: Option<ListAPIsError> = serde_json::from_str(&local_content).ok();
650            let local_error = datadog::ResponseContent {
651                status: local_status,
652                content: local_content,
653                entity: local_entity,
654            };
655            Err(datadog::Error::ResponseError(local_error))
656        }
657    }
658
659    /// Update information about a specific API. The given content will replace all API content of the given ID.
660    /// The ID is returned by the create API, or can be found in the URL in the API catalog UI.
661    pub async fn update_open_api(
662        &self,
663        id: uuid::Uuid,
664        params: UpdateOpenAPIOptionalParams,
665    ) -> Result<crate::datadogV2::model::UpdateOpenAPIResponse, datadog::Error<UpdateOpenAPIError>>
666    {
667        match self.update_open_api_with_http_info(id, params).await {
668            Ok(response_content) => {
669                if let Some(e) = response_content.entity {
670                    Ok(e)
671                } else {
672                    Err(datadog::Error::Serde(serde::de::Error::custom(
673                        "response content was None",
674                    )))
675                }
676            }
677            Err(err) => Err(err),
678        }
679    }
680
681    /// Update information about a specific API. The given content will replace all API content of the given ID.
682    /// The ID is returned by the create API, or can be found in the URL in the API catalog UI.
683    pub async fn update_open_api_with_http_info(
684        &self,
685        id: uuid::Uuid,
686        params: UpdateOpenAPIOptionalParams,
687    ) -> Result<
688        datadog::ResponseContent<crate::datadogV2::model::UpdateOpenAPIResponse>,
689        datadog::Error<UpdateOpenAPIError>,
690    > {
691        let local_configuration = &self.config;
692        let operation_id = "v2.update_open_api";
693        if local_configuration.is_unstable_operation_enabled(operation_id) {
694            warn!("Using unstable operation {operation_id}");
695        } else {
696            let local_error = datadog::UnstableOperationDisabledError {
697                msg: "Operation 'v2.update_open_api' is not enabled".to_string(),
698            };
699            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
700        }
701
702        // unbox and build optional parameters
703        let openapi_spec_file = params.openapi_spec_file;
704
705        let local_client = &self.client;
706
707        let local_uri_str = format!(
708            "{}/api/v2/apicatalog/api/{id}/openapi",
709            local_configuration.get_operation_host(operation_id),
710            id = datadog::urlencode(id.to_string())
711        );
712        let mut local_req_builder =
713            local_client.request(reqwest::Method::PUT, local_uri_str.as_str());
714
715        // build headers
716        let mut headers = HeaderMap::new();
717        headers.insert(
718            "Content-Type",
719            HeaderValue::from_static("multipart/form-data"),
720        );
721        headers.insert("Accept", HeaderValue::from_static("application/json"));
722
723        // build user agent
724        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
725            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
726            Err(e) => {
727                log::warn!("Failed to parse user agent header: {e}, falling back to default");
728                headers.insert(
729                    reqwest::header::USER_AGENT,
730                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
731                )
732            }
733        };
734
735        // build auth
736        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
737            headers.insert(
738                "DD-API-KEY",
739                HeaderValue::from_str(local_key.key.as_str())
740                    .expect("failed to parse DD-API-KEY header"),
741            );
742        };
743        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
744            headers.insert(
745                "DD-APPLICATION-KEY",
746                HeaderValue::from_str(local_key.key.as_str())
747                    .expect("failed to parse DD-APPLICATION-KEY header"),
748            );
749        };
750
751        // build form parameters
752        if let Some(openapi_spec_file) = openapi_spec_file {
753            let mut local_form = form_data_builder::FormData::new(Vec::new());
754            let cursor = std::io::Cursor::new(openapi_spec_file);
755            if let Err(e) = local_form.write_file(
756                "openapi_spec_file",
757                cursor,
758                Some("openapi_spec_file".as_ref()),
759                "application/octet-stream",
760            ) {
761                return Err(crate::datadog::Error::Io(e));
762            };
763            headers.insert(
764                "Content-Type",
765                local_form.content_type_header().parse().unwrap(),
766            );
767            let form_result = local_form.finish();
768            match form_result {
769                Ok(form) => local_req_builder = local_req_builder.body(form),
770                Err(e) => return Err(crate::datadog::Error::Io(e)),
771            };
772        };
773
774        local_req_builder = local_req_builder.headers(headers);
775        let local_req = local_req_builder.build()?;
776        log::debug!("request content: {:?}", local_req.body());
777        let local_resp = local_client.execute(local_req).await?;
778
779        let local_status = local_resp.status();
780        let local_content = local_resp.text().await?;
781        log::debug!("response content: {}", local_content);
782
783        if !local_status.is_client_error() && !local_status.is_server_error() {
784            match serde_json::from_str::<crate::datadogV2::model::UpdateOpenAPIResponse>(
785                &local_content,
786            ) {
787                Ok(e) => {
788                    return Ok(datadog::ResponseContent {
789                        status: local_status,
790                        content: local_content,
791                        entity: Some(e),
792                    })
793                }
794                Err(e) => return Err(datadog::Error::Serde(e)),
795            };
796        } else {
797            let local_entity: Option<UpdateOpenAPIError> =
798                serde_json::from_str(&local_content).ok();
799            let local_error = datadog::ResponseContent {
800                status: local_status,
801                content: local_content,
802                entity: local_entity,
803            };
804            Err(datadog::Error::ResponseError(local_error))
805        }
806    }
807}