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