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::tokens::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 = local_var_uri_str
69 .parse::<::url::Url>()
70 .ok()
71 .is_none_or(|url| {
72 configuration
73 .qcs_config
74 .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
75 });
76
77 if local_var_do_tracing {
78 ::tracing::debug!(
79 url=%local_var_uri_str,
80 method="POST",
81 "making create_engagement request",
82 );
83 }
84 }
85
86 if let Some(local_var_param_value) = x_qcs_account_id {
87 local_var_req_builder =
88 local_var_req_builder.header("x-qcs-account-id", local_var_param_value.to_string());
89 }
90 if let Some(local_var_param_value) = x_qcs_account_type {
91 local_var_req_builder =
92 local_var_req_builder.header("x-qcs-account-type", local_var_param_value.to_string());
93 }
94
95 {
98 use qcs_api_client_common::configuration::TokenError;
99
100 #[allow(
101 clippy::nonminimal_bool,
102 clippy::eq_op,
103 reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
104 )]
105 let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
106
107 let token = local_var_configuration
108 .qcs_config
109 .get_bearer_access_token()
110 .await;
111
112 if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
113 #[cfg(feature = "tracing")]
115 tracing::debug!(
116 "No client credentials found, but this call does not require authentication."
117 );
118 } else {
119 local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
120 }
121 }
122
123 local_var_req_builder = local_var_req_builder.json(&create_engagement_request);
124
125 let local_var_req = local_var_req_builder.build()?;
126 let local_var_resp = local_var_client.execute(local_var_req).await?;
127
128 let local_var_status = local_var_resp.status();
129
130 if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
131 let local_var_content = local_var_resp.text().await?;
132 serde_json::from_str(&local_var_content).map_err(Error::from)
133 } else {
134 let local_var_retry_delay =
135 duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
136 let local_var_content = local_var_resp.text().await?;
137 let local_var_entity: Option<CreateEngagementError> =
138 serde_json::from_str(&local_var_content).ok();
139 let local_var_error = ResponseContent {
140 status: local_var_status,
141 content: local_var_content,
142 entity: local_var_entity,
143 retry_delay: local_var_retry_delay,
144 };
145 Err(Error::ResponseError(local_var_error))
146 }
147}
148
149pub async fn create_engagement(
151 configuration: &configuration::Configuration,
152 create_engagement_request: crate::models::CreateEngagementRequest,
153 x_qcs_account_id: Option<&str>,
154 x_qcs_account_type: Option<crate::models::AccountType>,
155) -> Result<crate::models::EngagementWithCredentials, Error<CreateEngagementError>> {
156 let mut backoff = configuration.backoff.clone();
157 let mut refreshed_credentials = false;
158 let method = reqwest::Method::POST;
159 loop {
160 let result = create_engagement_inner(
161 configuration,
162 &mut backoff,
163 create_engagement_request.clone(),
164 x_qcs_account_id.clone(),
165 x_qcs_account_type.clone(),
166 )
167 .await;
168
169 match result {
170 Ok(result) => return Ok(result),
171 Err(Error::ResponseError(response)) => {
172 if !refreshed_credentials
173 && matches!(
174 response.status,
175 StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
176 )
177 {
178 configuration.qcs_config.refresh().await?;
179 refreshed_credentials = true;
180 continue;
181 } else if let Some(duration) = response.retry_delay {
182 tokio::time::sleep(duration).await;
183 continue;
184 }
185
186 return Err(Error::ResponseError(response));
187 }
188 Err(Error::Reqwest(error)) => {
189 if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
190 tokio::time::sleep(duration).await;
191 continue;
192 }
193
194 return Err(Error::Reqwest(error));
195 }
196 Err(Error::Io(error)) => {
197 if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
198 tokio::time::sleep(duration).await;
199 continue;
200 }
201
202 return Err(Error::Io(error));
203 }
204 Err(error) => return Err(error),
205 }
206 }
207}