diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index c26a927e83..fcdeca7c7c 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -73036,6 +73036,144 @@ components: type: string x-enum-varnames: - RULESET_STATUS + RumConfigAttributes: + description: Attributes of the RUM configuration. + properties: + disabled: + description: Whether the RUM configuration is disabled for the organization. + example: false + type: boolean + enforced_application_tags: + description: Whether application tags are enforced for the RUM applications in the organization. + example: true + type: boolean + enforced_application_tags_updated_at: + description: Timestamp of when the enforced application tags setting was last updated. + example: "2024-01-15T09:30:00.000Z" + format: date-time + type: string + enforced_application_tags_updated_by: + description: Handle of the user who last updated the enforced application tags setting. + example: "user@example.com" + type: string + ootb_metrics_version: + description: Version of the out-of-the-box metrics installed for the organization. + example: 5 + format: int64 + type: integer + ootb_metrics_version_installed_at: + description: Timestamp of when the out-of-the-box metrics version was installed. + example: "2024-01-15T09:30:00.000Z" + format: date-time + type: string + retention_filters_enabled: + description: Whether retention filters are enabled for the organization. + example: true + type: boolean + retention_filters_enabled_updated_at: + description: Timestamp of when the retention filters setting was last updated. + example: "2024-01-15T09:30:00.000Z" + format: date-time + type: string + retention_filters_enabled_updated_by: + description: Handle of the user or job who last updated the retention filters setting. + example: "contract-update-job" + type: string + required: + - enforced_application_tags + - retention_filters_enabled + type: object + RumConfigCreateAttributes: + description: Attributes of the RUM configuration to create. + properties: + enforced_application_tags: + description: Whether application tags are enforced for the RUM applications in the organization. + example: true + type: boolean + required: + - enforced_application_tags + type: object + RumConfigCreateData: + description: Object describing the RUM configuration to create. + properties: + attributes: + $ref: "#/components/schemas/RumConfigCreateAttributes" + type: + $ref: "#/components/schemas/RumConfigType" + required: + - type + - attributes + type: object + RumConfigCreateRequest: + description: Request body for creating the RUM configuration. + properties: + data: + $ref: "#/components/schemas/RumConfigCreateData" + required: + - data + type: object + RumConfigData: + description: The RUM configuration data. + properties: + attributes: + $ref: "#/components/schemas/RumConfigAttributes" + id: + description: The organization ID associated with the RUM configuration. + example: "1234" + type: string + type: + $ref: "#/components/schemas/RumConfigType" + required: + - id + - type + - attributes + type: object + RumConfigResponse: + description: The RUM configuration object. + properties: + data: + $ref: "#/components/schemas/RumConfigData" + required: + - data + type: object + RumConfigType: + default: rum_config + description: The type of the resource. The value should always be `rum_config`. + enum: + - rum_config + example: rum_config + type: string + x-enum-varnames: + - RUM_CONFIG + RumConfigUpdateAttributes: + description: Attributes of the RUM configuration to update. + properties: + enforced_application_tags: + description: Whether application tags are enforced for the RUM applications in the organization. + example: true + type: boolean + required: + - enforced_application_tags + type: object + RumConfigUpdateData: + description: Object describing the RUM configuration to update. + properties: + attributes: + $ref: "#/components/schemas/RumConfigUpdateAttributes" + type: + $ref: "#/components/schemas/RumConfigType" + required: + - type + - attributes + type: object + RumConfigUpdateRequest: + description: Request body for updating the RUM configuration. + properties: + data: + $ref: "#/components/schemas/RumConfigUpdateData" + required: + - data + type: object RumCrossProductSampling: description: The configuration for cross-product retention filters. properties: @@ -151423,6 +151561,153 @@ paths: operator: OR permissions: - rum_apps_write + /api/v2/rum/config: + get: + description: Get the RUM configuration for your organization. + operationId: GetRumConfig + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + disabled: false + enforced_application_tags: true + enforced_application_tags_updated_at: "2024-01-15T09:30:00.000Z" + enforced_application_tags_updated_by: "user@example.com" + ootb_metrics_version: 5 + ootb_metrics_version_installed_at: "2024-01-15T09:30:00.000Z" + retention_filters_enabled: true + retention_filters_enabled_updated_at: "2024-01-15T09:30:00.000Z" + retention_filters_enabled_updated_by: "contract-update-job" + id: "1234" + type: rum_config + schema: + $ref: "#/components/schemas/RumConfigResponse" + description: OK + "403": + $ref: "#/components/responses/NotAuthorizedResponse" + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + summary: Get the RUM configuration + tags: + - Rum Config + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + patch: + description: |- + Update the RUM configuration for your organization. + Returns the RUM configuration object from the request body when the request is successful. + operationId: UpdateRumConfig + requestBody: + content: + application/json: + examples: + default: + value: + data: + attributes: + enforced_application_tags: false + type: rum_config + schema: + $ref: "#/components/schemas/RumConfigUpdateRequest" + description: New definition of the RUM configuration. + required: true + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + disabled: false + enforced_application_tags: false + enforced_application_tags_updated_at: "2024-01-15T09:30:00.000Z" + enforced_application_tags_updated_by: "user@example.com" + ootb_metrics_version: 5 + ootb_metrics_version_installed_at: "2024-01-15T09:30:00.000Z" + retention_filters_enabled: true + retention_filters_enabled_updated_at: "2024-01-15T09:30:00.000Z" + retention_filters_enabled_updated_by: "contract-update-job" + id: "1234" + type: rum_config + schema: + $ref: "#/components/schemas/RumConfigResponse" + description: OK + "400": + $ref: "#/components/responses/BadRequestResponse" + "403": + $ref: "#/components/responses/NotAuthorizedResponse" + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + summary: Update the RUM configuration + tags: + - Rum Config + x-codegen-request-body-name: body + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + post: + description: |- + Create the RUM configuration for your organization. + Returns the RUM configuration object from the request body when the request is successful. + operationId: CreateRumConfig + requestBody: + content: + application/json: + examples: + default: + value: + data: + attributes: + enforced_application_tags: true + type: rum_config + schema: + $ref: "#/components/schemas/RumConfigCreateRequest" + description: The definition of the RUM configuration to create. + required: true + responses: + "201": + content: + application/json: + examples: + default: + value: + data: + attributes: + disabled: false + enforced_application_tags: true + enforced_application_tags_updated_at: "2024-01-15T09:30:00.000Z" + enforced_application_tags_updated_by: "user@example.com" + ootb_metrics_version: 5 + ootb_metrics_version_installed_at: "2024-01-15T09:30:00.000Z" + retention_filters_enabled: true + retention_filters_enabled_updated_at: "2024-01-15T09:30:00.000Z" + retention_filters_enabled_updated_by: "contract-update-job" + id: "1234" + type: rum_config + schema: + $ref: "#/components/schemas/RumConfigResponse" + description: Created + "400": + $ref: "#/components/responses/BadRequestResponse" + "403": + $ref: "#/components/responses/NotAuthorizedResponse" + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + summary: Create the RUM configuration + tags: + - Rum Config + x-codegen-request-body-name: body + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). /api/v2/rum/config/metrics: get: description: Get the list of configured RUM-based metrics with their definitions. @@ -176491,6 +176776,12 @@ tags: name: Roles - description: Auto-generated tag Rum Audience Management name: Rum Audience Management + - description: |- + Manage the [Real User Monitoring (RUM)](https://docs.datadoghq.com/real_user_monitoring/) configuration for your organization. + externalDocs: + description: Find out more at + url: https://docs.datadoghq.com/real_user_monitoring/ + name: Rum Config - description: |- Manage configuration of [RUM-based metrics](https://app.datadoghq.com/rum/generate-metrics) for your organization. externalDocs: diff --git a/examples/v2_rum-config_CreateRumConfig.rs b/examples/v2_rum-config_CreateRumConfig.rs new file mode 100644 index 0000000000..9063bf86e2 --- /dev/null +++ b/examples/v2_rum-config_CreateRumConfig.rs @@ -0,0 +1,24 @@ +// Create the RUM configuration returns "Created" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_rum_config::RumConfigAPI; +use datadog_api_client::datadogV2::model::RumConfigCreateAttributes; +use datadog_api_client::datadogV2::model::RumConfigCreateData; +use datadog_api_client::datadogV2::model::RumConfigCreateRequest; +use datadog_api_client::datadogV2::model::RumConfigType; + +#[tokio::main] +async fn main() { + let body = RumConfigCreateRequest::new(RumConfigCreateData::new( + RumConfigCreateAttributes::new(true), + RumConfigType::RUM_CONFIG, + )); + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.CreateRumConfig", true); + let api = RumConfigAPI::with_config(configuration); + let resp = api.create_rum_config(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_rum-config_GetRumConfig.rs b/examples/v2_rum-config_GetRumConfig.rs new file mode 100644 index 0000000000..a4350f04e6 --- /dev/null +++ b/examples/v2_rum-config_GetRumConfig.rs @@ -0,0 +1,16 @@ +// Get the RUM configuration returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_rum_config::RumConfigAPI; + +#[tokio::main] +async fn main() { + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.GetRumConfig", true); + let api = RumConfigAPI::with_config(configuration); + let resp = api.get_rum_config().await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_rum-config_UpdateRumConfig.rs b/examples/v2_rum-config_UpdateRumConfig.rs new file mode 100644 index 0000000000..4169bf732d --- /dev/null +++ b/examples/v2_rum-config_UpdateRumConfig.rs @@ -0,0 +1,24 @@ +// Update the RUM configuration returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_rum_config::RumConfigAPI; +use datadog_api_client::datadogV2::model::RumConfigType; +use datadog_api_client::datadogV2::model::RumConfigUpdateAttributes; +use datadog_api_client::datadogV2::model::RumConfigUpdateData; +use datadog_api_client::datadogV2::model::RumConfigUpdateRequest; + +#[tokio::main] +async fn main() { + let body = RumConfigUpdateRequest::new(RumConfigUpdateData::new( + RumConfigUpdateAttributes::new(true), + RumConfigType::RUM_CONFIG, + )); + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.UpdateRumConfig", true); + let api = RumConfigAPI::with_config(configuration); + let resp = api.update_rum_config(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/src/datadog/configuration.rs b/src/datadog/configuration.rs index e8d7176272..4a994a6b61 100644 --- a/src/datadog/configuration.rs +++ b/src/datadog/configuration.rs @@ -590,6 +590,9 @@ impl Default for Configuration { ("v2.update_connection".to_owned(), false), ("v2.get_pruned_trace_by_id".to_owned(), false), ("v2.get_trace_by_id".to_owned(), false), + ("v2.create_rum_config".to_owned(), false), + ("v2.get_rum_config".to_owned(), false), + ("v2.update_rum_config".to_owned(), false), ("v2.query_aggregated_long_tasks".to_owned(), false), ("v2.query_aggregated_signals_problems".to_owned(), false), ("v2.query_aggregated_waterfall".to_owned(), false), diff --git a/src/datadogV2/api/api_rum_config.rs b/src/datadogV2/api/api_rum_config.rs new file mode 100644 index 0000000000..27bcb663b2 --- /dev/null +++ b/src/datadogV2/api/api_rum_config.rs @@ -0,0 +1,544 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use crate::datadog; +use flate2::{ + write::{GzEncoder, ZlibEncoder}, + Compression, +}; +use log::warn; +use reqwest::header::{HeaderMap, HeaderValue}; +use serde::{Deserialize, Serialize}; +use std::io::Write; + +/// CreateRumConfigError is a struct for typed errors of method [`RumConfigAPI::create_rum_config`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum CreateRumConfigError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + +/// GetRumConfigError is a struct for typed errors of method [`RumConfigAPI::get_rum_config`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetRumConfigError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + +/// UpdateRumConfigError is a struct for typed errors of method [`RumConfigAPI::update_rum_config`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum UpdateRumConfigError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + +/// Manage the [Real User Monitoring (RUM)]() configuration for your organization. +#[derive(Debug, Clone)] +pub struct RumConfigAPI { + config: datadog::Configuration, + client: reqwest_middleware::ClientWithMiddleware, +} + +impl Default for RumConfigAPI { + fn default() -> Self { + Self::with_config(datadog::Configuration::default()) + } +} + +impl RumConfigAPI { + pub fn new() -> Self { + Self::default() + } + pub fn with_config(config: datadog::Configuration) -> Self { + let reqwest_client_builder = { + let builder = reqwest::Client::builder(); + #[cfg(not(target_arch = "wasm32"))] + let builder = if let Some(proxy_url) = &config.proxy_url { + builder.proxy(reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL")) + } else { + builder + }; + builder + }; + + let middleware_client_builder = { + let builder = + reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap()); + #[cfg(feature = "retry")] + let builder = if config.enable_retry { + struct RetryableStatus; + impl reqwest_retry::RetryableStrategy for RetryableStatus { + fn handle( + &self, + res: &Result, + ) -> Option { + match res { + Ok(success) => reqwest_retry::default_on_request_success(success), + Err(_) => None, + } + } + } + let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder() + .build_with_max_retries(config.max_retries); + + let retry_middleware = + reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy( + backoff_policy, + RetryableStatus, + ); + + builder.with(retry_middleware) + } else { + builder + }; + builder + }; + + let client = middleware_client_builder.build(); + + Self { config, client } + } + + pub fn with_client_and_config( + config: datadog::Configuration, + client: reqwest_middleware::ClientWithMiddleware, + ) -> Self { + Self { config, client } + } + + /// Create the RUM configuration for your organization. + /// Returns the RUM configuration object from the request body when the request is successful. + pub async fn create_rum_config( + &self, + body: crate::datadogV2::model::RumConfigCreateRequest, + ) -> Result> + { + match self.create_rum_config_with_http_info(body).await { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Create the RUM configuration for your organization. + /// Returns the RUM configuration object from the request body when the request is successful. + pub async fn create_rum_config_with_http_info( + &self, + body: crate::datadogV2::model::RumConfigCreateRequest, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.create_rum_config"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.create_rum_config' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/rum/config", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::POST, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + #[cfg(feature = "zstd")] + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::(&local_content) + { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + + /// Get the RUM configuration for your organization. + pub async fn get_rum_config( + &self, + ) -> Result> { + match self.get_rum_config_with_http_info().await { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Get the RUM configuration for your organization. + pub async fn get_rum_config_with_http_info( + &self, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.get_rum_config"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.get_rum_config' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/rum/config", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::GET, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::(&local_content) + { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + + /// Update the RUM configuration for your organization. + /// Returns the RUM configuration object from the request body when the request is successful. + pub async fn update_rum_config( + &self, + body: crate::datadogV2::model::RumConfigUpdateRequest, + ) -> Result> + { + match self.update_rum_config_with_http_info(body).await { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Update the RUM configuration for your organization. + /// Returns the RUM configuration object from the request body when the request is successful. + pub async fn update_rum_config_with_http_info( + &self, + body: crate::datadogV2::model::RumConfigUpdateRequest, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.update_rum_config"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.update_rum_config' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/rum/config", + local_configuration.get_operation_host(operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::PATCH, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + #[cfg(feature = "zstd")] + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::(&local_content) + { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } +} diff --git a/src/datadogV2/api/mod.rs b/src/datadogV2/api/mod.rs index b3b335bf6f..b3647dc19b 100644 --- a/src/datadogV2/api/mod.rs +++ b/src/datadogV2/api/mod.rs @@ -89,6 +89,7 @@ pub mod api_restriction_policies; pub mod api_roles; pub mod api_rum; pub mod api_rum_audience_management; +pub mod api_rum_config; pub mod api_rum_insights; pub mod api_rum_metrics; pub mod api_rum_replay_heatmaps; diff --git a/src/datadogV2/mod.rs b/src/datadogV2/mod.rs index dc464d2c8d..674386b2d9 100644 --- a/src/datadogV2/mod.rs +++ b/src/datadogV2/mod.rs @@ -90,6 +90,7 @@ pub use self::api::api_restriction_policies; pub use self::api::api_roles; pub use self::api::api_rum; pub use self::api::api_rum_audience_management; +pub use self::api::api_rum_config; pub use self::api::api_rum_insights; pub use self::api::api_rum_metrics; pub use self::api::api_rum_replay_heatmaps; diff --git a/src/datadogV2/model/mod.rs b/src/datadogV2/model/mod.rs index 544a0fa1c2..a9db6fe7b2 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -8720,6 +8720,26 @@ pub mod model_rum_application_update_attributes; pub use self::model_rum_application_update_attributes::RUMApplicationUpdateAttributes; pub mod model_rum_application_update_type; pub use self::model_rum_application_update_type::RUMApplicationUpdateType; +pub mod model_rum_config_response; +pub use self::model_rum_config_response::RumConfigResponse; +pub mod model_rum_config_data; +pub use self::model_rum_config_data::RumConfigData; +pub mod model_rum_config_attributes; +pub use self::model_rum_config_attributes::RumConfigAttributes; +pub mod model_rum_config_type; +pub use self::model_rum_config_type::RumConfigType; +pub mod model_rum_config_update_request; +pub use self::model_rum_config_update_request::RumConfigUpdateRequest; +pub mod model_rum_config_update_data; +pub use self::model_rum_config_update_data::RumConfigUpdateData; +pub mod model_rum_config_update_attributes; +pub use self::model_rum_config_update_attributes::RumConfigUpdateAttributes; +pub mod model_rum_config_create_request; +pub use self::model_rum_config_create_request::RumConfigCreateRequest; +pub mod model_rum_config_create_data; +pub use self::model_rum_config_create_data::RumConfigCreateData; +pub mod model_rum_config_create_attributes; +pub use self::model_rum_config_create_attributes::RumConfigCreateAttributes; pub mod model_rum_metrics_response; pub use self::model_rum_metrics_response::RumMetricsResponse; pub mod model_rum_metric_response_data; diff --git a/src/datadogV2/model/model_rum_config_attributes.rs b/src/datadogV2/model/model_rum_config_attributes.rs new file mode 100644 index 0000000000..b9d7562da9 --- /dev/null +++ b/src/datadogV2/model/model_rum_config_attributes.rs @@ -0,0 +1,248 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of the RUM configuration. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct RumConfigAttributes { + /// Whether the RUM configuration is disabled for the organization. + #[serde(rename = "disabled")] + pub disabled: Option, + /// Whether application tags are enforced for the RUM applications in the organization. + #[serde(rename = "enforced_application_tags")] + pub enforced_application_tags: bool, + /// Timestamp of when the enforced application tags setting was last updated. + #[serde(rename = "enforced_application_tags_updated_at")] + pub enforced_application_tags_updated_at: Option>, + /// Handle of the user who last updated the enforced application tags setting. + #[serde(rename = "enforced_application_tags_updated_by")] + pub enforced_application_tags_updated_by: Option, + /// Version of the out-of-the-box metrics installed for the organization. + #[serde(rename = "ootb_metrics_version")] + pub ootb_metrics_version: Option, + /// Timestamp of when the out-of-the-box metrics version was installed. + #[serde(rename = "ootb_metrics_version_installed_at")] + pub ootb_metrics_version_installed_at: Option>, + /// Whether retention filters are enabled for the organization. + #[serde(rename = "retention_filters_enabled")] + pub retention_filters_enabled: bool, + /// Timestamp of when the retention filters setting was last updated. + #[serde(rename = "retention_filters_enabled_updated_at")] + pub retention_filters_enabled_updated_at: Option>, + /// Handle of the user or job who last updated the retention filters setting. + #[serde(rename = "retention_filters_enabled_updated_by")] + pub retention_filters_enabled_updated_by: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl RumConfigAttributes { + pub fn new( + enforced_application_tags: bool, + retention_filters_enabled: bool, + ) -> RumConfigAttributes { + RumConfigAttributes { + disabled: None, + enforced_application_tags, + enforced_application_tags_updated_at: None, + enforced_application_tags_updated_by: None, + ootb_metrics_version: None, + ootb_metrics_version_installed_at: None, + retention_filters_enabled, + retention_filters_enabled_updated_at: None, + retention_filters_enabled_updated_by: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn disabled(mut self, value: bool) -> Self { + self.disabled = Some(value); + self + } + + pub fn enforced_application_tags_updated_at( + mut self, + value: chrono::DateTime, + ) -> Self { + self.enforced_application_tags_updated_at = Some(value); + self + } + + pub fn enforced_application_tags_updated_by(mut self, value: String) -> Self { + self.enforced_application_tags_updated_by = Some(value); + self + } + + pub fn ootb_metrics_version(mut self, value: i64) -> Self { + self.ootb_metrics_version = Some(value); + self + } + + pub fn ootb_metrics_version_installed_at( + mut self, + value: chrono::DateTime, + ) -> Self { + self.ootb_metrics_version_installed_at = Some(value); + self + } + + pub fn retention_filters_enabled_updated_at( + mut self, + value: chrono::DateTime, + ) -> Self { + self.retention_filters_enabled_updated_at = Some(value); + self + } + + pub fn retention_filters_enabled_updated_by(mut self, value: String) -> Self { + self.retention_filters_enabled_updated_by = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for RumConfigAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct RumConfigAttributesVisitor; + impl<'a> Visitor<'a> for RumConfigAttributesVisitor { + type Value = RumConfigAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut disabled: Option = None; + let mut enforced_application_tags: Option = None; + let mut enforced_application_tags_updated_at: Option< + chrono::DateTime, + > = None; + let mut enforced_application_tags_updated_by: Option = None; + let mut ootb_metrics_version: Option = None; + let mut ootb_metrics_version_installed_at: Option> = + None; + let mut retention_filters_enabled: Option = None; + let mut retention_filters_enabled_updated_at: Option< + chrono::DateTime, + > = None; + let mut retention_filters_enabled_updated_by: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "disabled" => { + if v.is_null() { + continue; + } + disabled = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "enforced_application_tags" => { + enforced_application_tags = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "enforced_application_tags_updated_at" => { + if v.is_null() { + continue; + } + enforced_application_tags_updated_at = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "enforced_application_tags_updated_by" => { + if v.is_null() { + continue; + } + enforced_application_tags_updated_by = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "ootb_metrics_version" => { + if v.is_null() { + continue; + } + ootb_metrics_version = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "ootb_metrics_version_installed_at" => { + if v.is_null() { + continue; + } + ootb_metrics_version_installed_at = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "retention_filters_enabled" => { + retention_filters_enabled = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "retention_filters_enabled_updated_at" => { + if v.is_null() { + continue; + } + retention_filters_enabled_updated_at = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "retention_filters_enabled_updated_by" => { + if v.is_null() { + continue; + } + retention_filters_enabled_updated_by = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let enforced_application_tags = enforced_application_tags + .ok_or_else(|| M::Error::missing_field("enforced_application_tags"))?; + let retention_filters_enabled = retention_filters_enabled + .ok_or_else(|| M::Error::missing_field("retention_filters_enabled"))?; + + let content = RumConfigAttributes { + disabled, + enforced_application_tags, + enforced_application_tags_updated_at, + enforced_application_tags_updated_by, + ootb_metrics_version, + ootb_metrics_version_installed_at, + retention_filters_enabled, + retention_filters_enabled_updated_at, + retention_filters_enabled_updated_by, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(RumConfigAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_rum_config_create_attributes.rs b/src/datadogV2/model/model_rum_config_create_attributes.rs new file mode 100644 index 0000000000..4a88d3e393 --- /dev/null +++ b/src/datadogV2/model/model_rum_config_create_attributes.rs @@ -0,0 +1,94 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of the RUM configuration to create. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct RumConfigCreateAttributes { + /// Whether application tags are enforced for the RUM applications in the organization. + #[serde(rename = "enforced_application_tags")] + pub enforced_application_tags: bool, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl RumConfigCreateAttributes { + pub fn new(enforced_application_tags: bool) -> RumConfigCreateAttributes { + RumConfigCreateAttributes { + enforced_application_tags, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for RumConfigCreateAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct RumConfigCreateAttributesVisitor; + impl<'a> Visitor<'a> for RumConfigCreateAttributesVisitor { + type Value = RumConfigCreateAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut enforced_application_tags: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "enforced_application_tags" => { + enforced_application_tags = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let enforced_application_tags = enforced_application_tags + .ok_or_else(|| M::Error::missing_field("enforced_application_tags"))?; + + let content = RumConfigCreateAttributes { + enforced_application_tags, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(RumConfigCreateAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_rum_config_create_data.rs b/src/datadogV2/model/model_rum_config_create_data.rs new file mode 100644 index 0000000000..3062a7331b --- /dev/null +++ b/src/datadogV2/model/model_rum_config_create_data.rs @@ -0,0 +1,116 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Object describing the RUM configuration to create. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct RumConfigCreateData { + /// Attributes of the RUM configuration to create. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::RumConfigCreateAttributes, + /// The type of the resource. The value should always be `rum_config`. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::RumConfigType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl RumConfigCreateData { + pub fn new( + attributes: crate::datadogV2::model::RumConfigCreateAttributes, + type_: crate::datadogV2::model::RumConfigType, + ) -> RumConfigCreateData { + RumConfigCreateData { + attributes, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for RumConfigCreateData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct RumConfigCreateDataVisitor; + impl<'a> Visitor<'a> for RumConfigCreateDataVisitor { + type Value = RumConfigCreateData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option = + None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::RumConfigType::UnparsedObject( + _type_, + ) => { + _unparsed = true; + } + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = RumConfigCreateData { + attributes, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(RumConfigCreateDataVisitor) + } +} diff --git a/src/datadogV2/model/model_rum_config_create_request.rs b/src/datadogV2/model/model_rum_config_create_request.rs new file mode 100644 index 0000000000..d1f4707d6f --- /dev/null +++ b/src/datadogV2/model/model_rum_config_create_request.rs @@ -0,0 +1,92 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Request body for creating the RUM configuration. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct RumConfigCreateRequest { + /// Object describing the RUM configuration to create. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::RumConfigCreateData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl RumConfigCreateRequest { + pub fn new(data: crate::datadogV2::model::RumConfigCreateData) -> RumConfigCreateRequest { + RumConfigCreateRequest { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for RumConfigCreateRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct RumConfigCreateRequestVisitor; + impl<'a> Visitor<'a> for RumConfigCreateRequestVisitor { + type Value = RumConfigCreateRequest; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = RumConfigCreateRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(RumConfigCreateRequestVisitor) + } +} diff --git a/src/datadogV2/model/model_rum_config_data.rs b/src/datadogV2/model/model_rum_config_data.rs new file mode 100644 index 0000000000..98021564ca --- /dev/null +++ b/src/datadogV2/model/model_rum_config_data.rs @@ -0,0 +1,126 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// The RUM configuration data. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct RumConfigData { + /// Attributes of the RUM configuration. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::RumConfigAttributes, + /// The organization ID associated with the RUM configuration. + #[serde(rename = "id")] + pub id: String, + /// The type of the resource. The value should always be `rum_config`. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::RumConfigType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl RumConfigData { + pub fn new( + attributes: crate::datadogV2::model::RumConfigAttributes, + id: String, + type_: crate::datadogV2::model::RumConfigType, + ) -> RumConfigData { + RumConfigData { + attributes, + id, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for RumConfigData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct RumConfigDataVisitor; + impl<'a> Visitor<'a> for RumConfigDataVisitor { + type Value = RumConfigData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option = None; + let mut id: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::RumConfigType::UnparsedObject( + _type_, + ) => { + _unparsed = true; + } + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let id = id.ok_or_else(|| M::Error::missing_field("id"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = RumConfigData { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(RumConfigDataVisitor) + } +} diff --git a/src/datadogV2/model/model_rum_config_response.rs b/src/datadogV2/model/model_rum_config_response.rs new file mode 100644 index 0000000000..ef93519746 --- /dev/null +++ b/src/datadogV2/model/model_rum_config_response.rs @@ -0,0 +1,92 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// The RUM configuration object. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct RumConfigResponse { + /// The RUM configuration data. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::RumConfigData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl RumConfigResponse { + pub fn new(data: crate::datadogV2::model::RumConfigData) -> RumConfigResponse { + RumConfigResponse { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for RumConfigResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct RumConfigResponseVisitor; + impl<'a> Visitor<'a> for RumConfigResponseVisitor { + type Value = RumConfigResponse; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = RumConfigResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(RumConfigResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_rum_config_type.rs b/src/datadogV2/model/model_rum_config_type.rs new file mode 100644 index 0000000000..a2f73e313c --- /dev/null +++ b/src/datadogV2/model/model_rum_config_type.rs @@ -0,0 +1,48 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum RumConfigType { + RUM_CONFIG, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for RumConfigType { + fn to_string(&self) -> String { + match self { + Self::RUM_CONFIG => String::from("rum_config"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for RumConfigType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for RumConfigType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "rum_config" => Self::RUM_CONFIG, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_rum_config_update_attributes.rs b/src/datadogV2/model/model_rum_config_update_attributes.rs new file mode 100644 index 0000000000..d657606ef2 --- /dev/null +++ b/src/datadogV2/model/model_rum_config_update_attributes.rs @@ -0,0 +1,94 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of the RUM configuration to update. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct RumConfigUpdateAttributes { + /// Whether application tags are enforced for the RUM applications in the organization. + #[serde(rename = "enforced_application_tags")] + pub enforced_application_tags: bool, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl RumConfigUpdateAttributes { + pub fn new(enforced_application_tags: bool) -> RumConfigUpdateAttributes { + RumConfigUpdateAttributes { + enforced_application_tags, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for RumConfigUpdateAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct RumConfigUpdateAttributesVisitor; + impl<'a> Visitor<'a> for RumConfigUpdateAttributesVisitor { + type Value = RumConfigUpdateAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut enforced_application_tags: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "enforced_application_tags" => { + enforced_application_tags = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let enforced_application_tags = enforced_application_tags + .ok_or_else(|| M::Error::missing_field("enforced_application_tags"))?; + + let content = RumConfigUpdateAttributes { + enforced_application_tags, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(RumConfigUpdateAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_rum_config_update_data.rs b/src/datadogV2/model/model_rum_config_update_data.rs new file mode 100644 index 0000000000..487878f0a6 --- /dev/null +++ b/src/datadogV2/model/model_rum_config_update_data.rs @@ -0,0 +1,116 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Object describing the RUM configuration to update. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct RumConfigUpdateData { + /// Attributes of the RUM configuration to update. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::RumConfigUpdateAttributes, + /// The type of the resource. The value should always be `rum_config`. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::RumConfigType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl RumConfigUpdateData { + pub fn new( + attributes: crate::datadogV2::model::RumConfigUpdateAttributes, + type_: crate::datadogV2::model::RumConfigType, + ) -> RumConfigUpdateData { + RumConfigUpdateData { + attributes, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for RumConfigUpdateData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct RumConfigUpdateDataVisitor; + impl<'a> Visitor<'a> for RumConfigUpdateDataVisitor { + type Value = RumConfigUpdateData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option = + None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::RumConfigType::UnparsedObject( + _type_, + ) => { + _unparsed = true; + } + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = RumConfigUpdateData { + attributes, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(RumConfigUpdateDataVisitor) + } +} diff --git a/src/datadogV2/model/model_rum_config_update_request.rs b/src/datadogV2/model/model_rum_config_update_request.rs new file mode 100644 index 0000000000..c40cc74908 --- /dev/null +++ b/src/datadogV2/model/model_rum_config_update_request.rs @@ -0,0 +1,92 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Request body for updating the RUM configuration. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct RumConfigUpdateRequest { + /// Object describing the RUM configuration to update. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::RumConfigUpdateData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl RumConfigUpdateRequest { + pub fn new(data: crate::datadogV2::model::RumConfigUpdateData) -> RumConfigUpdateRequest { + RumConfigUpdateRequest { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for RumConfigUpdateRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct RumConfigUpdateRequestVisitor; + impl<'a> Visitor<'a> for RumConfigUpdateRequestVisitor { + type Value = RumConfigUpdateRequest; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = RumConfigUpdateRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(RumConfigUpdateRequestVisitor) + } +} diff --git a/tests/scenarios/features/v2/rum_config.feature b/tests/scenarios/features/v2/rum_config.feature new file mode 100644 index 0000000000..e403c3fc9b --- /dev/null +++ b/tests/scenarios/features/v2/rum_config.feature @@ -0,0 +1,49 @@ +@endpoint(rum-config) @endpoint(rum-config-v2) +Feature: Rum Config + Manage the [Real User Monitoring + (RUM)](https://docs.datadoghq.com/real_user_monitoring/) configuration for + your organization. + + Background: + Given a valid "apiKeyAuth" key in the system + And a valid "appKeyAuth" key in the system + And an instance of "RumConfig" API + + @generated @skip @team:DataDog/rum-backend + Scenario: Create the RUM configuration returns "Bad Request" response + Given operation "CreateRumConfig" enabled + And new "CreateRumConfig" request + And body with value {"data": {"attributes": {"enforced_application_tags": true}, "type": "rum_config"}} + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/rum-backend + Scenario: Create the RUM configuration returns "Created" response + Given operation "CreateRumConfig" enabled + And new "CreateRumConfig" request + And body with value {"data": {"attributes": {"enforced_application_tags": true}, "type": "rum_config"}} + When the request is sent + Then the response status is 201 Created + + @generated @skip @team:DataDog/rum-backend + Scenario: Get the RUM configuration returns "OK" response + Given operation "GetRumConfig" enabled + And new "GetRumConfig" request + When the request is sent + Then the response status is 200 OK + + @generated @skip @team:DataDog/rum-backend + Scenario: Update the RUM configuration returns "Bad Request" response + Given operation "UpdateRumConfig" enabled + And new "UpdateRumConfig" request + And body with value {"data": {"attributes": {"enforced_application_tags": true}, "type": "rum_config"}} + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/rum-backend + Scenario: Update the RUM configuration returns "OK" response + Given operation "UpdateRumConfig" enabled + And new "UpdateRumConfig" request + And body with value {"data": {"attributes": {"enforced_application_tags": true}, "type": "rum_config"}} + When the request is sent + Then the response status is 200 OK diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index 211637b239..aafeaa1df8 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -6120,6 +6120,24 @@ "type": "idempotent" } }, + "GetRumConfig": { + "tag": "Rum Config", + "undo": { + "type": "safe" + } + }, + "UpdateRumConfig": { + "tag": "Rum Config", + "undo": { + "type": "idempotent" + } + }, + "CreateRumConfig": { + "tag": "Rum Config", + "undo": { + "type": "idempotent" + } + }, "ListRumMetrics": { "tag": "Rum Metrics", "undo": { diff --git a/tests/scenarios/function_mappings.rs b/tests/scenarios/function_mappings.rs index c128538fa5..bd317c88ef 100644 --- a/tests/scenarios/function_mappings.rs +++ b/tests/scenarios/function_mappings.rs @@ -181,6 +181,7 @@ pub struct ApiInstances { Option, pub v2_api_rum_retention_filters: Option, + pub v2_api_rum_config: Option, pub v2_api_rum_metrics: Option, pub v2_api_rum_insights: Option, pub v2_api_rum_replay_playlists: @@ -1166,6 +1167,14 @@ pub fn initialize_api_instance(world: &mut DatadogWorld, api: String) { world.http_client.as_ref().unwrap().clone() )); } + "RumConfig" => { + world.api_instances.v2_api_rum_config = Some( + datadogV2::api_rum_config::RumConfigAPI::with_client_and_config( + world.config.clone(), + world.http_client.as_ref().unwrap().clone(), + ), + ); + } "RumMetrics" => { world.api_instances.v2_api_rum_metrics = Some( datadogV2::api_rum_metrics::RumMetricsAPI::with_client_and_config( @@ -6134,6 +6143,15 @@ pub fn collect_function_calls(world: &mut DatadogWorld) { "v2.UpdateRetentionFilter".into(), test_v2_update_retention_filter, ); + world + .function_mappings + .insert("v2.GetRumConfig".into(), test_v2_get_rum_config); + world + .function_mappings + .insert("v2.UpdateRumConfig".into(), test_v2_update_rum_config); + world + .function_mappings + .insert("v2.CreateRumConfig".into(), test_v2_create_rum_config); world .function_mappings .insert("v2.ListRumMetrics".into(), test_v2_list_rum_metrics); @@ -48005,6 +48023,80 @@ fn test_v2_update_retention_filter(world: &mut DatadogWorld, _parameters: &HashM world.response.code = response.status.as_u16(); } +fn test_v2_get_rum_config(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_rum_config + .as_ref() + .expect("api instance not found"); + let response = match block_on(api.get_rum_config_with_http_info()) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_update_rum_config(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_rum_config + .as_ref() + .expect("api instance not found"); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on(api.update_rum_config_with_http_info(body)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_create_rum_config(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_rum_config + .as_ref() + .expect("api instance not found"); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on(api.create_rum_config_with_http_info(body)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + fn test_v2_list_rum_metrics(world: &mut DatadogWorld, _parameters: &HashMap) { let api = world .api_instances