datadog_api_client/datadogV2/api/
api_spa.rs1use crate::datadog;
5use log::warn;
6use reqwest::header::{HeaderMap, HeaderValue};
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11#[serde(untagged)]
12pub enum GetSPARecommendationsError {
13 APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
14 UnknownValue(serde_json::Value),
15}
16
17#[derive(Debug, Clone)]
19pub struct SpaAPI {
20 config: datadog::Configuration,
21 client: reqwest_middleware::ClientWithMiddleware,
22}
23
24impl Default for SpaAPI {
25 fn default() -> Self {
26 Self::with_config(datadog::Configuration::default())
27 }
28}
29
30impl SpaAPI {
31 pub fn new() -> Self {
32 Self::default()
33 }
34 pub fn with_config(config: datadog::Configuration) -> Self {
35 let mut reqwest_client_builder = reqwest::Client::builder();
36
37 if let Some(proxy_url) = &config.proxy_url {
38 let proxy = reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL");
39 reqwest_client_builder = reqwest_client_builder.proxy(proxy);
40 }
41
42 let mut middleware_client_builder =
43 reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap());
44
45 if config.enable_retry {
46 struct RetryableStatus;
47 impl reqwest_retry::RetryableStrategy for RetryableStatus {
48 fn handle(
49 &self,
50 res: &Result<reqwest::Response, reqwest_middleware::Error>,
51 ) -> Option<reqwest_retry::Retryable> {
52 match res {
53 Ok(success) => reqwest_retry::default_on_request_success(success),
54 Err(_) => None,
55 }
56 }
57 }
58 let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder()
59 .build_with_max_retries(config.max_retries);
60
61 let retry_middleware =
62 reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy(
63 backoff_policy,
64 RetryableStatus,
65 );
66
67 middleware_client_builder = middleware_client_builder.with(retry_middleware);
68 }
69
70 let client = middleware_client_builder.build();
71
72 Self { config, client }
73 }
74
75 pub fn with_client_and_config(
76 config: datadog::Configuration,
77 client: reqwest_middleware::ClientWithMiddleware,
78 ) -> Self {
79 Self { config, client }
80 }
81
82 pub async fn get_spa_recommendations(
84 &self,
85 shard: String,
86 service: String,
87 ) -> Result<
88 crate::datadogV2::model::RecommendationDocument,
89 datadog::Error<GetSPARecommendationsError>,
90 > {
91 match self
92 .get_spa_recommendations_with_http_info(shard, service)
93 .await
94 {
95 Ok(response_content) => {
96 if let Some(e) = response_content.entity {
97 Ok(e)
98 } else {
99 Err(datadog::Error::Serde(serde::de::Error::custom(
100 "response content was None",
101 )))
102 }
103 }
104 Err(err) => Err(err),
105 }
106 }
107
108 pub async fn get_spa_recommendations_with_http_info(
110 &self,
111 shard: String,
112 service: String,
113 ) -> Result<
114 datadog::ResponseContent<crate::datadogV2::model::RecommendationDocument>,
115 datadog::Error<GetSPARecommendationsError>,
116 > {
117 let local_configuration = &self.config;
118 let operation_id = "v2.get_spa_recommendations";
119 if local_configuration.is_unstable_operation_enabled(operation_id) {
120 warn!("Using unstable operation {operation_id}");
121 } else {
122 let local_error = datadog::UnstableOperationDisabledError {
123 msg: "Operation 'v2.get_spa_recommendations' is not enabled".to_string(),
124 };
125 return Err(datadog::Error::UnstableOperationDisabledError(local_error));
126 }
127
128 let local_client = &self.client;
129
130 let local_uri_str = format!(
131 "{}/api/v2/spa/recommendations/{service}/{shard}",
132 local_configuration.get_operation_host(operation_id),
133 shard = datadog::urlencode(shard),
134 service = datadog::urlencode(service)
135 );
136 let mut local_req_builder =
137 local_client.request(reqwest::Method::GET, local_uri_str.as_str());
138
139 let mut headers = HeaderMap::new();
141 headers.insert("Accept", HeaderValue::from_static("application/json"));
142
143 match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
145 Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
146 Err(e) => {
147 log::warn!("Failed to parse user agent header: {e}, falling back to default");
148 headers.insert(
149 reqwest::header::USER_AGENT,
150 HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
151 )
152 }
153 };
154
155 if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
157 headers.insert(
158 "DD-API-KEY",
159 HeaderValue::from_str(local_key.key.as_str())
160 .expect("failed to parse DD-API-KEY header"),
161 );
162 };
163 if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
164 headers.insert(
165 "DD-APPLICATION-KEY",
166 HeaderValue::from_str(local_key.key.as_str())
167 .expect("failed to parse DD-APPLICATION-KEY header"),
168 );
169 };
170
171 local_req_builder = local_req_builder.headers(headers);
172 let local_req = local_req_builder.build()?;
173 log::debug!("request content: {:?}", local_req.body());
174 let local_resp = local_client.execute(local_req).await?;
175
176 let local_status = local_resp.status();
177 let local_content = local_resp.text().await?;
178 log::debug!("response content: {}", local_content);
179
180 if !local_status.is_client_error() && !local_status.is_server_error() {
181 match serde_json::from_str::<crate::datadogV2::model::RecommendationDocument>(
182 &local_content,
183 ) {
184 Ok(e) => {
185 return Ok(datadog::ResponseContent {
186 status: local_status,
187 content: local_content,
188 entity: Some(e),
189 })
190 }
191 Err(e) => return Err(datadog::Error::Serde(e)),
192 };
193 } else {
194 let local_entity: Option<GetSPARecommendationsError> =
195 serde_json::from_str(&local_content).ok();
196 let local_error = datadog::ResponseContent {
197 status: local_status,
198 content: local_content,
199 entity: local_entity,
200 };
201 Err(datadog::Error::ResponseError(local_error))
202 }
203 }
204}