1use crate::datadog;
5use flate2::{
6 write::{GzEncoder, ZlibEncoder},
7 Compression,
8};
9use reqwest::header::{HeaderMap, HeaderValue};
10use serde::{Deserialize, Serialize};
11use std::io::Write;
12
13#[non_exhaustive]
15#[derive(Clone, Default, Debug)]
16pub struct GetIssueOptionalParams {
17 pub include: Option<Vec<crate::datadogV2::model::GetIssueIncludeQueryParameterItem>>,
19}
20
21impl GetIssueOptionalParams {
22 pub fn include(
24 mut self,
25 value: Vec<crate::datadogV2::model::GetIssueIncludeQueryParameterItem>,
26 ) -> Self {
27 self.include = Some(value);
28 self
29 }
30}
31
32#[non_exhaustive]
34#[derive(Clone, Default, Debug)]
35pub struct SearchIssuesOptionalParams {
36 pub include: Option<Vec<crate::datadogV2::model::SearchIssuesIncludeQueryParameterItem>>,
38}
39
40impl SearchIssuesOptionalParams {
41 pub fn include(
43 mut self,
44 value: Vec<crate::datadogV2::model::SearchIssuesIncludeQueryParameterItem>,
45 ) -> Self {
46 self.include = Some(value);
47 self
48 }
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
53#[serde(untagged)]
54pub enum GetIssueError {
55 APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
56 UnknownValue(serde_json::Value),
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
61#[serde(untagged)]
62pub enum SearchIssuesError {
63 APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
64 UnknownValue(serde_json::Value),
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize)]
69#[serde(untagged)]
70pub enum UpdateIssueAssigneeError {
71 APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
72 UnknownValue(serde_json::Value),
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize)]
77#[serde(untagged)]
78pub enum UpdateIssueStateError {
79 APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
80 UnknownValue(serde_json::Value),
81}
82
83#[derive(Debug, Clone)]
85pub struct ErrorTrackingAPI {
86 config: datadog::Configuration,
87 client: reqwest_middleware::ClientWithMiddleware,
88}
89
90impl Default for ErrorTrackingAPI {
91 fn default() -> Self {
92 Self::with_config(datadog::Configuration::default())
93 }
94}
95
96impl ErrorTrackingAPI {
97 pub fn new() -> Self {
98 Self::default()
99 }
100 pub fn with_config(config: datadog::Configuration) -> Self {
101 let mut reqwest_client_builder = reqwest::Client::builder();
102
103 if let Some(proxy_url) = &config.proxy_url {
104 let proxy = reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL");
105 reqwest_client_builder = reqwest_client_builder.proxy(proxy);
106 }
107
108 let mut middleware_client_builder =
109 reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap());
110
111 if config.enable_retry {
112 struct RetryableStatus;
113 impl reqwest_retry::RetryableStrategy for RetryableStatus {
114 fn handle(
115 &self,
116 res: &Result<reqwest::Response, reqwest_middleware::Error>,
117 ) -> Option<reqwest_retry::Retryable> {
118 match res {
119 Ok(success) => reqwest_retry::default_on_request_success(success),
120 Err(_) => None,
121 }
122 }
123 }
124 let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder()
125 .build_with_max_retries(config.max_retries);
126
127 let retry_middleware =
128 reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy(
129 backoff_policy,
130 RetryableStatus,
131 );
132
133 middleware_client_builder = middleware_client_builder.with(retry_middleware);
134 }
135
136 let client = middleware_client_builder.build();
137
138 Self { config, client }
139 }
140
141 pub fn with_client_and_config(
142 config: datadog::Configuration,
143 client: reqwest_middleware::ClientWithMiddleware,
144 ) -> Self {
145 Self { config, client }
146 }
147
148 pub async fn get_issue(
150 &self,
151 issue_id: String,
152 params: GetIssueOptionalParams,
153 ) -> Result<crate::datadogV2::model::IssueResponse, datadog::Error<GetIssueError>> {
154 match self.get_issue_with_http_info(issue_id, params).await {
155 Ok(response_content) => {
156 if let Some(e) = response_content.entity {
157 Ok(e)
158 } else {
159 Err(datadog::Error::Serde(serde::de::Error::custom(
160 "response content was None",
161 )))
162 }
163 }
164 Err(err) => Err(err),
165 }
166 }
167
168 pub async fn get_issue_with_http_info(
170 &self,
171 issue_id: String,
172 params: GetIssueOptionalParams,
173 ) -> Result<
174 datadog::ResponseContent<crate::datadogV2::model::IssueResponse>,
175 datadog::Error<GetIssueError>,
176 > {
177 let local_configuration = &self.config;
178 let operation_id = "v2.get_issue";
179
180 let include = params.include;
182
183 let local_client = &self.client;
184
185 let local_uri_str = format!(
186 "{}/api/v2/error-tracking/issues/{issue_id}",
187 local_configuration.get_operation_host(operation_id),
188 issue_id = datadog::urlencode(issue_id)
189 );
190 let mut local_req_builder =
191 local_client.request(reqwest::Method::GET, local_uri_str.as_str());
192
193 if let Some(ref local) = include {
194 local_req_builder = local_req_builder.query(&[(
195 "include",
196 &local
197 .iter()
198 .map(|p| p.to_string())
199 .collect::<Vec<String>>()
200 .join(",")
201 .to_string(),
202 )]);
203 };
204
205 let mut headers = HeaderMap::new();
207 headers.insert("Accept", HeaderValue::from_static("application/json"));
208
209 match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
211 Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
212 Err(e) => {
213 log::warn!("Failed to parse user agent header: {e}, falling back to default");
214 headers.insert(
215 reqwest::header::USER_AGENT,
216 HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
217 )
218 }
219 };
220
221 if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
223 headers.insert(
224 "DD-API-KEY",
225 HeaderValue::from_str(local_key.key.as_str())
226 .expect("failed to parse DD-API-KEY header"),
227 );
228 };
229 if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
230 headers.insert(
231 "DD-APPLICATION-KEY",
232 HeaderValue::from_str(local_key.key.as_str())
233 .expect("failed to parse DD-APPLICATION-KEY header"),
234 );
235 };
236
237 local_req_builder = local_req_builder.headers(headers);
238 let local_req = local_req_builder.build()?;
239 log::debug!("request content: {:?}", local_req.body());
240 let local_resp = local_client.execute(local_req).await?;
241
242 let local_status = local_resp.status();
243 let local_content = local_resp.text().await?;
244 log::debug!("response content: {}", local_content);
245
246 if !local_status.is_client_error() && !local_status.is_server_error() {
247 match serde_json::from_str::<crate::datadogV2::model::IssueResponse>(&local_content) {
248 Ok(e) => {
249 return Ok(datadog::ResponseContent {
250 status: local_status,
251 content: local_content,
252 entity: Some(e),
253 })
254 }
255 Err(e) => return Err(datadog::Error::Serde(e)),
256 };
257 } else {
258 let local_entity: Option<GetIssueError> = serde_json::from_str(&local_content).ok();
259 let local_error = datadog::ResponseContent {
260 status: local_status,
261 content: local_content,
262 entity: local_entity,
263 };
264 Err(datadog::Error::ResponseError(local_error))
265 }
266 }
267
268 pub async fn search_issues(
270 &self,
271 body: crate::datadogV2::model::IssuesSearchRequest,
272 params: SearchIssuesOptionalParams,
273 ) -> Result<crate::datadogV2::model::IssuesSearchResponse, datadog::Error<SearchIssuesError>>
274 {
275 match self.search_issues_with_http_info(body, params).await {
276 Ok(response_content) => {
277 if let Some(e) = response_content.entity {
278 Ok(e)
279 } else {
280 Err(datadog::Error::Serde(serde::de::Error::custom(
281 "response content was None",
282 )))
283 }
284 }
285 Err(err) => Err(err),
286 }
287 }
288
289 pub async fn search_issues_with_http_info(
291 &self,
292 body: crate::datadogV2::model::IssuesSearchRequest,
293 params: SearchIssuesOptionalParams,
294 ) -> Result<
295 datadog::ResponseContent<crate::datadogV2::model::IssuesSearchResponse>,
296 datadog::Error<SearchIssuesError>,
297 > {
298 let local_configuration = &self.config;
299 let operation_id = "v2.search_issues";
300
301 let include = params.include;
303
304 let local_client = &self.client;
305
306 let local_uri_str = format!(
307 "{}/api/v2/error-tracking/issues/search",
308 local_configuration.get_operation_host(operation_id)
309 );
310 let mut local_req_builder =
311 local_client.request(reqwest::Method::POST, local_uri_str.as_str());
312
313 if let Some(ref local) = include {
314 local_req_builder = local_req_builder.query(&[(
315 "include",
316 &local
317 .iter()
318 .map(|p| p.to_string())
319 .collect::<Vec<String>>()
320 .join(",")
321 .to_string(),
322 )]);
323 };
324
325 let mut headers = HeaderMap::new();
327 headers.insert("Content-Type", HeaderValue::from_static("application/json"));
328 headers.insert("Accept", HeaderValue::from_static("application/json"));
329
330 match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
332 Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
333 Err(e) => {
334 log::warn!("Failed to parse user agent header: {e}, falling back to default");
335 headers.insert(
336 reqwest::header::USER_AGENT,
337 HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
338 )
339 }
340 };
341
342 if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
344 headers.insert(
345 "DD-API-KEY",
346 HeaderValue::from_str(local_key.key.as_str())
347 .expect("failed to parse DD-API-KEY header"),
348 );
349 };
350 if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
351 headers.insert(
352 "DD-APPLICATION-KEY",
353 HeaderValue::from_str(local_key.key.as_str())
354 .expect("failed to parse DD-APPLICATION-KEY header"),
355 );
356 };
357
358 let output = Vec::new();
360 let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
361 if body.serialize(&mut ser).is_ok() {
362 if let Some(content_encoding) = headers.get("Content-Encoding") {
363 match content_encoding.to_str().unwrap_or_default() {
364 "gzip" => {
365 let mut enc = GzEncoder::new(Vec::new(), Compression::default());
366 let _ = enc.write_all(ser.into_inner().as_slice());
367 match enc.finish() {
368 Ok(buf) => {
369 local_req_builder = local_req_builder.body(buf);
370 }
371 Err(e) => return Err(datadog::Error::Io(e)),
372 }
373 }
374 "deflate" => {
375 let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
376 let _ = enc.write_all(ser.into_inner().as_slice());
377 match enc.finish() {
378 Ok(buf) => {
379 local_req_builder = local_req_builder.body(buf);
380 }
381 Err(e) => return Err(datadog::Error::Io(e)),
382 }
383 }
384 "zstd1" => {
385 let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
386 let _ = enc.write_all(ser.into_inner().as_slice());
387 match enc.finish() {
388 Ok(buf) => {
389 local_req_builder = local_req_builder.body(buf);
390 }
391 Err(e) => return Err(datadog::Error::Io(e)),
392 }
393 }
394 _ => {
395 local_req_builder = local_req_builder.body(ser.into_inner());
396 }
397 }
398 } else {
399 local_req_builder = local_req_builder.body(ser.into_inner());
400 }
401 }
402
403 local_req_builder = local_req_builder.headers(headers);
404 let local_req = local_req_builder.build()?;
405 log::debug!("request content: {:?}", local_req.body());
406 let local_resp = local_client.execute(local_req).await?;
407
408 let local_status = local_resp.status();
409 let local_content = local_resp.text().await?;
410 log::debug!("response content: {}", local_content);
411
412 if !local_status.is_client_error() && !local_status.is_server_error() {
413 match serde_json::from_str::<crate::datadogV2::model::IssuesSearchResponse>(
414 &local_content,
415 ) {
416 Ok(e) => {
417 return Ok(datadog::ResponseContent {
418 status: local_status,
419 content: local_content,
420 entity: Some(e),
421 })
422 }
423 Err(e) => return Err(datadog::Error::Serde(e)),
424 };
425 } else {
426 let local_entity: Option<SearchIssuesError> = serde_json::from_str(&local_content).ok();
427 let local_error = datadog::ResponseContent {
428 status: local_status,
429 content: local_content,
430 entity: local_entity,
431 };
432 Err(datadog::Error::ResponseError(local_error))
433 }
434 }
435
436 pub async fn update_issue_assignee(
438 &self,
439 issue_id: String,
440 body: crate::datadogV2::model::IssueUpdateAssigneeRequest,
441 ) -> Result<crate::datadogV2::model::IssueResponse, datadog::Error<UpdateIssueAssigneeError>>
442 {
443 match self
444 .update_issue_assignee_with_http_info(issue_id, body)
445 .await
446 {
447 Ok(response_content) => {
448 if let Some(e) = response_content.entity {
449 Ok(e)
450 } else {
451 Err(datadog::Error::Serde(serde::de::Error::custom(
452 "response content was None",
453 )))
454 }
455 }
456 Err(err) => Err(err),
457 }
458 }
459
460 pub async fn update_issue_assignee_with_http_info(
462 &self,
463 issue_id: String,
464 body: crate::datadogV2::model::IssueUpdateAssigneeRequest,
465 ) -> Result<
466 datadog::ResponseContent<crate::datadogV2::model::IssueResponse>,
467 datadog::Error<UpdateIssueAssigneeError>,
468 > {
469 let local_configuration = &self.config;
470 let operation_id = "v2.update_issue_assignee";
471
472 let local_client = &self.client;
473
474 let local_uri_str = format!(
475 "{}/api/v2/error-tracking/issues/{issue_id}/assignee",
476 local_configuration.get_operation_host(operation_id),
477 issue_id = datadog::urlencode(issue_id)
478 );
479 let mut local_req_builder =
480 local_client.request(reqwest::Method::PUT, local_uri_str.as_str());
481
482 let mut headers = HeaderMap::new();
484 headers.insert("Content-Type", HeaderValue::from_static("application/json"));
485 headers.insert("Accept", HeaderValue::from_static("application/json"));
486
487 match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
489 Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
490 Err(e) => {
491 log::warn!("Failed to parse user agent header: {e}, falling back to default");
492 headers.insert(
493 reqwest::header::USER_AGENT,
494 HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
495 )
496 }
497 };
498
499 if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
501 headers.insert(
502 "DD-API-KEY",
503 HeaderValue::from_str(local_key.key.as_str())
504 .expect("failed to parse DD-API-KEY header"),
505 );
506 };
507 if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
508 headers.insert(
509 "DD-APPLICATION-KEY",
510 HeaderValue::from_str(local_key.key.as_str())
511 .expect("failed to parse DD-APPLICATION-KEY header"),
512 );
513 };
514
515 let output = Vec::new();
517 let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
518 if body.serialize(&mut ser).is_ok() {
519 if let Some(content_encoding) = headers.get("Content-Encoding") {
520 match content_encoding.to_str().unwrap_or_default() {
521 "gzip" => {
522 let mut enc = GzEncoder::new(Vec::new(), Compression::default());
523 let _ = enc.write_all(ser.into_inner().as_slice());
524 match enc.finish() {
525 Ok(buf) => {
526 local_req_builder = local_req_builder.body(buf);
527 }
528 Err(e) => return Err(datadog::Error::Io(e)),
529 }
530 }
531 "deflate" => {
532 let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
533 let _ = enc.write_all(ser.into_inner().as_slice());
534 match enc.finish() {
535 Ok(buf) => {
536 local_req_builder = local_req_builder.body(buf);
537 }
538 Err(e) => return Err(datadog::Error::Io(e)),
539 }
540 }
541 "zstd1" => {
542 let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
543 let _ = enc.write_all(ser.into_inner().as_slice());
544 match enc.finish() {
545 Ok(buf) => {
546 local_req_builder = local_req_builder.body(buf);
547 }
548 Err(e) => return Err(datadog::Error::Io(e)),
549 }
550 }
551 _ => {
552 local_req_builder = local_req_builder.body(ser.into_inner());
553 }
554 }
555 } else {
556 local_req_builder = local_req_builder.body(ser.into_inner());
557 }
558 }
559
560 local_req_builder = local_req_builder.headers(headers);
561 let local_req = local_req_builder.build()?;
562 log::debug!("request content: {:?}", local_req.body());
563 let local_resp = local_client.execute(local_req).await?;
564
565 let local_status = local_resp.status();
566 let local_content = local_resp.text().await?;
567 log::debug!("response content: {}", local_content);
568
569 if !local_status.is_client_error() && !local_status.is_server_error() {
570 match serde_json::from_str::<crate::datadogV2::model::IssueResponse>(&local_content) {
571 Ok(e) => {
572 return Ok(datadog::ResponseContent {
573 status: local_status,
574 content: local_content,
575 entity: Some(e),
576 })
577 }
578 Err(e) => return Err(datadog::Error::Serde(e)),
579 };
580 } else {
581 let local_entity: Option<UpdateIssueAssigneeError> =
582 serde_json::from_str(&local_content).ok();
583 let local_error = datadog::ResponseContent {
584 status: local_status,
585 content: local_content,
586 entity: local_entity,
587 };
588 Err(datadog::Error::ResponseError(local_error))
589 }
590 }
591
592 pub async fn update_issue_state(
594 &self,
595 issue_id: String,
596 body: crate::datadogV2::model::IssueUpdateStateRequest,
597 ) -> Result<crate::datadogV2::model::IssueResponse, datadog::Error<UpdateIssueStateError>> {
598 match self.update_issue_state_with_http_info(issue_id, body).await {
599 Ok(response_content) => {
600 if let Some(e) = response_content.entity {
601 Ok(e)
602 } else {
603 Err(datadog::Error::Serde(serde::de::Error::custom(
604 "response content was None",
605 )))
606 }
607 }
608 Err(err) => Err(err),
609 }
610 }
611
612 pub async fn update_issue_state_with_http_info(
614 &self,
615 issue_id: String,
616 body: crate::datadogV2::model::IssueUpdateStateRequest,
617 ) -> Result<
618 datadog::ResponseContent<crate::datadogV2::model::IssueResponse>,
619 datadog::Error<UpdateIssueStateError>,
620 > {
621 let local_configuration = &self.config;
622 let operation_id = "v2.update_issue_state";
623
624 let local_client = &self.client;
625
626 let local_uri_str = format!(
627 "{}/api/v2/error-tracking/issues/{issue_id}/state",
628 local_configuration.get_operation_host(operation_id),
629 issue_id = datadog::urlencode(issue_id)
630 );
631 let mut local_req_builder =
632 local_client.request(reqwest::Method::PUT, local_uri_str.as_str());
633
634 let mut headers = HeaderMap::new();
636 headers.insert("Content-Type", HeaderValue::from_static("application/json"));
637 headers.insert("Accept", HeaderValue::from_static("application/json"));
638
639 match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
641 Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
642 Err(e) => {
643 log::warn!("Failed to parse user agent header: {e}, falling back to default");
644 headers.insert(
645 reqwest::header::USER_AGENT,
646 HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
647 )
648 }
649 };
650
651 if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
653 headers.insert(
654 "DD-API-KEY",
655 HeaderValue::from_str(local_key.key.as_str())
656 .expect("failed to parse DD-API-KEY header"),
657 );
658 };
659 if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
660 headers.insert(
661 "DD-APPLICATION-KEY",
662 HeaderValue::from_str(local_key.key.as_str())
663 .expect("failed to parse DD-APPLICATION-KEY header"),
664 );
665 };
666
667 let output = Vec::new();
669 let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
670 if body.serialize(&mut ser).is_ok() {
671 if let Some(content_encoding) = headers.get("Content-Encoding") {
672 match content_encoding.to_str().unwrap_or_default() {
673 "gzip" => {
674 let mut enc = GzEncoder::new(Vec::new(), Compression::default());
675 let _ = enc.write_all(ser.into_inner().as_slice());
676 match enc.finish() {
677 Ok(buf) => {
678 local_req_builder = local_req_builder.body(buf);
679 }
680 Err(e) => return Err(datadog::Error::Io(e)),
681 }
682 }
683 "deflate" => {
684 let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
685 let _ = enc.write_all(ser.into_inner().as_slice());
686 match enc.finish() {
687 Ok(buf) => {
688 local_req_builder = local_req_builder.body(buf);
689 }
690 Err(e) => return Err(datadog::Error::Io(e)),
691 }
692 }
693 "zstd1" => {
694 let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
695 let _ = enc.write_all(ser.into_inner().as_slice());
696 match enc.finish() {
697 Ok(buf) => {
698 local_req_builder = local_req_builder.body(buf);
699 }
700 Err(e) => return Err(datadog::Error::Io(e)),
701 }
702 }
703 _ => {
704 local_req_builder = local_req_builder.body(ser.into_inner());
705 }
706 }
707 } else {
708 local_req_builder = local_req_builder.body(ser.into_inner());
709 }
710 }
711
712 local_req_builder = local_req_builder.headers(headers);
713 let local_req = local_req_builder.build()?;
714 log::debug!("request content: {:?}", local_req.body());
715 let local_resp = local_client.execute(local_req).await?;
716
717 let local_status = local_resp.status();
718 let local_content = local_resp.text().await?;
719 log::debug!("response content: {}", local_content);
720
721 if !local_status.is_client_error() && !local_status.is_server_error() {
722 match serde_json::from_str::<crate::datadogV2::model::IssueResponse>(&local_content) {
723 Ok(e) => {
724 return Ok(datadog::ResponseContent {
725 status: local_status,
726 content: local_content,
727 entity: Some(e),
728 })
729 }
730 Err(e) => return Err(datadog::Error::Serde(e)),
731 };
732 } else {
733 let local_entity: Option<UpdateIssueStateError> =
734 serde_json::from_str(&local_content).ok();
735 let local_error = datadog::ResponseContent {
736 status: local_status,
737 content: local_content,
738 entity: local_entity,
739 };
740 Err(datadog::Error::ResponseError(local_error))
741 }
742 }
743}