1use super::{ContentType, Error, configuration};
26use crate::{apis::ResponseContent, models};
27use ::qcs_api_client_common::backoff::{
28 ExponentialBackoff, duration_from_io_error, duration_from_reqwest_error, duration_from_response,
29};
30#[cfg(feature = "tracing")]
31use qcs_api_client_common::configuration::tokens::TokenRefresher;
32use qcs_dependencies_client::reqwest::{self, StatusCode};
33use serde::{Deserialize, Serialize};
34
35#[cfg(feature = "clap")]
36#[allow(unused, reason = "not used in all templates, but required in some")]
37use ::{miette::IntoDiagnostic as _, qcs_api_client_common::clap_utils::JsonMaybeStdin};
38
39#[cfg(feature = "clap")]
41#[derive(Debug, clap::Args)]
42pub struct CheckClientApplicationClapParams {
43 pub check_client_application_request:
44 JsonMaybeStdin<crate::models::CheckClientApplicationRequest>,
45}
46
47#[cfg(feature = "clap")]
48impl CheckClientApplicationClapParams {
49 pub async fn execute(
50 self,
51 configuration: &configuration::Configuration,
52 ) -> Result<models::CheckClientApplicationResponse, miette::Error> {
53 let request = self
54 .check_client_application_request
55 .into_inner()
56 .into_inner();
57
58 check_client_application(configuration, request)
59 .await
60 .into_diagnostic()
61 }
62}
63
64#[cfg(feature = "clap")]
66#[derive(Debug, clap::Args)]
67pub struct GetClientApplicationClapParams {
68 #[arg(long)]
69 pub client_application_name: String,
70}
71
72#[cfg(feature = "clap")]
73impl GetClientApplicationClapParams {
74 pub async fn execute(
75 self,
76 configuration: &configuration::Configuration,
77 ) -> Result<models::ClientApplication, miette::Error> {
78 get_client_application(configuration, self.client_application_name.as_str())
79 .await
80 .into_diagnostic()
81 }
82}
83
84#[cfg(feature = "clap")]
86#[derive(Debug, clap::Args)]
87pub struct ListClientApplicationsClapParams {}
88
89#[cfg(feature = "clap")]
90impl ListClientApplicationsClapParams {
91 pub async fn execute(
92 self,
93 configuration: &configuration::Configuration,
94 ) -> Result<models::ListClientApplicationsResponse, miette::Error> {
95 list_client_applications(configuration)
96 .await
97 .into_diagnostic()
98 }
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
103#[serde(untagged)]
104pub enum CheckClientApplicationError {
105 Status404(models::Error),
106 Status422(models::Error),
107 UnknownValue(serde_json::Value),
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
112#[serde(untagged)]
113pub enum GetClientApplicationError {
114 Status404(models::Error),
115 UnknownValue(serde_json::Value),
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize)]
120#[serde(untagged)]
121pub enum ListClientApplicationsError {
122 UnknownValue(serde_json::Value),
123}
124
125async fn check_client_application_inner(
126 configuration: &configuration::Configuration,
127 backoff: &mut ExponentialBackoff,
128 check_client_application_request: crate::models::CheckClientApplicationRequest,
129) -> Result<models::CheckClientApplicationResponse, Error<CheckClientApplicationError>> {
130 let local_var_configuration = configuration;
131 let p_body_check_client_application_request = check_client_application_request;
133
134 let local_var_client = &local_var_configuration.client;
135
136 let local_var_uri_str = format!(
137 "{}/v1/clientApplications:check",
138 local_var_configuration.qcs_config.api_url()
139 );
140 let mut local_var_req_builder =
141 local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
142
143 #[cfg(feature = "tracing")]
144 {
145 let local_var_do_tracing = local_var_uri_str
148 .parse::<::url::Url>()
149 .ok()
150 .is_none_or(|url| {
151 configuration
152 .qcs_config
153 .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
154 });
155
156 if local_var_do_tracing {
157 ::tracing::debug!(
158 url=%local_var_uri_str,
159 method="POST",
160 "making check_client_application request",
161 );
162 }
163 }
164
165 {
168 use qcs_api_client_common::configuration::TokenError;
169
170 #[allow(
171 clippy::nonminimal_bool,
172 clippy::eq_op,
173 reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
174 )]
175 let is_jwt_bearer_optional: bool = false;
176
177 let token = local_var_configuration
178 .qcs_config
179 .get_bearer_access_token()
180 .await;
181
182 if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
183 #[cfg(feature = "tracing")]
185 tracing::debug!(
186 "No client credentials found, but this call does not require authentication."
187 );
188 } else {
189 local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
190 }
191 }
192
193 local_var_req_builder = local_var_req_builder.json(&p_body_check_client_application_request);
194
195 let local_var_req = local_var_req_builder.build()?;
196 let local_var_resp = local_var_client.execute(local_var_req).await?;
197
198 let local_var_status = local_var_resp.status();
199 let local_var_raw_content_type = local_var_resp
200 .headers()
201 .get("content-type")
202 .and_then(|v| v.to_str().ok())
203 .unwrap_or("application/octet-stream")
204 .to_string();
205 let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
206
207 if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
208 let local_var_content = local_var_resp.text().await?;
209 match local_var_content_type {
210 ContentType::Json => serde_path_to_error::deserialize(
211 &mut serde_json::Deserializer::from_str(&local_var_content),
212 )
213 .map_err(Error::from),
214 ContentType::Text => Err(Error::InvalidContentType {
215 content_type: local_var_raw_content_type,
216 return_type: "models::CheckClientApplicationResponse",
217 }),
218 ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
219 content_type: unknown_type,
220 return_type: "models::CheckClientApplicationResponse",
221 }),
222 }
223 } else {
224 let local_var_retry_delay =
225 duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
226 let local_var_content = local_var_resp.text().await?;
227 let local_var_entity: Option<CheckClientApplicationError> =
228 serde_json::from_str(&local_var_content).ok();
229 let local_var_error = ResponseContent {
230 status: local_var_status,
231 content: local_var_content,
232 entity: local_var_entity,
233 retry_delay: local_var_retry_delay,
234 };
235 Err(Error::ResponseError(local_var_error))
236 }
237}
238
239pub async fn check_client_application(
241 configuration: &configuration::Configuration,
242 check_client_application_request: crate::models::CheckClientApplicationRequest,
243) -> Result<models::CheckClientApplicationResponse, Error<CheckClientApplicationError>> {
244 let mut backoff = configuration.backoff.clone();
245 let mut refreshed_credentials = false;
246 let method = reqwest::Method::POST;
247 loop {
248 let result = check_client_application_inner(
249 configuration,
250 &mut backoff,
251 check_client_application_request.clone(),
252 )
253 .await;
254
255 match result {
256 Ok(result) => return Ok(result),
257 Err(Error::ResponseError(response)) => {
258 if !refreshed_credentials
259 && matches!(
260 response.status,
261 StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
262 )
263 {
264 match configuration.qcs_config.refresh().await {
266 Ok(_) => {
267 refreshed_credentials = true;
268 continue;
269 }
270 Err(::qcs_api_client_common::configuration::TokenError::Write {
271 error,
272 oauth_session: _,
273 }) => {
274 #[cfg(feature = "tracing")]
277 tracing::warn!(
278 "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
279 error
280 );
281 refreshed_credentials = true;
282 continue;
283 }
284 Err(e) => return Err(e.into()),
285 }
286 } else if let Some(duration) = response.retry_delay {
287 tokio::time::sleep(duration).await;
288 continue;
289 }
290
291 return Err(Error::ResponseError(response));
292 }
293 Err(Error::Reqwest(error)) => {
294 if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
295 tokio::time::sleep(duration).await;
296 continue;
297 }
298
299 return Err(Error::Reqwest(error));
300 }
301 Err(Error::Io(error)) => {
302 if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
303 tokio::time::sleep(duration).await;
304 continue;
305 }
306
307 return Err(Error::Io(error));
308 }
309 Err(error) => return Err(error),
310 }
311 }
312}
313async fn get_client_application_inner(
314 configuration: &configuration::Configuration,
315 backoff: &mut ExponentialBackoff,
316 client_application_name: &str,
317) -> Result<models::ClientApplication, Error<GetClientApplicationError>> {
318 let local_var_configuration = configuration;
319 let p_path_client_application_name = client_application_name;
321
322 let local_var_client = &local_var_configuration.client;
323
324 let local_var_uri_str = format!(
325 "{}/v1/clientApplications/{clientApplicationName}",
326 local_var_configuration.qcs_config.api_url(),
327 clientApplicationName = crate::apis::urlencode(p_path_client_application_name)
328 );
329 let mut local_var_req_builder =
330 local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
331
332 #[cfg(feature = "tracing")]
333 {
334 let local_var_do_tracing = local_var_uri_str
337 .parse::<::url::Url>()
338 .ok()
339 .is_none_or(|url| {
340 configuration
341 .qcs_config
342 .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
343 });
344
345 if local_var_do_tracing {
346 ::tracing::debug!(
347 url=%local_var_uri_str,
348 method="GET",
349 "making get_client_application request",
350 );
351 }
352 }
353
354 {
357 use qcs_api_client_common::configuration::TokenError;
358
359 #[allow(
360 clippy::nonminimal_bool,
361 clippy::eq_op,
362 reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
363 )]
364 let is_jwt_bearer_optional: bool = false;
365
366 let token = local_var_configuration
367 .qcs_config
368 .get_bearer_access_token()
369 .await;
370
371 if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
372 #[cfg(feature = "tracing")]
374 tracing::debug!(
375 "No client credentials found, but this call does not require authentication."
376 );
377 } else {
378 local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
379 }
380 }
381
382 let local_var_req = local_var_req_builder.build()?;
383 let local_var_resp = local_var_client.execute(local_var_req).await?;
384
385 let local_var_status = local_var_resp.status();
386 let local_var_raw_content_type = local_var_resp
387 .headers()
388 .get("content-type")
389 .and_then(|v| v.to_str().ok())
390 .unwrap_or("application/octet-stream")
391 .to_string();
392 let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
393
394 if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
395 let local_var_content = local_var_resp.text().await?;
396 match local_var_content_type {
397 ContentType::Json => serde_path_to_error::deserialize(
398 &mut serde_json::Deserializer::from_str(&local_var_content),
399 )
400 .map_err(Error::from),
401 ContentType::Text => Err(Error::InvalidContentType {
402 content_type: local_var_raw_content_type,
403 return_type: "models::ClientApplication",
404 }),
405 ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
406 content_type: unknown_type,
407 return_type: "models::ClientApplication",
408 }),
409 }
410 } else {
411 let local_var_retry_delay =
412 duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
413 let local_var_content = local_var_resp.text().await?;
414 let local_var_entity: Option<GetClientApplicationError> =
415 serde_json::from_str(&local_var_content).ok();
416 let local_var_error = ResponseContent {
417 status: local_var_status,
418 content: local_var_content,
419 entity: local_var_entity,
420 retry_delay: local_var_retry_delay,
421 };
422 Err(Error::ResponseError(local_var_error))
423 }
424}
425
426pub async fn get_client_application(
428 configuration: &configuration::Configuration,
429 client_application_name: &str,
430) -> Result<models::ClientApplication, Error<GetClientApplicationError>> {
431 let mut backoff = configuration.backoff.clone();
432 let mut refreshed_credentials = false;
433 let method = reqwest::Method::GET;
434 loop {
435 let result = get_client_application_inner(
436 configuration,
437 &mut backoff,
438 client_application_name.clone(),
439 )
440 .await;
441
442 match result {
443 Ok(result) => return Ok(result),
444 Err(Error::ResponseError(response)) => {
445 if !refreshed_credentials
446 && matches!(
447 response.status,
448 StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
449 )
450 {
451 match configuration.qcs_config.refresh().await {
453 Ok(_) => {
454 refreshed_credentials = true;
455 continue;
456 }
457 Err(::qcs_api_client_common::configuration::TokenError::Write {
458 error,
459 oauth_session: _,
460 }) => {
461 #[cfg(feature = "tracing")]
464 tracing::warn!(
465 "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
466 error
467 );
468 refreshed_credentials = true;
469 continue;
470 }
471 Err(e) => return Err(e.into()),
472 }
473 } else if let Some(duration) = response.retry_delay {
474 tokio::time::sleep(duration).await;
475 continue;
476 }
477
478 return Err(Error::ResponseError(response));
479 }
480 Err(Error::Reqwest(error)) => {
481 if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
482 tokio::time::sleep(duration).await;
483 continue;
484 }
485
486 return Err(Error::Reqwest(error));
487 }
488 Err(Error::Io(error)) => {
489 if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
490 tokio::time::sleep(duration).await;
491 continue;
492 }
493
494 return Err(Error::Io(error));
495 }
496 Err(error) => return Err(error),
497 }
498 }
499}
500async fn list_client_applications_inner(
501 configuration: &configuration::Configuration,
502 backoff: &mut ExponentialBackoff,
503) -> Result<models::ListClientApplicationsResponse, Error<ListClientApplicationsError>> {
504 let local_var_configuration = configuration;
505
506 let local_var_client = &local_var_configuration.client;
507
508 let local_var_uri_str = format!(
509 "{}/v1/clientApplications",
510 local_var_configuration.qcs_config.api_url()
511 );
512 let mut local_var_req_builder =
513 local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
514
515 #[cfg(feature = "tracing")]
516 {
517 let local_var_do_tracing = local_var_uri_str
520 .parse::<::url::Url>()
521 .ok()
522 .is_none_or(|url| {
523 configuration
524 .qcs_config
525 .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
526 });
527
528 if local_var_do_tracing {
529 ::tracing::debug!(
530 url=%local_var_uri_str,
531 method="GET",
532 "making list_client_applications request",
533 );
534 }
535 }
536
537 {
540 use qcs_api_client_common::configuration::TokenError;
541
542 #[allow(
543 clippy::nonminimal_bool,
544 clippy::eq_op,
545 reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
546 )]
547 let is_jwt_bearer_optional: bool = false;
548
549 let token = local_var_configuration
550 .qcs_config
551 .get_bearer_access_token()
552 .await;
553
554 if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
555 #[cfg(feature = "tracing")]
557 tracing::debug!(
558 "No client credentials found, but this call does not require authentication."
559 );
560 } else {
561 local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
562 }
563 }
564
565 let local_var_req = local_var_req_builder.build()?;
566 let local_var_resp = local_var_client.execute(local_var_req).await?;
567
568 let local_var_status = local_var_resp.status();
569 let local_var_raw_content_type = local_var_resp
570 .headers()
571 .get("content-type")
572 .and_then(|v| v.to_str().ok())
573 .unwrap_or("application/octet-stream")
574 .to_string();
575 let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
576
577 if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
578 let local_var_content = local_var_resp.text().await?;
579 match local_var_content_type {
580 ContentType::Json => serde_path_to_error::deserialize(
581 &mut serde_json::Deserializer::from_str(&local_var_content),
582 )
583 .map_err(Error::from),
584 ContentType::Text => Err(Error::InvalidContentType {
585 content_type: local_var_raw_content_type,
586 return_type: "models::ListClientApplicationsResponse",
587 }),
588 ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
589 content_type: unknown_type,
590 return_type: "models::ListClientApplicationsResponse",
591 }),
592 }
593 } else {
594 let local_var_retry_delay =
595 duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
596 let local_var_content = local_var_resp.text().await?;
597 let local_var_entity: Option<ListClientApplicationsError> =
598 serde_json::from_str(&local_var_content).ok();
599 let local_var_error = ResponseContent {
600 status: local_var_status,
601 content: local_var_content,
602 entity: local_var_entity,
603 retry_delay: local_var_retry_delay,
604 };
605 Err(Error::ResponseError(local_var_error))
606 }
607}
608
609pub async fn list_client_applications(
611 configuration: &configuration::Configuration,
612) -> Result<models::ListClientApplicationsResponse, Error<ListClientApplicationsError>> {
613 let mut backoff = configuration.backoff.clone();
614 let mut refreshed_credentials = false;
615 let method = reqwest::Method::GET;
616 loop {
617 let result = list_client_applications_inner(configuration, &mut backoff).await;
618
619 match result {
620 Ok(result) => return Ok(result),
621 Err(Error::ResponseError(response)) => {
622 if !refreshed_credentials
623 && matches!(
624 response.status,
625 StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
626 )
627 {
628 match configuration.qcs_config.refresh().await {
630 Ok(_) => {
631 refreshed_credentials = true;
632 continue;
633 }
634 Err(::qcs_api_client_common::configuration::TokenError::Write {
635 error,
636 oauth_session: _,
637 }) => {
638 #[cfg(feature = "tracing")]
641 tracing::warn!(
642 "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
643 error
644 );
645 refreshed_credentials = true;
646 continue;
647 }
648 Err(e) => return Err(e.into()),
649 }
650 } else if let Some(duration) = response.retry_delay {
651 tokio::time::sleep(duration).await;
652 continue;
653 }
654
655 return Err(Error::ResponseError(response));
656 }
657 Err(Error::Reqwest(error)) => {
658 if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
659 tokio::time::sleep(duration).await;
660 continue;
661 }
662
663 return Err(Error::Reqwest(error));
664 }
665 Err(Error::Io(error)) => {
666 if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
667 tokio::time::sleep(duration).await;
668 continue;
669 }
670
671 return Err(Error::Io(error));
672 }
673 Err(error) => return Err(error),
674 }
675 }
676}