qcs_api_client_openapi/apis/
engagements_api.rs1use super::{configuration, Error};
26use crate::apis::ResponseContent;
27use ::qcs_api_client_common::backoff::{
28 duration_from_io_error, duration_from_reqwest_error, duration_from_response, ExponentialBackoff,
29};
30#[cfg(feature = "tracing")]
31use qcs_api_client_common::configuration::TokenRefresher;
32use reqwest::StatusCode;
33use serde::{Deserialize, Serialize};
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
37#[serde(untagged)]
38pub enum CreateEngagementError {
39 Status400(crate::models::Error),
40 Status404(crate::models::Error),
41 Status422(crate::models::Error),
42 Status503(),
43 UnknownValue(serde_json::Value),
44}
45
46async fn create_engagement_inner(
47 configuration: &configuration::Configuration,
48 backoff: &mut ExponentialBackoff,
49 create_engagement_request: crate::models::CreateEngagementRequest,
50 x_qcs_account_id: Option<&str>,
51 x_qcs_account_type: Option<crate::models::AccountType>,
52) -> Result<crate::models::EngagementWithCredentials, Error<CreateEngagementError>> {
53 let local_var_configuration = configuration;
54
55 let local_var_client = &local_var_configuration.client;
56
57 let local_var_uri_str = format!(
58 "{}/v1/engagements",
59 local_var_configuration.qcs_config.api_url()
60 );
61 let mut local_var_req_builder =
62 local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
63
64 #[cfg(feature = "tracing")]
65 {
66 let local_var_do_tracing =
69 local_var_uri_str
70 .parse::<::url::Url>()
71 .ok()
72 .map_or(true, |url| {
73 configuration
74 .qcs_config
75 .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
76 });
77
78 if local_var_do_tracing {
79 ::tracing::debug!(
80 url=%local_var_uri_str,
81 method="POST",
82 "making create_engagement request",
83 );
84 }
85 }
86
87 if let Some(local_var_param_value) = x_qcs_account_id {
88 local_var_req_builder =
89 local_var_req_builder.header("x-qcs-account-id", local_var_param_value.to_string());
90 }
91 if let Some(local_var_param_value) = x_qcs_account_type {
92 local_var_req_builder =
93 local_var_req_builder.header("x-qcs-account-type", local_var_param_value.to_string());
94 }
95
96 {
99 use qcs_api_client_common::configuration::TokenError;
100
101 #[allow(
102 clippy::nonminimal_bool,
103 clippy::eq_op,
104 reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
105 )]
106 let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
107
108 let token = local_var_configuration
109 .qcs_config
110 .get_bearer_access_token()
111 .await;
112
113 if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
114 #[cfg(feature = "tracing")]
116 tracing::debug!(
117 "No client credentials found, but this call does not require authentication."
118 );
119 } else {
120 local_var_req_builder = local_var_req_builder.bearer_auth(token?);
121 }
122 }
123
124 local_var_req_builder = local_var_req_builder.json(&create_engagement_request);
125
126 let local_var_req = local_var_req_builder.build()?;
127 let local_var_resp = local_var_client.execute(local_var_req).await?;
128
129 let local_var_status = local_var_resp.status();
130
131 if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
132 let local_var_content = local_var_resp.text().await?;
133 serde_json::from_str(&local_var_content).map_err(Error::from)
134 } else {
135 let local_var_retry_delay =
136 duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
137 let local_var_content = local_var_resp.text().await?;
138 let local_var_entity: Option<CreateEngagementError> =
139 serde_json::from_str(&local_var_content).ok();
140 let local_var_error = ResponseContent {
141 status: local_var_status,
142 content: local_var_content,
143 entity: local_var_entity,
144 retry_delay: local_var_retry_delay,
145 };
146 Err(Error::ResponseError(local_var_error))
147 }
148}
149
150pub async fn create_engagement(
152 configuration: &configuration::Configuration,
153 create_engagement_request: crate::models::CreateEngagementRequest,
154 x_qcs_account_id: Option<&str>,
155 x_qcs_account_type: Option<crate::models::AccountType>,
156) -> Result<crate::models::EngagementWithCredentials, Error<CreateEngagementError>> {
157 let mut backoff = configuration.backoff.clone();
158 let mut refreshed_credentials = false;
159 let method = reqwest::Method::POST;
160 loop {
161 let result = create_engagement_inner(
162 configuration,
163 &mut backoff,
164 create_engagement_request.clone(),
165 x_qcs_account_id.clone(),
166 x_qcs_account_type.clone(),
167 )
168 .await;
169
170 match result {
171 Ok(result) => return Ok(result),
172 Err(Error::ResponseError(response)) => {
173 if !refreshed_credentials
174 && matches!(
175 response.status,
176 StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
177 )
178 {
179 configuration.qcs_config.refresh().await?;
180 refreshed_credentials = true;
181 continue;
182 } else if let Some(duration) = response.retry_delay {
183 tokio::time::sleep(duration).await;
184 continue;
185 }
186
187 return Err(Error::ResponseError(response));
188 }
189 Err(Error::Reqwest(error)) => {
190 if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
191 tokio::time::sleep(duration).await;
192 continue;
193 }
194
195 return Err(Error::Reqwest(error));
196 }
197 Err(Error::Io(error)) => {
198 if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
199 tokio::time::sleep(duration).await;
200 continue;
201 }
202
203 return Err(Error::Io(error));
204 }
205 Err(error) => return Err(error),
206 }
207 }
208}