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    ///
186    pub async fn create_open_api(
187        &self,
188        params: CreateOpenAPIOptionalParams,
189    ) -> Result<crate::datadogV2::model::CreateOpenAPIResponse, datadog::Error<CreateOpenAPIError>>
190    {
191        match self.create_open_api_with_http_info(params).await {
192            Ok(response_content) => {
193                if let Some(e) = response_content.entity {
194                    Ok(e)
195                } else {
196                    Err(datadog::Error::Serde(serde::de::Error::custom(
197                        "response content was None",
198                    )))
199                }
200            }
201            Err(err) => Err(err),
202        }
203    }
204
205    /// Create a new API from the [OpenAPI](<https://spec.openapis.org/oas/latest.html>) specification given.
206    /// See the [API Catalog documentation](<https://docs.datadoghq.com/api_catalog/add_metadata/>) for additional
207    /// information about the possible metadata.
208    /// It returns the created API ID.
209    ///
210    pub async fn create_open_api_with_http_info(
211        &self,
212        params: CreateOpenAPIOptionalParams,
213    ) -> Result<
214        datadog::ResponseContent<crate::datadogV2::model::CreateOpenAPIResponse>,
215        datadog::Error<CreateOpenAPIError>,
216    > {
217        let local_configuration = &self.config;
218        let operation_id = "v2.create_open_api";
219        if local_configuration.is_unstable_operation_enabled(operation_id) {
220            warn!("Using unstable operation {operation_id}");
221        } else {
222            let local_error = datadog::UnstableOperationDisabledError {
223                msg: "Operation 'v2.create_open_api' is not enabled".to_string(),
224            };
225            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
226        }
227
228        // unbox and build optional parameters
229        let openapi_spec_file = params.openapi_spec_file;
230
231        let local_client = &self.client;
232
233        let local_uri_str = format!(
234            "{}/api/v2/apicatalog/openapi",
235            local_configuration.get_operation_host(operation_id)
236        );
237        let mut local_req_builder =
238            local_client.request(reqwest::Method::POST, local_uri_str.as_str());
239
240        // build headers
241        let mut headers = HeaderMap::new();
242        headers.insert(
243            "Content-Type",
244            HeaderValue::from_static("multipart/form-data"),
245        );
246        headers.insert("Accept", HeaderValue::from_static("application/json"));
247
248        // build user agent
249        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
250            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
251            Err(e) => {
252                log::warn!("Failed to parse user agent header: {e}, falling back to default");
253                headers.insert(
254                    reqwest::header::USER_AGENT,
255                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
256                )
257            }
258        };
259
260        // build auth
261        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
262            headers.insert(
263                "DD-API-KEY",
264                HeaderValue::from_str(local_key.key.as_str())
265                    .expect("failed to parse DD-API-KEY header"),
266            );
267        };
268        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
269            headers.insert(
270                "DD-APPLICATION-KEY",
271                HeaderValue::from_str(local_key.key.as_str())
272                    .expect("failed to parse DD-APPLICATION-KEY header"),
273            );
274        };
275
276        // build form parameters
277        if let Some(openapi_spec_file) = openapi_spec_file {
278            let mut local_form = form_data_builder::FormData::new(Vec::new());
279            let cursor = std::io::Cursor::new(openapi_spec_file);
280            if let Err(e) = local_form.write_file(
281                "openapi_spec_file",
282                cursor,
283                Some("openapi_spec_file".as_ref()),
284                "application/octet-stream",
285            ) {
286                return Err(crate::datadog::Error::Io(e));
287            };
288            headers.insert(
289                "Content-Type",
290                local_form.content_type_header().parse().unwrap(),
291            );
292            let form_result = local_form.finish();
293            match form_result {
294                Ok(form) => local_req_builder = local_req_builder.body(form),
295                Err(e) => return Err(crate::datadog::Error::Io(e)),
296            };
297        };
298
299        local_req_builder = local_req_builder.headers(headers);
300        let local_req = local_req_builder.build()?;
301        log::debug!("request content: {:?}", local_req.body());
302        let local_resp = local_client.execute(local_req).await?;
303
304        let local_status = local_resp.status();
305        let local_content = local_resp.text().await?;
306        log::debug!("response content: {}", local_content);
307
308        if !local_status.is_client_error() && !local_status.is_server_error() {
309            match serde_json::from_str::<crate::datadogV2::model::CreateOpenAPIResponse>(
310                &local_content,
311            ) {
312                Ok(e) => {
313                    return Ok(datadog::ResponseContent {
314                        status: local_status,
315                        content: local_content,
316                        entity: Some(e),
317                    })
318                }
319                Err(e) => return Err(datadog::Error::Serde(e)),
320            };
321        } else {
322            let local_entity: Option<CreateOpenAPIError> =
323                serde_json::from_str(&local_content).ok();
324            let local_error = datadog::ResponseContent {
325                status: local_status,
326                content: local_content,
327                entity: local_entity,
328            };
329            Err(datadog::Error::ResponseError(local_error))
330        }
331    }
332
333    /// Delete a specific API by ID.
334    pub async fn delete_open_api(
335        &self,
336        id: uuid::Uuid,
337    ) -> Result<(), datadog::Error<DeleteOpenAPIError>> {
338        match self.delete_open_api_with_http_info(id).await {
339            Ok(_) => Ok(()),
340            Err(err) => Err(err),
341        }
342    }
343
344    /// Delete a specific API by ID.
345    pub async fn delete_open_api_with_http_info(
346        &self,
347        id: uuid::Uuid,
348    ) -> Result<datadog::ResponseContent<()>, datadog::Error<DeleteOpenAPIError>> {
349        let local_configuration = &self.config;
350        let operation_id = "v2.delete_open_api";
351        if local_configuration.is_unstable_operation_enabled(operation_id) {
352            warn!("Using unstable operation {operation_id}");
353        } else {
354            let local_error = datadog::UnstableOperationDisabledError {
355                msg: "Operation 'v2.delete_open_api' is not enabled".to_string(),
356            };
357            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
358        }
359
360        let local_client = &self.client;
361
362        let local_uri_str = format!(
363            "{}/api/v2/apicatalog/api/{id}",
364            local_configuration.get_operation_host(operation_id),
365            id = datadog::urlencode(id.to_string())
366        );
367        let mut local_req_builder =
368            local_client.request(reqwest::Method::DELETE, local_uri_str.as_str());
369
370        // build headers
371        let mut headers = HeaderMap::new();
372        headers.insert("Accept", HeaderValue::from_static("*/*"));
373
374        // build user agent
375        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
376            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
377            Err(e) => {
378                log::warn!("Failed to parse user agent header: {e}, falling back to default");
379                headers.insert(
380                    reqwest::header::USER_AGENT,
381                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
382                )
383            }
384        };
385
386        // build auth
387        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
388            headers.insert(
389                "DD-API-KEY",
390                HeaderValue::from_str(local_key.key.as_str())
391                    .expect("failed to parse DD-API-KEY header"),
392            );
393        };
394        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
395            headers.insert(
396                "DD-APPLICATION-KEY",
397                HeaderValue::from_str(local_key.key.as_str())
398                    .expect("failed to parse DD-APPLICATION-KEY header"),
399            );
400        };
401
402        local_req_builder = local_req_builder.headers(headers);
403        let local_req = local_req_builder.build()?;
404        log::debug!("request content: {:?}", local_req.body());
405        let local_resp = local_client.execute(local_req).await?;
406
407        let local_status = local_resp.status();
408        let local_content = local_resp.text().await?;
409        log::debug!("response content: {}", local_content);
410
411        if !local_status.is_client_error() && !local_status.is_server_error() {
412            Ok(datadog::ResponseContent {
413                status: local_status,
414                content: local_content,
415                entity: None,
416            })
417        } else {
418            let local_entity: Option<DeleteOpenAPIError> =
419                serde_json::from_str(&local_content).ok();
420            let local_error = datadog::ResponseContent {
421                status: local_status,
422                content: local_content,
423                entity: local_entity,
424            };
425            Err(datadog::Error::ResponseError(local_error))
426        }
427    }
428
429    /// Retrieve information about a specific API in [OpenAPI](<https://spec.openapis.org/oas/latest.html>) format file.
430    pub async fn get_open_api(
431        &self,
432        id: uuid::Uuid,
433    ) -> Result<Vec<u8>, datadog::Error<GetOpenAPIError>> {
434        match self.get_open_api_with_http_info(id).await {
435            Ok(response_content) => {
436                if let Some(e) = response_content.entity {
437                    Ok(e)
438                } else {
439                    Err(datadog::Error::Serde(serde::de::Error::custom(
440                        "response content was None",
441                    )))
442                }
443            }
444            Err(err) => Err(err),
445        }
446    }
447
448    /// Retrieve information about a specific API in [OpenAPI](<https://spec.openapis.org/oas/latest.html>) format file.
449    pub async fn get_open_api_with_http_info(
450        &self,
451        id: uuid::Uuid,
452    ) -> Result<datadog::ResponseContent<Vec<u8>>, datadog::Error<GetOpenAPIError>> {
453        let local_configuration = &self.config;
454        let operation_id = "v2.get_open_api";
455        if local_configuration.is_unstable_operation_enabled(operation_id) {
456            warn!("Using unstable operation {operation_id}");
457        } else {
458            let local_error = datadog::UnstableOperationDisabledError {
459                msg: "Operation 'v2.get_open_api' is not enabled".to_string(),
460            };
461            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
462        }
463
464        let local_client = &self.client;
465
466        let local_uri_str = format!(
467            "{}/api/v2/apicatalog/api/{id}/openapi",
468            local_configuration.get_operation_host(operation_id),
469            id = datadog::urlencode(id.to_string())
470        );
471        let mut local_req_builder =
472            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
473
474        // build headers
475        let mut headers = HeaderMap::new();
476        headers.insert("Accept", HeaderValue::from_static("application/json"));
477
478        // build user agent
479        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
480            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
481            Err(e) => {
482                log::warn!("Failed to parse user agent header: {e}, falling back to default");
483                headers.insert(
484                    reqwest::header::USER_AGENT,
485                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
486                )
487            }
488        };
489
490        // build auth
491        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
492            headers.insert(
493                "DD-API-KEY",
494                HeaderValue::from_str(local_key.key.as_str())
495                    .expect("failed to parse DD-API-KEY header"),
496            );
497        };
498        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
499            headers.insert(
500                "DD-APPLICATION-KEY",
501                HeaderValue::from_str(local_key.key.as_str())
502                    .expect("failed to parse DD-APPLICATION-KEY header"),
503            );
504        };
505
506        local_req_builder = local_req_builder.headers(headers);
507        let local_req = local_req_builder.build()?;
508        log::debug!("request content: {:?}", local_req.body());
509        let local_resp = local_client.execute(local_req).await?;
510
511        let local_status = local_resp.status();
512        let local_content = local_resp.text().await?;
513        log::debug!("response content: {}", local_content);
514
515        if !local_status.is_client_error() && !local_status.is_server_error() {
516            Ok(datadog::ResponseContent {
517                status: local_status,
518                content: local_content.clone(),
519                entity: Some(local_content.into_bytes()),
520            })
521        } else {
522            let local_entity: Option<GetOpenAPIError> = serde_json::from_str(&local_content).ok();
523            let local_error = datadog::ResponseContent {
524                status: local_status,
525                content: local_content,
526                entity: local_entity,
527            };
528            Err(datadog::Error::ResponseError(local_error))
529        }
530    }
531
532    /// List APIs and their IDs.
533    pub async fn list_apis(
534        &self,
535        params: ListAPIsOptionalParams,
536    ) -> Result<crate::datadogV2::model::ListAPIsResponse, datadog::Error<ListAPIsError>> {
537        match self.list_apis_with_http_info(params).await {
538            Ok(response_content) => {
539                if let Some(e) = response_content.entity {
540                    Ok(e)
541                } else {
542                    Err(datadog::Error::Serde(serde::de::Error::custom(
543                        "response content was None",
544                    )))
545                }
546            }
547            Err(err) => Err(err),
548        }
549    }
550
551    /// List APIs and their IDs.
552    pub async fn list_apis_with_http_info(
553        &self,
554        params: ListAPIsOptionalParams,
555    ) -> Result<
556        datadog::ResponseContent<crate::datadogV2::model::ListAPIsResponse>,
557        datadog::Error<ListAPIsError>,
558    > {
559        let local_configuration = &self.config;
560        let operation_id = "v2.list_apis";
561        if local_configuration.is_unstable_operation_enabled(operation_id) {
562            warn!("Using unstable operation {operation_id}");
563        } else {
564            let local_error = datadog::UnstableOperationDisabledError {
565                msg: "Operation 'v2.list_apis' is not enabled".to_string(),
566            };
567            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
568        }
569
570        // unbox and build optional parameters
571        let query = params.query;
572        let page_limit = params.page_limit;
573        let page_offset = params.page_offset;
574
575        let local_client = &self.client;
576
577        let local_uri_str = format!(
578            "{}/api/v2/apicatalog/api",
579            local_configuration.get_operation_host(operation_id)
580        );
581        let mut local_req_builder =
582            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
583
584        if let Some(ref local_query_param) = query {
585            local_req_builder =
586                local_req_builder.query(&[("query", &local_query_param.to_string())]);
587        };
588        if let Some(ref local_query_param) = page_limit {
589            local_req_builder =
590                local_req_builder.query(&[("page[limit]", &local_query_param.to_string())]);
591        };
592        if let Some(ref local_query_param) = page_offset {
593            local_req_builder =
594                local_req_builder.query(&[("page[offset]", &local_query_param.to_string())]);
595        };
596
597        // build headers
598        let mut headers = HeaderMap::new();
599        headers.insert("Accept", HeaderValue::from_static("application/json"));
600
601        // build user agent
602        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
603            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
604            Err(e) => {
605                log::warn!("Failed to parse user agent header: {e}, falling back to default");
606                headers.insert(
607                    reqwest::header::USER_AGENT,
608                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
609                )
610            }
611        };
612
613        // build auth
614        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
615            headers.insert(
616                "DD-API-KEY",
617                HeaderValue::from_str(local_key.key.as_str())
618                    .expect("failed to parse DD-API-KEY header"),
619            );
620        };
621        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
622            headers.insert(
623                "DD-APPLICATION-KEY",
624                HeaderValue::from_str(local_key.key.as_str())
625                    .expect("failed to parse DD-APPLICATION-KEY header"),
626            );
627        };
628
629        local_req_builder = local_req_builder.headers(headers);
630        let local_req = local_req_builder.build()?;
631        log::debug!("request content: {:?}", local_req.body());
632        let local_resp = local_client.execute(local_req).await?;
633
634        let local_status = local_resp.status();
635        let local_content = local_resp.text().await?;
636        log::debug!("response content: {}", local_content);
637
638        if !local_status.is_client_error() && !local_status.is_server_error() {
639            match serde_json::from_str::<crate::datadogV2::model::ListAPIsResponse>(&local_content)
640            {
641                Ok(e) => {
642                    return Ok(datadog::ResponseContent {
643                        status: local_status,
644                        content: local_content,
645                        entity: Some(e),
646                    })
647                }
648                Err(e) => return Err(datadog::Error::Serde(e)),
649            };
650        } else {
651            let local_entity: Option<ListAPIsError> = serde_json::from_str(&local_content).ok();
652            let local_error = datadog::ResponseContent {
653                status: local_status,
654                content: local_content,
655                entity: local_entity,
656            };
657            Err(datadog::Error::ResponseError(local_error))
658        }
659    }
660
661    /// Update information about a specific API. The given content will replace all API content of the given ID.
662    /// The ID is returned by the create API, or can be found in the URL in the API catalog UI.
663    ///
664    pub async fn update_open_api(
665        &self,
666        id: uuid::Uuid,
667        params: UpdateOpenAPIOptionalParams,
668    ) -> Result<crate::datadogV2::model::UpdateOpenAPIResponse, datadog::Error<UpdateOpenAPIError>>
669    {
670        match self.update_open_api_with_http_info(id, params).await {
671            Ok(response_content) => {
672                if let Some(e) = response_content.entity {
673                    Ok(e)
674                } else {
675                    Err(datadog::Error::Serde(serde::de::Error::custom(
676                        "response content was None",
677                    )))
678                }
679            }
680            Err(err) => Err(err),
681        }
682    }
683
684    /// Update information about a specific API. The given content will replace all API content of the given ID.
685    /// The ID is returned by the create API, or can be found in the URL in the API catalog UI.
686    ///
687    pub async fn update_open_api_with_http_info(
688        &self,
689        id: uuid::Uuid,
690        params: UpdateOpenAPIOptionalParams,
691    ) -> Result<
692        datadog::ResponseContent<crate::datadogV2::model::UpdateOpenAPIResponse>,
693        datadog::Error<UpdateOpenAPIError>,
694    > {
695        let local_configuration = &self.config;
696        let operation_id = "v2.update_open_api";
697        if local_configuration.is_unstable_operation_enabled(operation_id) {
698            warn!("Using unstable operation {operation_id}");
699        } else {
700            let local_error = datadog::UnstableOperationDisabledError {
701                msg: "Operation 'v2.update_open_api' is not enabled".to_string(),
702            };
703            return Err(datadog::Error::UnstableOperationDisabledError(local_error));
704        }
705
706        // unbox and build optional parameters
707        let openapi_spec_file = params.openapi_spec_file;
708
709        let local_client = &self.client;
710
711        let local_uri_str = format!(
712            "{}/api/v2/apicatalog/api/{id}/openapi",
713            local_configuration.get_operation_host(operation_id),
714            id = datadog::urlencode(id.to_string())
715        );
716        let mut local_req_builder =
717            local_client.request(reqwest::Method::PUT, local_uri_str.as_str());
718
719        // build headers
720        let mut headers = HeaderMap::new();
721        headers.insert(
722            "Content-Type",
723            HeaderValue::from_static("multipart/form-data"),
724        );
725        headers.insert("Accept", HeaderValue::from_static("application/json"));
726
727        // build user agent
728        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
729            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
730            Err(e) => {
731                log::warn!("Failed to parse user agent header: {e}, falling back to default");
732                headers.insert(
733                    reqwest::header::USER_AGENT,
734                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
735                )
736            }
737        };
738
739        // build auth
740        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
741            headers.insert(
742                "DD-API-KEY",
743                HeaderValue::from_str(local_key.key.as_str())
744                    .expect("failed to parse DD-API-KEY header"),
745            );
746        };
747        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
748            headers.insert(
749                "DD-APPLICATION-KEY",
750                HeaderValue::from_str(local_key.key.as_str())
751                    .expect("failed to parse DD-APPLICATION-KEY header"),
752            );
753        };
754
755        // build form parameters
756        if let Some(openapi_spec_file) = openapi_spec_file {
757            let mut local_form = form_data_builder::FormData::new(Vec::new());
758            let cursor = std::io::Cursor::new(openapi_spec_file);
759            if let Err(e) = local_form.write_file(
760                "openapi_spec_file",
761                cursor,
762                Some("openapi_spec_file".as_ref()),
763                "application/octet-stream",
764            ) {
765                return Err(crate::datadog::Error::Io(e));
766            };
767            headers.insert(
768                "Content-Type",
769                local_form.content_type_header().parse().unwrap(),
770            );
771            let form_result = local_form.finish();
772            match form_result {
773                Ok(form) => local_req_builder = local_req_builder.body(form),
774                Err(e) => return Err(crate::datadog::Error::Io(e)),
775            };
776        };
777
778        local_req_builder = local_req_builder.headers(headers);
779        let local_req = local_req_builder.build()?;
780        log::debug!("request content: {:?}", local_req.body());
781        let local_resp = local_client.execute(local_req).await?;
782
783        let local_status = local_resp.status();
784        let local_content = local_resp.text().await?;
785        log::debug!("response content: {}", local_content);
786
787        if !local_status.is_client_error() && !local_status.is_server_error() {
788            match serde_json::from_str::<crate::datadogV2::model::UpdateOpenAPIResponse>(
789                &local_content,
790            ) {
791                Ok(e) => {
792                    return Ok(datadog::ResponseContent {
793                        status: local_status,
794                        content: local_content,
795                        entity: Some(e),
796                    })
797                }
798                Err(e) => return Err(datadog::Error::Serde(e)),
799            };
800        } else {
801            let local_entity: Option<UpdateOpenAPIError> =
802                serde_json::from_str(&local_content).ok();
803            let local_error = datadog::ResponseContent {
804                status: local_status,
805                content: local_content,
806                entity: local_entity,
807            };
808            Err(datadog::Error::ResponseError(local_error))
809        }
810    }
811}