datadog_api_client/datadogV1/api/
api_snapshots.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 reqwest::header::{HeaderMap, HeaderValue};
6use serde::{Deserialize, Serialize};
7
8/// GetGraphSnapshotOptionalParams is a struct for passing parameters to the method [`SnapshotsAPI::get_graph_snapshot`]
9#[non_exhaustive]
10#[derive(Clone, Default, Debug)]
11pub struct GetGraphSnapshotOptionalParams {
12    /// The metric query.
13    pub metric_query: Option<String>,
14    /// A query that adds event bands to the graph.
15    pub event_query: Option<String>,
16    /// A JSON document defining the graph. `graph_def` can be used instead of `metric_query`.
17    /// The JSON document uses the [grammar defined here](<https://docs.datadoghq.com/graphing/graphing_json/#grammar>)
18    /// and should be formatted to a single line then URL encoded.
19    pub graph_def: Option<String>,
20    /// A title for the graph. If no title is specified, the graph does not have a title.
21    pub title: Option<String>,
22    /// The height of the graph. If no height is specified, the graph's original height is used.
23    pub height: Option<i64>,
24    /// The width of the graph. If no width is specified, the graph's original width is used.
25    pub width: Option<i64>,
26}
27
28impl GetGraphSnapshotOptionalParams {
29    /// The metric query.
30    pub fn metric_query(mut self, value: String) -> Self {
31        self.metric_query = Some(value);
32        self
33    }
34    /// A query that adds event bands to the graph.
35    pub fn event_query(mut self, value: String) -> Self {
36        self.event_query = Some(value);
37        self
38    }
39    /// A JSON document defining the graph. `graph_def` can be used instead of `metric_query`.
40    /// The JSON document uses the [grammar defined here](<https://docs.datadoghq.com/graphing/graphing_json/#grammar>)
41    /// and should be formatted to a single line then URL encoded.
42    pub fn graph_def(mut self, value: String) -> Self {
43        self.graph_def = Some(value);
44        self
45    }
46    /// A title for the graph. If no title is specified, the graph does not have a title.
47    pub fn title(mut self, value: String) -> Self {
48        self.title = Some(value);
49        self
50    }
51    /// The height of the graph. If no height is specified, the graph's original height is used.
52    pub fn height(mut self, value: i64) -> Self {
53        self.height = Some(value);
54        self
55    }
56    /// The width of the graph. If no width is specified, the graph's original width is used.
57    pub fn width(mut self, value: i64) -> Self {
58        self.width = Some(value);
59        self
60    }
61}
62
63/// GetGraphSnapshotError is a struct for typed errors of method [`SnapshotsAPI::get_graph_snapshot`]
64#[derive(Debug, Clone, Serialize, Deserialize)]
65#[serde(untagged)]
66pub enum GetGraphSnapshotError {
67    APIErrorResponse(crate::datadogV1::model::APIErrorResponse),
68    UnknownValue(serde_json::Value),
69}
70
71/// Take graph snapshots using the API.
72#[derive(Debug, Clone)]
73pub struct SnapshotsAPI {
74    config: datadog::Configuration,
75    client: reqwest_middleware::ClientWithMiddleware,
76}
77
78impl Default for SnapshotsAPI {
79    fn default() -> Self {
80        Self::with_config(datadog::Configuration::default())
81    }
82}
83
84impl SnapshotsAPI {
85    pub fn new() -> Self {
86        Self::default()
87    }
88    pub fn with_config(config: datadog::Configuration) -> Self {
89        let mut reqwest_client_builder = reqwest::Client::builder();
90
91        if let Some(proxy_url) = &config.proxy_url {
92            let proxy = reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL");
93            reqwest_client_builder = reqwest_client_builder.proxy(proxy);
94        }
95
96        let mut middleware_client_builder =
97            reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap());
98
99        if config.enable_retry {
100            struct RetryableStatus;
101            impl reqwest_retry::RetryableStrategy for RetryableStatus {
102                fn handle(
103                    &self,
104                    res: &Result<reqwest::Response, reqwest_middleware::Error>,
105                ) -> Option<reqwest_retry::Retryable> {
106                    match res {
107                        Ok(success) => reqwest_retry::default_on_request_success(success),
108                        Err(_) => None,
109                    }
110                }
111            }
112            let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder()
113                .build_with_max_retries(config.max_retries);
114
115            let retry_middleware =
116                reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy(
117                    backoff_policy,
118                    RetryableStatus,
119                );
120
121            middleware_client_builder = middleware_client_builder.with(retry_middleware);
122        }
123
124        let client = middleware_client_builder.build();
125
126        Self { config, client }
127    }
128
129    pub fn with_client_and_config(
130        config: datadog::Configuration,
131        client: reqwest_middleware::ClientWithMiddleware,
132    ) -> Self {
133        Self { config, client }
134    }
135
136    /// Take graph snapshots. Snapshots are PNG images generated by rendering a specified widget in a web page and capturing it once the data is available. The image is then uploaded to cloud storage.
137    ///
138    /// **Note**: When a snapshot is created, there is some delay before it is available.
139    pub async fn get_graph_snapshot(
140        &self,
141        start: i64,
142        end: i64,
143        params: GetGraphSnapshotOptionalParams,
144    ) -> Result<crate::datadogV1::model::GraphSnapshot, datadog::Error<GetGraphSnapshotError>> {
145        match self
146            .get_graph_snapshot_with_http_info(start, end, params)
147            .await
148        {
149            Ok(response_content) => {
150                if let Some(e) = response_content.entity {
151                    Ok(e)
152                } else {
153                    Err(datadog::Error::Serde(serde::de::Error::custom(
154                        "response content was None",
155                    )))
156                }
157            }
158            Err(err) => Err(err),
159        }
160    }
161
162    /// Take graph snapshots. Snapshots are PNG images generated by rendering a specified widget in a web page and capturing it once the data is available. The image is then uploaded to cloud storage.
163    ///
164    /// **Note**: When a snapshot is created, there is some delay before it is available.
165    pub async fn get_graph_snapshot_with_http_info(
166        &self,
167        start: i64,
168        end: i64,
169        params: GetGraphSnapshotOptionalParams,
170    ) -> Result<
171        datadog::ResponseContent<crate::datadogV1::model::GraphSnapshot>,
172        datadog::Error<GetGraphSnapshotError>,
173    > {
174        let local_configuration = &self.config;
175        let operation_id = "v1.get_graph_snapshot";
176
177        // unbox and build optional parameters
178        let metric_query = params.metric_query;
179        let event_query = params.event_query;
180        let graph_def = params.graph_def;
181        let title = params.title;
182        let height = params.height;
183        let width = params.width;
184
185        let local_client = &self.client;
186
187        let local_uri_str = format!(
188            "{}/api/v1/graph/snapshot",
189            local_configuration.get_operation_host(operation_id)
190        );
191        let mut local_req_builder =
192            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
193
194        local_req_builder = local_req_builder.query(&[("start", &start.to_string())]);
195        local_req_builder = local_req_builder.query(&[("end", &end.to_string())]);
196        if let Some(ref local_query_param) = metric_query {
197            local_req_builder =
198                local_req_builder.query(&[("metric_query", &local_query_param.to_string())]);
199        };
200        if let Some(ref local_query_param) = event_query {
201            local_req_builder =
202                local_req_builder.query(&[("event_query", &local_query_param.to_string())]);
203        };
204        if let Some(ref local_query_param) = graph_def {
205            local_req_builder =
206                local_req_builder.query(&[("graph_def", &local_query_param.to_string())]);
207        };
208        if let Some(ref local_query_param) = title {
209            local_req_builder =
210                local_req_builder.query(&[("title", &local_query_param.to_string())]);
211        };
212        if let Some(ref local_query_param) = height {
213            local_req_builder =
214                local_req_builder.query(&[("height", &local_query_param.to_string())]);
215        };
216        if let Some(ref local_query_param) = width {
217            local_req_builder =
218                local_req_builder.query(&[("width", &local_query_param.to_string())]);
219        };
220
221        // build headers
222        let mut headers = HeaderMap::new();
223        headers.insert("Accept", HeaderValue::from_static("application/json"));
224
225        // build user agent
226        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
227            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
228            Err(e) => {
229                log::warn!("Failed to parse user agent header: {e}, falling back to default");
230                headers.insert(
231                    reqwest::header::USER_AGENT,
232                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
233                )
234            }
235        };
236
237        // build auth
238        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
239            headers.insert(
240                "DD-API-KEY",
241                HeaderValue::from_str(local_key.key.as_str())
242                    .expect("failed to parse DD-API-KEY header"),
243            );
244        };
245        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
246            headers.insert(
247                "DD-APPLICATION-KEY",
248                HeaderValue::from_str(local_key.key.as_str())
249                    .expect("failed to parse DD-APPLICATION-KEY header"),
250            );
251        };
252
253        local_req_builder = local_req_builder.headers(headers);
254        let local_req = local_req_builder.build()?;
255        log::debug!("request content: {:?}", local_req.body());
256        let local_resp = local_client.execute(local_req).await?;
257
258        let local_status = local_resp.status();
259        let local_content = local_resp.text().await?;
260        log::debug!("response content: {}", local_content);
261
262        if !local_status.is_client_error() && !local_status.is_server_error() {
263            match serde_json::from_str::<crate::datadogV1::model::GraphSnapshot>(&local_content) {
264                Ok(e) => {
265                    return Ok(datadog::ResponseContent {
266                        status: local_status,
267                        content: local_content,
268                        entity: Some(e),
269                    })
270                }
271                Err(e) => return Err(datadog::Error::Serde(e)),
272            };
273        } else {
274            let local_entity: Option<GetGraphSnapshotError> =
275                serde_json::from_str(&local_content).ok();
276            let local_error = datadog::ResponseContent {
277                status: local_status,
278                content: local_content,
279                entity: local_entity,
280            };
281            Err(datadog::Error::ResponseError(local_error))
282        }
283    }
284}