qcs_api_client_openapi/apis/
endpoints_api.rs

1// Copyright 2022 Rigetti Computing
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/*
16 * Rigetti QCS API
17 *
18 * # Introduction  This is the documentation for the Rigetti QCS HTTP API.  You can find out more about Rigetti at [https://rigetti.com](https://rigetti.com), and also interact with QCS via the web at [https://qcs.rigetti.com](https://qcs.rigetti.com).  This API is documented in **OpenAPI format** and so is compatible with the dozens of language-specific client generators available [here](https://github.com/OpenAPITools/openapi-generator) and elsewhere on the web.  # Principles  This API follows REST design principles where appropriate, and otherwise an HTTP RPC paradigm. We adhere to the Google [API Improvement Proposals](https://google.aip.dev/general) where reasonable to provide a consistent, intuitive developer experience. HTTP response codes match their specifications, and error messages fit a common format.  # Authentication  All access to the QCS API requires OAuth2 authentication provided by Okta. You can request access [here](https://www.rigetti.com/get-quantum). Once you have a user account, you can download your access token from QCS [here](https://qcs.rigetti.com/auth/token).   That access token is valid for 24 hours after issuance. The value of `access_token` within the JSON file is the token used for authentication (don't use the entire JSON file).  Authenticate requests using the `Authorization` header and a `Bearer` prefix:  ``` curl --header \"Authorization: Bearer eyJraW...Iow\" ```  # Quantum Processor Access  Access to the quantum processors themselves is not yet provided directly by this HTTP API, but is instead performed over ZeroMQ/[rpcq](https://github.com/rigetti/rpcq). Until that changes, we suggest using [pyquil](https://github.com/rigetti/pyquil) to build and execute quantum programs via the Legacy API.  # Legacy API  Our legacy HTTP API remains accessible at https://forest-server.qcs.rigetti.com, and it shares a source of truth with this API's services. You can use either service with the same user account and means of authentication. We strongly recommend using the API documented here, as the legacy API is on the path to deprecation.
19 *
20 * The version of the OpenAPI document: 2020-07-31
21 * Contact: support@rigetti.com
22 * Generated by: https://openapi-generator.tech
23 */
24
25use 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#[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/// Serialize command-line arguments for [`create_endpoint`]
40#[cfg(feature = "clap")]
41#[derive(Debug, clap::Args)]
42pub struct CreateEndpointClapParams {
43    pub create_endpoint_parameters: JsonMaybeStdin<crate::models::CreateEndpointParameters>,
44}
45
46#[cfg(feature = "clap")]
47impl CreateEndpointClapParams {
48    pub async fn execute(
49        self,
50        configuration: &configuration::Configuration,
51    ) -> Result<crate::models::Endpoint, miette::Error> {
52        let request = self.create_endpoint_parameters.into_inner().into_inner();
53
54        create_endpoint(configuration, request)
55            .await
56            .into_diagnostic()
57    }
58}
59
60/// Serialize command-line arguments for [`delete_endpoint`]
61#[cfg(feature = "clap")]
62#[derive(Debug, clap::Args)]
63pub struct DeleteEndpointClapParams {
64    #[arg(long)]
65    pub endpoint_id: String,
66}
67
68#[cfg(feature = "clap")]
69impl DeleteEndpointClapParams {
70    pub async fn execute(
71        self,
72        configuration: &configuration::Configuration,
73    ) -> Result<(), miette::Error> {
74        delete_endpoint(configuration, self.endpoint_id.as_str())
75            .await
76            .into_diagnostic()
77    }
78}
79
80/// Serialize command-line arguments for [`get_default_endpoint`]
81#[cfg(feature = "clap")]
82#[derive(Debug, clap::Args)]
83pub struct GetDefaultEndpointClapParams {
84    /// Public identifier for a quantum processor [example: Aspen-1]
85    #[arg(long)]
86    pub quantum_processor_id: String,
87}
88
89#[cfg(feature = "clap")]
90impl GetDefaultEndpointClapParams {
91    pub async fn execute(
92        self,
93        configuration: &configuration::Configuration,
94    ) -> Result<crate::models::Endpoint, miette::Error> {
95        get_default_endpoint(configuration, self.quantum_processor_id.as_str())
96            .await
97            .into_diagnostic()
98    }
99}
100
101/// Serialize command-line arguments for [`get_endpoint`]
102#[cfg(feature = "clap")]
103#[derive(Debug, clap::Args)]
104pub struct GetEndpointClapParams {
105    #[arg(long)]
106    pub endpoint_id: String,
107}
108
109#[cfg(feature = "clap")]
110impl GetEndpointClapParams {
111    pub async fn execute(
112        self,
113        configuration: &configuration::Configuration,
114    ) -> Result<crate::models::Endpoint, miette::Error> {
115        get_endpoint(configuration, self.endpoint_id.as_str())
116            .await
117            .into_diagnostic()
118    }
119}
120
121/// Serialize command-line arguments for [`list_endpoints`]
122#[cfg(feature = "clap")]
123#[derive(Debug, clap::Args)]
124pub struct ListEndpointsClapParams {
125    /// Filtering logic specified using [rule-engine](https://zerosteiner.github.io/rule-engine/syntax.html) grammar
126    #[arg(long)]
127    pub filter: Option<String>,
128    #[arg(long)]
129    pub page_size: Option<i64>,
130    #[arg(long)]
131    pub page_token: Option<String>,
132}
133
134#[cfg(feature = "clap")]
135impl ListEndpointsClapParams {
136    pub async fn execute(
137        self,
138        configuration: &configuration::Configuration,
139    ) -> Result<crate::models::ListEndpointsResponse, miette::Error> {
140        list_endpoints(
141            configuration,
142            self.filter.as_deref(),
143            self.page_size,
144            self.page_token.as_deref(),
145        )
146        .await
147        .into_diagnostic()
148    }
149}
150
151/// Serialize command-line arguments for [`restart_endpoint`]
152#[cfg(feature = "clap")]
153#[derive(Debug, clap::Args)]
154pub struct RestartEndpointClapParams {
155    #[arg(long)]
156    pub endpoint_id: String,
157    pub restart_endpoint_request: Option<JsonMaybeStdin<crate::models::RestartEndpointRequest>>,
158}
159
160#[cfg(feature = "clap")]
161impl RestartEndpointClapParams {
162    pub async fn execute(
163        self,
164        configuration: &configuration::Configuration,
165    ) -> Result<(), miette::Error> {
166        let request = self
167            .restart_endpoint_request
168            .map(|body| body.into_inner().into_inner());
169
170        restart_endpoint(configuration, self.endpoint_id.as_str(), request)
171            .await
172            .into_diagnostic()
173    }
174}
175
176/// struct for typed errors of method [`create_endpoint`]
177#[derive(Debug, Clone, Serialize, Deserialize)]
178#[serde(untagged)]
179pub enum CreateEndpointError {
180    Status400(crate::models::Error),
181    Status404(crate::models::Error),
182    Status422(crate::models::ValidationError),
183    UnknownValue(serde_json::Value),
184}
185
186/// struct for typed errors of method [`delete_endpoint`]
187#[derive(Debug, Clone, Serialize, Deserialize)]
188#[serde(untagged)]
189pub enum DeleteEndpointError {
190    Status403(crate::models::Error),
191    Status404(crate::models::Error),
192    Status422(crate::models::ValidationError),
193    UnknownValue(serde_json::Value),
194}
195
196/// struct for typed errors of method [`get_default_endpoint`]
197#[derive(Debug, Clone, Serialize, Deserialize)]
198#[serde(untagged)]
199pub enum GetDefaultEndpointError {
200    Status404(crate::models::Error),
201    Status422(crate::models::ValidationError),
202    UnknownValue(serde_json::Value),
203}
204
205/// struct for typed errors of method [`get_endpoint`]
206#[derive(Debug, Clone, Serialize, Deserialize)]
207#[serde(untagged)]
208pub enum GetEndpointError {
209    Status404(crate::models::Error),
210    Status422(crate::models::ValidationError),
211    UnknownValue(serde_json::Value),
212}
213
214/// struct for typed errors of method [`list_endpoints`]
215#[derive(Debug, Clone, Serialize, Deserialize)]
216#[serde(untagged)]
217pub enum ListEndpointsError {
218    Status422(crate::models::ValidationError),
219    UnknownValue(serde_json::Value),
220}
221
222/// struct for typed errors of method [`restart_endpoint`]
223#[derive(Debug, Clone, Serialize, Deserialize)]
224#[serde(untagged)]
225pub enum RestartEndpointError {
226    Status403(crate::models::Error),
227    Status422(crate::models::ValidationError),
228    UnknownValue(serde_json::Value),
229}
230
231async fn create_endpoint_inner(
232    configuration: &configuration::Configuration,
233    backoff: &mut ExponentialBackoff,
234    create_endpoint_parameters: crate::models::CreateEndpointParameters,
235) -> Result<crate::models::Endpoint, Error<CreateEndpointError>> {
236    let local_var_configuration = configuration;
237
238    let local_var_client = &local_var_configuration.client;
239
240    let local_var_uri_str = format!(
241        "{}/v1/endpoints",
242        local_var_configuration.qcs_config.api_url()
243    );
244    let mut local_var_req_builder =
245        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
246
247    #[cfg(feature = "tracing")]
248    {
249        // Ignore parsing errors if the URL is invalid for some reason.
250        // If it is invalid, it will turn up as an error later when actually making the request.
251        let local_var_do_tracing = local_var_uri_str
252            .parse::<::url::Url>()
253            .ok()
254            .is_none_or(|url| {
255                configuration
256                    .qcs_config
257                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
258            });
259
260        if local_var_do_tracing {
261            ::tracing::debug!(
262                url=%local_var_uri_str,
263                method="POST",
264                "making create_endpoint request",
265            );
266        }
267    }
268
269    // Use the QCS Bearer token if a client OAuthSession is present,
270    // but do not require one when the security schema says it is optional.
271    {
272        use qcs_api_client_common::configuration::TokenError;
273
274        #[allow(
275            clippy::nonminimal_bool,
276            clippy::eq_op,
277            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
278        )]
279        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
280
281        let token = local_var_configuration
282            .qcs_config
283            .get_bearer_access_token()
284            .await;
285
286        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
287            // the client is configured without any OAuthSession, but this call does not require one.
288            #[cfg(feature = "tracing")]
289            tracing::debug!(
290                "No client credentials found, but this call does not require authentication."
291            );
292        } else {
293            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
294        }
295    }
296
297    local_var_req_builder = local_var_req_builder.json(&create_endpoint_parameters);
298
299    let local_var_req = local_var_req_builder.build()?;
300    let local_var_resp = local_var_client.execute(local_var_req).await?;
301
302    let local_var_status = local_var_resp.status();
303
304    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
305        let local_var_content = local_var_resp.text().await?;
306        serde_json::from_str(&local_var_content).map_err(Error::from)
307    } else {
308        let local_var_retry_delay =
309            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
310        let local_var_content = local_var_resp.text().await?;
311        let local_var_entity: Option<CreateEndpointError> =
312            serde_json::from_str(&local_var_content).ok();
313        let local_var_error = ResponseContent {
314            status: local_var_status,
315            content: local_var_content,
316            entity: local_var_entity,
317            retry_delay: local_var_retry_delay,
318        };
319        Err(Error::ResponseError(local_var_error))
320    }
321}
322
323/// Create an endpoint associated with your user account.
324pub async fn create_endpoint(
325    configuration: &configuration::Configuration,
326    create_endpoint_parameters: crate::models::CreateEndpointParameters,
327) -> Result<crate::models::Endpoint, Error<CreateEndpointError>> {
328    let mut backoff = configuration.backoff.clone();
329    let mut refreshed_credentials = false;
330    let method = reqwest::Method::POST;
331    loop {
332        let result = create_endpoint_inner(
333            configuration,
334            &mut backoff,
335            create_endpoint_parameters.clone(),
336        )
337        .await;
338
339        match result {
340            Ok(result) => return Ok(result),
341            Err(Error::ResponseError(response)) => {
342                if !refreshed_credentials
343                    && matches!(
344                        response.status,
345                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
346                    )
347                {
348                    configuration.qcs_config.refresh().await?;
349                    refreshed_credentials = true;
350                    continue;
351                } else if let Some(duration) = response.retry_delay {
352                    tokio::time::sleep(duration).await;
353                    continue;
354                }
355
356                return Err(Error::ResponseError(response));
357            }
358            Err(Error::Reqwest(error)) => {
359                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
360                    tokio::time::sleep(duration).await;
361                    continue;
362                }
363
364                return Err(Error::Reqwest(error));
365            }
366            Err(Error::Io(error)) => {
367                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
368                    tokio::time::sleep(duration).await;
369                    continue;
370                }
371
372                return Err(Error::Io(error));
373            }
374            Err(error) => return Err(error),
375        }
376    }
377}
378async fn delete_endpoint_inner(
379    configuration: &configuration::Configuration,
380    backoff: &mut ExponentialBackoff,
381    endpoint_id: &str,
382) -> Result<(), Error<DeleteEndpointError>> {
383    let local_var_configuration = configuration;
384
385    let local_var_client = &local_var_configuration.client;
386
387    let local_var_uri_str = format!(
388        "{}/v1/endpoints/{endpointId}",
389        local_var_configuration.qcs_config.api_url(),
390        endpointId = crate::apis::urlencode(endpoint_id)
391    );
392    let mut local_var_req_builder =
393        local_var_client.request(reqwest::Method::DELETE, local_var_uri_str.as_str());
394
395    #[cfg(feature = "tracing")]
396    {
397        // Ignore parsing errors if the URL is invalid for some reason.
398        // If it is invalid, it will turn up as an error later when actually making the request.
399        let local_var_do_tracing = local_var_uri_str
400            .parse::<::url::Url>()
401            .ok()
402            .is_none_or(|url| {
403                configuration
404                    .qcs_config
405                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
406            });
407
408        if local_var_do_tracing {
409            ::tracing::debug!(
410                url=%local_var_uri_str,
411                method="DELETE",
412                "making delete_endpoint request",
413            );
414        }
415    }
416
417    // Use the QCS Bearer token if a client OAuthSession is present,
418    // but do not require one when the security schema says it is optional.
419    {
420        use qcs_api_client_common::configuration::TokenError;
421
422        #[allow(
423            clippy::nonminimal_bool,
424            clippy::eq_op,
425            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
426        )]
427        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
428
429        let token = local_var_configuration
430            .qcs_config
431            .get_bearer_access_token()
432            .await;
433
434        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
435            // the client is configured without any OAuthSession, but this call does not require one.
436            #[cfg(feature = "tracing")]
437            tracing::debug!(
438                "No client credentials found, but this call does not require authentication."
439            );
440        } else {
441            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
442        }
443    }
444
445    let local_var_req = local_var_req_builder.build()?;
446    let local_var_resp = local_var_client.execute(local_var_req).await?;
447
448    let local_var_status = local_var_resp.status();
449
450    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
451        Ok(())
452    } else {
453        let local_var_retry_delay =
454            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
455        let local_var_content = local_var_resp.text().await?;
456        let local_var_entity: Option<DeleteEndpointError> =
457            serde_json::from_str(&local_var_content).ok();
458        let local_var_error = ResponseContent {
459            status: local_var_status,
460            content: local_var_content,
461            entity: local_var_entity,
462            retry_delay: local_var_retry_delay,
463        };
464        Err(Error::ResponseError(local_var_error))
465    }
466}
467
468/// Delete an endpoint, releasing its resources. This operation is not reversible.
469pub async fn delete_endpoint(
470    configuration: &configuration::Configuration,
471    endpoint_id: &str,
472) -> Result<(), Error<DeleteEndpointError>> {
473    let mut backoff = configuration.backoff.clone();
474    let mut refreshed_credentials = false;
475    let method = reqwest::Method::DELETE;
476    loop {
477        let result = delete_endpoint_inner(configuration, &mut backoff, endpoint_id.clone()).await;
478
479        match result {
480            Ok(result) => return Ok(result),
481            Err(Error::ResponseError(response)) => {
482                if !refreshed_credentials
483                    && matches!(
484                        response.status,
485                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
486                    )
487                {
488                    configuration.qcs_config.refresh().await?;
489                    refreshed_credentials = true;
490                    continue;
491                } else if let Some(duration) = response.retry_delay {
492                    tokio::time::sleep(duration).await;
493                    continue;
494                }
495
496                return Err(Error::ResponseError(response));
497            }
498            Err(Error::Reqwest(error)) => {
499                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
500                    tokio::time::sleep(duration).await;
501                    continue;
502                }
503
504                return Err(Error::Reqwest(error));
505            }
506            Err(Error::Io(error)) => {
507                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
508                    tokio::time::sleep(duration).await;
509                    continue;
510                }
511
512                return Err(Error::Io(error));
513            }
514            Err(error) => return Err(error),
515        }
516    }
517}
518async fn get_default_endpoint_inner(
519    configuration: &configuration::Configuration,
520    backoff: &mut ExponentialBackoff,
521    quantum_processor_id: &str,
522) -> Result<crate::models::Endpoint, Error<GetDefaultEndpointError>> {
523    let local_var_configuration = configuration;
524
525    let local_var_client = &local_var_configuration.client;
526
527    let local_var_uri_str = format!(
528        "{}/v1/quantumProcessors/{quantumProcessorId}/endpoints:getDefault",
529        local_var_configuration.qcs_config.api_url(),
530        quantumProcessorId = crate::apis::urlencode(quantum_processor_id)
531    );
532    let mut local_var_req_builder =
533        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
534
535    #[cfg(feature = "tracing")]
536    {
537        // Ignore parsing errors if the URL is invalid for some reason.
538        // If it is invalid, it will turn up as an error later when actually making the request.
539        let local_var_do_tracing = local_var_uri_str
540            .parse::<::url::Url>()
541            .ok()
542            .is_none_or(|url| {
543                configuration
544                    .qcs_config
545                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
546            });
547
548        if local_var_do_tracing {
549            ::tracing::debug!(
550                url=%local_var_uri_str,
551                method="GET",
552                "making get_default_endpoint request",
553            );
554        }
555    }
556
557    // Use the QCS Bearer token if a client OAuthSession is present,
558    // but do not require one when the security schema says it is optional.
559    {
560        use qcs_api_client_common::configuration::TokenError;
561
562        #[allow(
563            clippy::nonminimal_bool,
564            clippy::eq_op,
565            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
566        )]
567        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
568
569        let token = local_var_configuration
570            .qcs_config
571            .get_bearer_access_token()
572            .await;
573
574        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
575            // the client is configured without any OAuthSession, but this call does not require one.
576            #[cfg(feature = "tracing")]
577            tracing::debug!(
578                "No client credentials found, but this call does not require authentication."
579            );
580        } else {
581            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
582        }
583    }
584
585    let local_var_req = local_var_req_builder.build()?;
586    let local_var_resp = local_var_client.execute(local_var_req).await?;
587
588    let local_var_status = local_var_resp.status();
589
590    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
591        let local_var_content = local_var_resp.text().await?;
592        serde_json::from_str(&local_var_content).map_err(Error::from)
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<GetDefaultEndpointError> =
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
609/// Retrieve the endpoint set as \"default\" for the given Quantum Processor.  If no endpoint is set as the default, return \"not found.\"
610pub async fn get_default_endpoint(
611    configuration: &configuration::Configuration,
612    quantum_processor_id: &str,
613) -> Result<crate::models::Endpoint, Error<GetDefaultEndpointError>> {
614    let mut backoff = configuration.backoff.clone();
615    let mut refreshed_credentials = false;
616    let method = reqwest::Method::GET;
617    loop {
618        let result =
619            get_default_endpoint_inner(configuration, &mut backoff, quantum_processor_id.clone())
620                .await;
621
622        match result {
623            Ok(result) => return Ok(result),
624            Err(Error::ResponseError(response)) => {
625                if !refreshed_credentials
626                    && matches!(
627                        response.status,
628                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
629                    )
630                {
631                    configuration.qcs_config.refresh().await?;
632                    refreshed_credentials = true;
633                    continue;
634                } else if let Some(duration) = response.retry_delay {
635                    tokio::time::sleep(duration).await;
636                    continue;
637                }
638
639                return Err(Error::ResponseError(response));
640            }
641            Err(Error::Reqwest(error)) => {
642                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
643                    tokio::time::sleep(duration).await;
644                    continue;
645                }
646
647                return Err(Error::Reqwest(error));
648            }
649            Err(Error::Io(error)) => {
650                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
651                    tokio::time::sleep(duration).await;
652                    continue;
653                }
654
655                return Err(Error::Io(error));
656            }
657            Err(error) => return Err(error),
658        }
659    }
660}
661async fn get_endpoint_inner(
662    configuration: &configuration::Configuration,
663    backoff: &mut ExponentialBackoff,
664    endpoint_id: &str,
665) -> Result<crate::models::Endpoint, Error<GetEndpointError>> {
666    let local_var_configuration = configuration;
667
668    let local_var_client = &local_var_configuration.client;
669
670    let local_var_uri_str = format!(
671        "{}/v1/endpoints/{endpointId}",
672        local_var_configuration.qcs_config.api_url(),
673        endpointId = crate::apis::urlencode(endpoint_id)
674    );
675    let mut local_var_req_builder =
676        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
677
678    #[cfg(feature = "tracing")]
679    {
680        // Ignore parsing errors if the URL is invalid for some reason.
681        // If it is invalid, it will turn up as an error later when actually making the request.
682        let local_var_do_tracing = local_var_uri_str
683            .parse::<::url::Url>()
684            .ok()
685            .is_none_or(|url| {
686                configuration
687                    .qcs_config
688                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
689            });
690
691        if local_var_do_tracing {
692            ::tracing::debug!(
693                url=%local_var_uri_str,
694                method="GET",
695                "making get_endpoint request",
696            );
697        }
698    }
699
700    // Use the QCS Bearer token if a client OAuthSession is present,
701    // but do not require one when the security schema says it is optional.
702    {
703        use qcs_api_client_common::configuration::TokenError;
704
705        #[allow(
706            clippy::nonminimal_bool,
707            clippy::eq_op,
708            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
709        )]
710        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
711
712        let token = local_var_configuration
713            .qcs_config
714            .get_bearer_access_token()
715            .await;
716
717        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
718            // the client is configured without any OAuthSession, but this call does not require one.
719            #[cfg(feature = "tracing")]
720            tracing::debug!(
721                "No client credentials found, but this call does not require authentication."
722            );
723        } else {
724            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
725        }
726    }
727
728    let local_var_req = local_var_req_builder.build()?;
729    let local_var_resp = local_var_client.execute(local_var_req).await?;
730
731    let local_var_status = local_var_resp.status();
732
733    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
734        let local_var_content = local_var_resp.text().await?;
735        serde_json::from_str(&local_var_content).map_err(Error::from)
736    } else {
737        let local_var_retry_delay =
738            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
739        let local_var_content = local_var_resp.text().await?;
740        let local_var_entity: Option<GetEndpointError> =
741            serde_json::from_str(&local_var_content).ok();
742        let local_var_error = ResponseContent {
743            status: local_var_status,
744            content: local_var_content,
745            entity: local_var_entity,
746            retry_delay: local_var_retry_delay,
747        };
748        Err(Error::ResponseError(local_var_error))
749    }
750}
751
752/// Retrieve a specific endpoint by its ID.
753pub async fn get_endpoint(
754    configuration: &configuration::Configuration,
755    endpoint_id: &str,
756) -> Result<crate::models::Endpoint, Error<GetEndpointError>> {
757    let mut backoff = configuration.backoff.clone();
758    let mut refreshed_credentials = false;
759    let method = reqwest::Method::GET;
760    loop {
761        let result = get_endpoint_inner(configuration, &mut backoff, endpoint_id.clone()).await;
762
763        match result {
764            Ok(result) => return Ok(result),
765            Err(Error::ResponseError(response)) => {
766                if !refreshed_credentials
767                    && matches!(
768                        response.status,
769                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
770                    )
771                {
772                    configuration.qcs_config.refresh().await?;
773                    refreshed_credentials = true;
774                    continue;
775                } else if let Some(duration) = response.retry_delay {
776                    tokio::time::sleep(duration).await;
777                    continue;
778                }
779
780                return Err(Error::ResponseError(response));
781            }
782            Err(Error::Reqwest(error)) => {
783                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
784                    tokio::time::sleep(duration).await;
785                    continue;
786                }
787
788                return Err(Error::Reqwest(error));
789            }
790            Err(Error::Io(error)) => {
791                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
792                    tokio::time::sleep(duration).await;
793                    continue;
794                }
795
796                return Err(Error::Io(error));
797            }
798            Err(error) => return Err(error),
799        }
800    }
801}
802async fn list_endpoints_inner(
803    configuration: &configuration::Configuration,
804    backoff: &mut ExponentialBackoff,
805    filter: Option<&str>,
806    page_size: Option<i64>,
807    page_token: Option<&str>,
808) -> Result<crate::models::ListEndpointsResponse, Error<ListEndpointsError>> {
809    let local_var_configuration = configuration;
810
811    let local_var_client = &local_var_configuration.client;
812
813    let local_var_uri_str = format!(
814        "{}/v1/endpoints",
815        local_var_configuration.qcs_config.api_url()
816    );
817    let mut local_var_req_builder =
818        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
819
820    #[cfg(feature = "tracing")]
821    {
822        // Ignore parsing errors if the URL is invalid for some reason.
823        // If it is invalid, it will turn up as an error later when actually making the request.
824        let local_var_do_tracing = local_var_uri_str
825            .parse::<::url::Url>()
826            .ok()
827            .is_none_or(|url| {
828                configuration
829                    .qcs_config
830                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
831            });
832
833        if local_var_do_tracing {
834            ::tracing::debug!(
835                url=%local_var_uri_str,
836                method="GET",
837                "making list_endpoints request",
838            );
839        }
840    }
841
842    if let Some(ref local_var_str) = filter {
843        local_var_req_builder =
844            local_var_req_builder.query(&[("filter", &local_var_str.to_string())]);
845    }
846    if let Some(ref local_var_str) = page_size {
847        local_var_req_builder =
848            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
849    }
850    if let Some(ref local_var_str) = page_token {
851        local_var_req_builder =
852            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
853    }
854
855    // Use the QCS Bearer token if a client OAuthSession is present,
856    // but do not require one when the security schema says it is optional.
857    {
858        use qcs_api_client_common::configuration::TokenError;
859
860        #[allow(
861            clippy::nonminimal_bool,
862            clippy::eq_op,
863            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
864        )]
865        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
866
867        let token = local_var_configuration
868            .qcs_config
869            .get_bearer_access_token()
870            .await;
871
872        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
873            // the client is configured without any OAuthSession, but this call does not require one.
874            #[cfg(feature = "tracing")]
875            tracing::debug!(
876                "No client credentials found, but this call does not require authentication."
877            );
878        } else {
879            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
880        }
881    }
882
883    let local_var_req = local_var_req_builder.build()?;
884    let local_var_resp = local_var_client.execute(local_var_req).await?;
885
886    let local_var_status = local_var_resp.status();
887
888    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
889        let local_var_content = local_var_resp.text().await?;
890        serde_json::from_str(&local_var_content).map_err(Error::from)
891    } else {
892        let local_var_retry_delay =
893            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
894        let local_var_content = local_var_resp.text().await?;
895        let local_var_entity: Option<ListEndpointsError> =
896            serde_json::from_str(&local_var_content).ok();
897        let local_var_error = ResponseContent {
898            status: local_var_status,
899            content: local_var_content,
900            entity: local_var_entity,
901            retry_delay: local_var_retry_delay,
902        };
903        Err(Error::ResponseError(local_var_error))
904    }
905}
906
907/// List all endpoints, optionally filtering by attribute.
908pub async fn list_endpoints(
909    configuration: &configuration::Configuration,
910    filter: Option<&str>,
911    page_size: Option<i64>,
912    page_token: Option<&str>,
913) -> Result<crate::models::ListEndpointsResponse, Error<ListEndpointsError>> {
914    let mut backoff = configuration.backoff.clone();
915    let mut refreshed_credentials = false;
916    let method = reqwest::Method::GET;
917    loop {
918        let result = list_endpoints_inner(
919            configuration,
920            &mut backoff,
921            filter.clone(),
922            page_size.clone(),
923            page_token.clone(),
924        )
925        .await;
926
927        match result {
928            Ok(result) => return Ok(result),
929            Err(Error::ResponseError(response)) => {
930                if !refreshed_credentials
931                    && matches!(
932                        response.status,
933                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
934                    )
935                {
936                    configuration.qcs_config.refresh().await?;
937                    refreshed_credentials = true;
938                    continue;
939                } else if let Some(duration) = response.retry_delay {
940                    tokio::time::sleep(duration).await;
941                    continue;
942                }
943
944                return Err(Error::ResponseError(response));
945            }
946            Err(Error::Reqwest(error)) => {
947                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
948                    tokio::time::sleep(duration).await;
949                    continue;
950                }
951
952                return Err(Error::Reqwest(error));
953            }
954            Err(Error::Io(error)) => {
955                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
956                    tokio::time::sleep(duration).await;
957                    continue;
958                }
959
960                return Err(Error::Io(error));
961            }
962            Err(error) => return Err(error),
963        }
964    }
965}
966async fn restart_endpoint_inner(
967    configuration: &configuration::Configuration,
968    backoff: &mut ExponentialBackoff,
969    endpoint_id: &str,
970    restart_endpoint_request: Option<crate::models::RestartEndpointRequest>,
971) -> Result<(), Error<RestartEndpointError>> {
972    let local_var_configuration = configuration;
973
974    let local_var_client = &local_var_configuration.client;
975
976    let local_var_uri_str = format!(
977        "{}/v1/endpoints/{endpointId}:restart",
978        local_var_configuration.qcs_config.api_url(),
979        endpointId = crate::apis::urlencode(endpoint_id)
980    );
981    let mut local_var_req_builder =
982        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
983
984    #[cfg(feature = "tracing")]
985    {
986        // Ignore parsing errors if the URL is invalid for some reason.
987        // If it is invalid, it will turn up as an error later when actually making the request.
988        let local_var_do_tracing = local_var_uri_str
989            .parse::<::url::Url>()
990            .ok()
991            .is_none_or(|url| {
992                configuration
993                    .qcs_config
994                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
995            });
996
997        if local_var_do_tracing {
998            ::tracing::debug!(
999                url=%local_var_uri_str,
1000                method="POST",
1001                "making restart_endpoint request",
1002            );
1003        }
1004    }
1005
1006    // Use the QCS Bearer token if a client OAuthSession is present,
1007    // but do not require one when the security schema says it is optional.
1008    {
1009        use qcs_api_client_common::configuration::TokenError;
1010
1011        #[allow(
1012            clippy::nonminimal_bool,
1013            clippy::eq_op,
1014            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
1015        )]
1016        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
1017
1018        let token = local_var_configuration
1019            .qcs_config
1020            .get_bearer_access_token()
1021            .await;
1022
1023        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
1024            // the client is configured without any OAuthSession, but this call does not require one.
1025            #[cfg(feature = "tracing")]
1026            tracing::debug!(
1027                "No client credentials found, but this call does not require authentication."
1028            );
1029        } else {
1030            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
1031        }
1032    }
1033
1034    local_var_req_builder = local_var_req_builder.json(&restart_endpoint_request);
1035
1036    let local_var_req = local_var_req_builder.build()?;
1037    let local_var_resp = local_var_client.execute(local_var_req).await?;
1038
1039    let local_var_status = local_var_resp.status();
1040
1041    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1042        Ok(())
1043    } else {
1044        let local_var_retry_delay =
1045            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
1046        let local_var_content = local_var_resp.text().await?;
1047        let local_var_entity: Option<RestartEndpointError> =
1048            serde_json::from_str(&local_var_content).ok();
1049        let local_var_error = ResponseContent {
1050            status: local_var_status,
1051            content: local_var_content,
1052            entity: local_var_entity,
1053            retry_delay: local_var_retry_delay,
1054        };
1055        Err(Error::ResponseError(local_var_error))
1056    }
1057}
1058
1059/// Restart an entire endpoint or a single component within an endpoint.
1060pub async fn restart_endpoint(
1061    configuration: &configuration::Configuration,
1062    endpoint_id: &str,
1063    restart_endpoint_request: Option<crate::models::RestartEndpointRequest>,
1064) -> Result<(), Error<RestartEndpointError>> {
1065    let mut backoff = configuration.backoff.clone();
1066    let mut refreshed_credentials = false;
1067    let method = reqwest::Method::POST;
1068    loop {
1069        let result = restart_endpoint_inner(
1070            configuration,
1071            &mut backoff,
1072            endpoint_id.clone(),
1073            restart_endpoint_request.clone(),
1074        )
1075        .await;
1076
1077        match result {
1078            Ok(result) => return Ok(result),
1079            Err(Error::ResponseError(response)) => {
1080                if !refreshed_credentials
1081                    && matches!(
1082                        response.status,
1083                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1084                    )
1085                {
1086                    configuration.qcs_config.refresh().await?;
1087                    refreshed_credentials = true;
1088                    continue;
1089                } else if let Some(duration) = response.retry_delay {
1090                    tokio::time::sleep(duration).await;
1091                    continue;
1092                }
1093
1094                return Err(Error::ResponseError(response));
1095            }
1096            Err(Error::Reqwest(error)) => {
1097                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1098                    tokio::time::sleep(duration).await;
1099                    continue;
1100                }
1101
1102                return Err(Error::Reqwest(error));
1103            }
1104            Err(Error::Io(error)) => {
1105                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1106                    tokio::time::sleep(duration).await;
1107                    continue;
1108                }
1109
1110                return Err(Error::Io(error));
1111            }
1112            Err(error) => return Err(error),
1113        }
1114    }
1115}