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/// struct for typed errors of method [`create_endpoint`]
36#[derive(Debug, Clone, Serialize, Deserialize)]
37#[serde(untagged)]
38pub enum CreateEndpointError {
39    Status400(crate::models::Error),
40    Status404(crate::models::Error),
41    Status422(crate::models::ValidationError),
42    UnknownValue(serde_json::Value),
43}
44
45/// struct for typed errors of method [`delete_endpoint`]
46#[derive(Debug, Clone, Serialize, Deserialize)]
47#[serde(untagged)]
48pub enum DeleteEndpointError {
49    Status403(crate::models::Error),
50    Status404(crate::models::Error),
51    Status422(crate::models::ValidationError),
52    UnknownValue(serde_json::Value),
53}
54
55/// struct for typed errors of method [`get_default_endpoint`]
56#[derive(Debug, Clone, Serialize, Deserialize)]
57#[serde(untagged)]
58pub enum GetDefaultEndpointError {
59    Status404(crate::models::Error),
60    Status422(crate::models::ValidationError),
61    UnknownValue(serde_json::Value),
62}
63
64/// struct for typed errors of method [`get_endpoint`]
65#[derive(Debug, Clone, Serialize, Deserialize)]
66#[serde(untagged)]
67pub enum GetEndpointError {
68    Status404(crate::models::Error),
69    Status422(crate::models::ValidationError),
70    UnknownValue(serde_json::Value),
71}
72
73/// struct for typed errors of method [`list_endpoints`]
74#[derive(Debug, Clone, Serialize, Deserialize)]
75#[serde(untagged)]
76pub enum ListEndpointsError {
77    Status422(crate::models::ValidationError),
78    UnknownValue(serde_json::Value),
79}
80
81/// struct for typed errors of method [`restart_endpoint`]
82#[derive(Debug, Clone, Serialize, Deserialize)]
83#[serde(untagged)]
84pub enum RestartEndpointError {
85    Status403(crate::models::Error),
86    Status422(crate::models::ValidationError),
87    UnknownValue(serde_json::Value),
88}
89
90async fn create_endpoint_inner(
91    configuration: &configuration::Configuration,
92    backoff: &mut ExponentialBackoff,
93    create_endpoint_parameters: crate::models::CreateEndpointParameters,
94) -> Result<crate::models::Endpoint, Error<CreateEndpointError>> {
95    let local_var_configuration = configuration;
96
97    let local_var_client = &local_var_configuration.client;
98
99    let local_var_uri_str = format!(
100        "{}/v1/endpoints",
101        local_var_configuration.qcs_config.api_url()
102    );
103    let mut local_var_req_builder =
104        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
105
106    #[cfg(feature = "tracing")]
107    {
108        // Ignore parsing errors if the URL is invalid for some reason.
109        // If it is invalid, it will turn up as an error later when actually making the request.
110        let local_var_do_tracing = local_var_uri_str
111            .parse::<::url::Url>()
112            .ok()
113            .is_none_or(|url| {
114                configuration
115                    .qcs_config
116                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
117            });
118
119        if local_var_do_tracing {
120            ::tracing::debug!(
121                url=%local_var_uri_str,
122                method="POST",
123                "making create_endpoint request",
124            );
125        }
126    }
127
128    // Use the QCS Bearer token if a client OAuthSession is present,
129    // but do not require one when the security schema says it is optional.
130    {
131        use qcs_api_client_common::configuration::TokenError;
132
133        #[allow(
134            clippy::nonminimal_bool,
135            clippy::eq_op,
136            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
137        )]
138        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
139
140        let token = local_var_configuration
141            .qcs_config
142            .get_bearer_access_token()
143            .await;
144
145        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
146            // the client is configured without any OAuthSession, but this call does not require one.
147            #[cfg(feature = "tracing")]
148            tracing::debug!(
149                "No client credentials found, but this call does not require authentication."
150            );
151        } else {
152            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
153        }
154    }
155
156    local_var_req_builder = local_var_req_builder.json(&create_endpoint_parameters);
157
158    let local_var_req = local_var_req_builder.build()?;
159    let local_var_resp = local_var_client.execute(local_var_req).await?;
160
161    let local_var_status = local_var_resp.status();
162
163    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
164        let local_var_content = local_var_resp.text().await?;
165        serde_json::from_str(&local_var_content).map_err(Error::from)
166    } else {
167        let local_var_retry_delay =
168            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
169        let local_var_content = local_var_resp.text().await?;
170        let local_var_entity: Option<CreateEndpointError> =
171            serde_json::from_str(&local_var_content).ok();
172        let local_var_error = ResponseContent {
173            status: local_var_status,
174            content: local_var_content,
175            entity: local_var_entity,
176            retry_delay: local_var_retry_delay,
177        };
178        Err(Error::ResponseError(local_var_error))
179    }
180}
181
182/// Create an endpoint associated with your user account.
183pub async fn create_endpoint(
184    configuration: &configuration::Configuration,
185    create_endpoint_parameters: crate::models::CreateEndpointParameters,
186) -> Result<crate::models::Endpoint, Error<CreateEndpointError>> {
187    let mut backoff = configuration.backoff.clone();
188    let mut refreshed_credentials = false;
189    let method = reqwest::Method::POST;
190    loop {
191        let result = create_endpoint_inner(
192            configuration,
193            &mut backoff,
194            create_endpoint_parameters.clone(),
195        )
196        .await;
197
198        match result {
199            Ok(result) => return Ok(result),
200            Err(Error::ResponseError(response)) => {
201                if !refreshed_credentials
202                    && matches!(
203                        response.status,
204                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
205                    )
206                {
207                    configuration.qcs_config.refresh().await?;
208                    refreshed_credentials = true;
209                    continue;
210                } else if let Some(duration) = response.retry_delay {
211                    tokio::time::sleep(duration).await;
212                    continue;
213                }
214
215                return Err(Error::ResponseError(response));
216            }
217            Err(Error::Reqwest(error)) => {
218                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
219                    tokio::time::sleep(duration).await;
220                    continue;
221                }
222
223                return Err(Error::Reqwest(error));
224            }
225            Err(Error::Io(error)) => {
226                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
227                    tokio::time::sleep(duration).await;
228                    continue;
229                }
230
231                return Err(Error::Io(error));
232            }
233            Err(error) => return Err(error),
234        }
235    }
236}
237async fn delete_endpoint_inner(
238    configuration: &configuration::Configuration,
239    backoff: &mut ExponentialBackoff,
240    endpoint_id: &str,
241) -> Result<(), Error<DeleteEndpointError>> {
242    let local_var_configuration = configuration;
243
244    let local_var_client = &local_var_configuration.client;
245
246    let local_var_uri_str = format!(
247        "{}/v1/endpoints/{endpointId}",
248        local_var_configuration.qcs_config.api_url(),
249        endpointId = crate::apis::urlencode(endpoint_id)
250    );
251    let mut local_var_req_builder =
252        local_var_client.request(reqwest::Method::DELETE, local_var_uri_str.as_str());
253
254    #[cfg(feature = "tracing")]
255    {
256        // Ignore parsing errors if the URL is invalid for some reason.
257        // If it is invalid, it will turn up as an error later when actually making the request.
258        let local_var_do_tracing = local_var_uri_str
259            .parse::<::url::Url>()
260            .ok()
261            .is_none_or(|url| {
262                configuration
263                    .qcs_config
264                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
265            });
266
267        if local_var_do_tracing {
268            ::tracing::debug!(
269                url=%local_var_uri_str,
270                method="DELETE",
271                "making delete_endpoint request",
272            );
273        }
274    }
275
276    // Use the QCS Bearer token if a client OAuthSession is present,
277    // but do not require one when the security schema says it is optional.
278    {
279        use qcs_api_client_common::configuration::TokenError;
280
281        #[allow(
282            clippy::nonminimal_bool,
283            clippy::eq_op,
284            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
285        )]
286        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
287
288        let token = local_var_configuration
289            .qcs_config
290            .get_bearer_access_token()
291            .await;
292
293        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
294            // the client is configured without any OAuthSession, but this call does not require one.
295            #[cfg(feature = "tracing")]
296            tracing::debug!(
297                "No client credentials found, but this call does not require authentication."
298            );
299        } else {
300            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
301        }
302    }
303
304    let local_var_req = local_var_req_builder.build()?;
305    let local_var_resp = local_var_client.execute(local_var_req).await?;
306
307    let local_var_status = local_var_resp.status();
308
309    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
310        Ok(())
311    } else {
312        let local_var_retry_delay =
313            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
314        let local_var_content = local_var_resp.text().await?;
315        let local_var_entity: Option<DeleteEndpointError> =
316            serde_json::from_str(&local_var_content).ok();
317        let local_var_error = ResponseContent {
318            status: local_var_status,
319            content: local_var_content,
320            entity: local_var_entity,
321            retry_delay: local_var_retry_delay,
322        };
323        Err(Error::ResponseError(local_var_error))
324    }
325}
326
327/// Delete an endpoint, releasing its resources. This operation is not reversible.
328pub async fn delete_endpoint(
329    configuration: &configuration::Configuration,
330    endpoint_id: &str,
331) -> Result<(), Error<DeleteEndpointError>> {
332    let mut backoff = configuration.backoff.clone();
333    let mut refreshed_credentials = false;
334    let method = reqwest::Method::DELETE;
335    loop {
336        let result = delete_endpoint_inner(configuration, &mut backoff, endpoint_id.clone()).await;
337
338        match result {
339            Ok(result) => return Ok(result),
340            Err(Error::ResponseError(response)) => {
341                if !refreshed_credentials
342                    && matches!(
343                        response.status,
344                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
345                    )
346                {
347                    configuration.qcs_config.refresh().await?;
348                    refreshed_credentials = true;
349                    continue;
350                } else if let Some(duration) = response.retry_delay {
351                    tokio::time::sleep(duration).await;
352                    continue;
353                }
354
355                return Err(Error::ResponseError(response));
356            }
357            Err(Error::Reqwest(error)) => {
358                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
359                    tokio::time::sleep(duration).await;
360                    continue;
361                }
362
363                return Err(Error::Reqwest(error));
364            }
365            Err(Error::Io(error)) => {
366                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
367                    tokio::time::sleep(duration).await;
368                    continue;
369                }
370
371                return Err(Error::Io(error));
372            }
373            Err(error) => return Err(error),
374        }
375    }
376}
377async fn get_default_endpoint_inner(
378    configuration: &configuration::Configuration,
379    backoff: &mut ExponentialBackoff,
380    quantum_processor_id: &str,
381) -> Result<crate::models::Endpoint, Error<GetDefaultEndpointError>> {
382    let local_var_configuration = configuration;
383
384    let local_var_client = &local_var_configuration.client;
385
386    let local_var_uri_str = format!(
387        "{}/v1/quantumProcessors/{quantumProcessorId}/endpoints:getDefault",
388        local_var_configuration.qcs_config.api_url(),
389        quantumProcessorId = crate::apis::urlencode(quantum_processor_id)
390    );
391    let mut local_var_req_builder =
392        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
393
394    #[cfg(feature = "tracing")]
395    {
396        // Ignore parsing errors if the URL is invalid for some reason.
397        // If it is invalid, it will turn up as an error later when actually making the request.
398        let local_var_do_tracing = local_var_uri_str
399            .parse::<::url::Url>()
400            .ok()
401            .is_none_or(|url| {
402                configuration
403                    .qcs_config
404                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
405            });
406
407        if local_var_do_tracing {
408            ::tracing::debug!(
409                url=%local_var_uri_str,
410                method="GET",
411                "making get_default_endpoint request",
412            );
413        }
414    }
415
416    // Use the QCS Bearer token if a client OAuthSession is present,
417    // but do not require one when the security schema says it is optional.
418    {
419        use qcs_api_client_common::configuration::TokenError;
420
421        #[allow(
422            clippy::nonminimal_bool,
423            clippy::eq_op,
424            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
425        )]
426        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
427
428        let token = local_var_configuration
429            .qcs_config
430            .get_bearer_access_token()
431            .await;
432
433        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
434            // the client is configured without any OAuthSession, but this call does not require one.
435            #[cfg(feature = "tracing")]
436            tracing::debug!(
437                "No client credentials found, but this call does not require authentication."
438            );
439        } else {
440            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
441        }
442    }
443
444    let local_var_req = local_var_req_builder.build()?;
445    let local_var_resp = local_var_client.execute(local_var_req).await?;
446
447    let local_var_status = local_var_resp.status();
448
449    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
450        let local_var_content = local_var_resp.text().await?;
451        serde_json::from_str(&local_var_content).map_err(Error::from)
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<GetDefaultEndpointError> =
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/// Retrieve the endpoint set as \"default\" for the given Quantum Processor.  If no endpoint is set as the default, return \"not found.\"
469pub async fn get_default_endpoint(
470    configuration: &configuration::Configuration,
471    quantum_processor_id: &str,
472) -> Result<crate::models::Endpoint, Error<GetDefaultEndpointError>> {
473    let mut backoff = configuration.backoff.clone();
474    let mut refreshed_credentials = false;
475    let method = reqwest::Method::GET;
476    loop {
477        let result =
478            get_default_endpoint_inner(configuration, &mut backoff, quantum_processor_id.clone())
479                .await;
480
481        match result {
482            Ok(result) => return Ok(result),
483            Err(Error::ResponseError(response)) => {
484                if !refreshed_credentials
485                    && matches!(
486                        response.status,
487                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
488                    )
489                {
490                    configuration.qcs_config.refresh().await?;
491                    refreshed_credentials = true;
492                    continue;
493                } else if let Some(duration) = response.retry_delay {
494                    tokio::time::sleep(duration).await;
495                    continue;
496                }
497
498                return Err(Error::ResponseError(response));
499            }
500            Err(Error::Reqwest(error)) => {
501                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
502                    tokio::time::sleep(duration).await;
503                    continue;
504                }
505
506                return Err(Error::Reqwest(error));
507            }
508            Err(Error::Io(error)) => {
509                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
510                    tokio::time::sleep(duration).await;
511                    continue;
512                }
513
514                return Err(Error::Io(error));
515            }
516            Err(error) => return Err(error),
517        }
518    }
519}
520async fn get_endpoint_inner(
521    configuration: &configuration::Configuration,
522    backoff: &mut ExponentialBackoff,
523    endpoint_id: &str,
524) -> Result<crate::models::Endpoint, Error<GetEndpointError>> {
525    let local_var_configuration = configuration;
526
527    let local_var_client = &local_var_configuration.client;
528
529    let local_var_uri_str = format!(
530        "{}/v1/endpoints/{endpointId}",
531        local_var_configuration.qcs_config.api_url(),
532        endpointId = crate::apis::urlencode(endpoint_id)
533    );
534    let mut local_var_req_builder =
535        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
536
537    #[cfg(feature = "tracing")]
538    {
539        // Ignore parsing errors if the URL is invalid for some reason.
540        // If it is invalid, it will turn up as an error later when actually making the request.
541        let local_var_do_tracing = local_var_uri_str
542            .parse::<::url::Url>()
543            .ok()
544            .is_none_or(|url| {
545                configuration
546                    .qcs_config
547                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
548            });
549
550        if local_var_do_tracing {
551            ::tracing::debug!(
552                url=%local_var_uri_str,
553                method="GET",
554                "making get_endpoint request",
555            );
556        }
557    }
558
559    // Use the QCS Bearer token if a client OAuthSession is present,
560    // but do not require one when the security schema says it is optional.
561    {
562        use qcs_api_client_common::configuration::TokenError;
563
564        #[allow(
565            clippy::nonminimal_bool,
566            clippy::eq_op,
567            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
568        )]
569        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
570
571        let token = local_var_configuration
572            .qcs_config
573            .get_bearer_access_token()
574            .await;
575
576        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
577            // the client is configured without any OAuthSession, but this call does not require one.
578            #[cfg(feature = "tracing")]
579            tracing::debug!(
580                "No client credentials found, but this call does not require authentication."
581            );
582        } else {
583            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
584        }
585    }
586
587    let local_var_req = local_var_req_builder.build()?;
588    let local_var_resp = local_var_client.execute(local_var_req).await?;
589
590    let local_var_status = local_var_resp.status();
591
592    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
593        let local_var_content = local_var_resp.text().await?;
594        serde_json::from_str(&local_var_content).map_err(Error::from)
595    } else {
596        let local_var_retry_delay =
597            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
598        let local_var_content = local_var_resp.text().await?;
599        let local_var_entity: Option<GetEndpointError> =
600            serde_json::from_str(&local_var_content).ok();
601        let local_var_error = ResponseContent {
602            status: local_var_status,
603            content: local_var_content,
604            entity: local_var_entity,
605            retry_delay: local_var_retry_delay,
606        };
607        Err(Error::ResponseError(local_var_error))
608    }
609}
610
611/// Retrieve a specific endpoint by its ID.
612pub async fn get_endpoint(
613    configuration: &configuration::Configuration,
614    endpoint_id: &str,
615) -> Result<crate::models::Endpoint, Error<GetEndpointError>> {
616    let mut backoff = configuration.backoff.clone();
617    let mut refreshed_credentials = false;
618    let method = reqwest::Method::GET;
619    loop {
620        let result = get_endpoint_inner(configuration, &mut backoff, endpoint_id.clone()).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 list_endpoints_inner(
662    configuration: &configuration::Configuration,
663    backoff: &mut ExponentialBackoff,
664    filter: Option<&str>,
665    page_size: Option<i64>,
666    page_token: Option<&str>,
667) -> Result<crate::models::ListEndpointsResponse, Error<ListEndpointsError>> {
668    let local_var_configuration = configuration;
669
670    let local_var_client = &local_var_configuration.client;
671
672    let local_var_uri_str = format!(
673        "{}/v1/endpoints",
674        local_var_configuration.qcs_config.api_url()
675    );
676    let mut local_var_req_builder =
677        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
678
679    #[cfg(feature = "tracing")]
680    {
681        // Ignore parsing errors if the URL is invalid for some reason.
682        // If it is invalid, it will turn up as an error later when actually making the request.
683        let local_var_do_tracing = local_var_uri_str
684            .parse::<::url::Url>()
685            .ok()
686            .is_none_or(|url| {
687                configuration
688                    .qcs_config
689                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
690            });
691
692        if local_var_do_tracing {
693            ::tracing::debug!(
694                url=%local_var_uri_str,
695                method="GET",
696                "making list_endpoints request",
697            );
698        }
699    }
700
701    if let Some(ref local_var_str) = filter {
702        local_var_req_builder =
703            local_var_req_builder.query(&[("filter", &local_var_str.to_string())]);
704    }
705    if let Some(ref local_var_str) = page_size {
706        local_var_req_builder =
707            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
708    }
709    if let Some(ref local_var_str) = page_token {
710        local_var_req_builder =
711            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
712    }
713
714    // Use the QCS Bearer token if a client OAuthSession is present,
715    // but do not require one when the security schema says it is optional.
716    {
717        use qcs_api_client_common::configuration::TokenError;
718
719        #[allow(
720            clippy::nonminimal_bool,
721            clippy::eq_op,
722            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
723        )]
724        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
725
726        let token = local_var_configuration
727            .qcs_config
728            .get_bearer_access_token()
729            .await;
730
731        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
732            // the client is configured without any OAuthSession, but this call does not require one.
733            #[cfg(feature = "tracing")]
734            tracing::debug!(
735                "No client credentials found, but this call does not require authentication."
736            );
737        } else {
738            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
739        }
740    }
741
742    let local_var_req = local_var_req_builder.build()?;
743    let local_var_resp = local_var_client.execute(local_var_req).await?;
744
745    let local_var_status = local_var_resp.status();
746
747    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
748        let local_var_content = local_var_resp.text().await?;
749        serde_json::from_str(&local_var_content).map_err(Error::from)
750    } else {
751        let local_var_retry_delay =
752            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
753        let local_var_content = local_var_resp.text().await?;
754        let local_var_entity: Option<ListEndpointsError> =
755            serde_json::from_str(&local_var_content).ok();
756        let local_var_error = ResponseContent {
757            status: local_var_status,
758            content: local_var_content,
759            entity: local_var_entity,
760            retry_delay: local_var_retry_delay,
761        };
762        Err(Error::ResponseError(local_var_error))
763    }
764}
765
766/// List all endpoints, optionally filtering by attribute.
767pub async fn list_endpoints(
768    configuration: &configuration::Configuration,
769    filter: Option<&str>,
770    page_size: Option<i64>,
771    page_token: Option<&str>,
772) -> Result<crate::models::ListEndpointsResponse, Error<ListEndpointsError>> {
773    let mut backoff = configuration.backoff.clone();
774    let mut refreshed_credentials = false;
775    let method = reqwest::Method::GET;
776    loop {
777        let result = list_endpoints_inner(
778            configuration,
779            &mut backoff,
780            filter.clone(),
781            page_size.clone(),
782            page_token.clone(),
783        )
784        .await;
785
786        match result {
787            Ok(result) => return Ok(result),
788            Err(Error::ResponseError(response)) => {
789                if !refreshed_credentials
790                    && matches!(
791                        response.status,
792                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
793                    )
794                {
795                    configuration.qcs_config.refresh().await?;
796                    refreshed_credentials = true;
797                    continue;
798                } else if let Some(duration) = response.retry_delay {
799                    tokio::time::sleep(duration).await;
800                    continue;
801                }
802
803                return Err(Error::ResponseError(response));
804            }
805            Err(Error::Reqwest(error)) => {
806                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
807                    tokio::time::sleep(duration).await;
808                    continue;
809                }
810
811                return Err(Error::Reqwest(error));
812            }
813            Err(Error::Io(error)) => {
814                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
815                    tokio::time::sleep(duration).await;
816                    continue;
817                }
818
819                return Err(Error::Io(error));
820            }
821            Err(error) => return Err(error),
822        }
823    }
824}
825async fn restart_endpoint_inner(
826    configuration: &configuration::Configuration,
827    backoff: &mut ExponentialBackoff,
828    endpoint_id: &str,
829    restart_endpoint_request: Option<crate::models::RestartEndpointRequest>,
830) -> Result<(), Error<RestartEndpointError>> {
831    let local_var_configuration = configuration;
832
833    let local_var_client = &local_var_configuration.client;
834
835    let local_var_uri_str = format!(
836        "{}/v1/endpoints/{endpointId}:restart",
837        local_var_configuration.qcs_config.api_url(),
838        endpointId = crate::apis::urlencode(endpoint_id)
839    );
840    let mut local_var_req_builder =
841        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
842
843    #[cfg(feature = "tracing")]
844    {
845        // Ignore parsing errors if the URL is invalid for some reason.
846        // If it is invalid, it will turn up as an error later when actually making the request.
847        let local_var_do_tracing = local_var_uri_str
848            .parse::<::url::Url>()
849            .ok()
850            .is_none_or(|url| {
851                configuration
852                    .qcs_config
853                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
854            });
855
856        if local_var_do_tracing {
857            ::tracing::debug!(
858                url=%local_var_uri_str,
859                method="POST",
860                "making restart_endpoint request",
861            );
862        }
863    }
864
865    // Use the QCS Bearer token if a client OAuthSession is present,
866    // but do not require one when the security schema says it is optional.
867    {
868        use qcs_api_client_common::configuration::TokenError;
869
870        #[allow(
871            clippy::nonminimal_bool,
872            clippy::eq_op,
873            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
874        )]
875        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
876
877        let token = local_var_configuration
878            .qcs_config
879            .get_bearer_access_token()
880            .await;
881
882        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
883            // the client is configured without any OAuthSession, but this call does not require one.
884            #[cfg(feature = "tracing")]
885            tracing::debug!(
886                "No client credentials found, but this call does not require authentication."
887            );
888        } else {
889            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
890        }
891    }
892
893    local_var_req_builder = local_var_req_builder.json(&restart_endpoint_request);
894
895    let local_var_req = local_var_req_builder.build()?;
896    let local_var_resp = local_var_client.execute(local_var_req).await?;
897
898    let local_var_status = local_var_resp.status();
899
900    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
901        Ok(())
902    } else {
903        let local_var_retry_delay =
904            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
905        let local_var_content = local_var_resp.text().await?;
906        let local_var_entity: Option<RestartEndpointError> =
907            serde_json::from_str(&local_var_content).ok();
908        let local_var_error = ResponseContent {
909            status: local_var_status,
910            content: local_var_content,
911            entity: local_var_entity,
912            retry_delay: local_var_retry_delay,
913        };
914        Err(Error::ResponseError(local_var_error))
915    }
916}
917
918/// Restart an entire endpoint or a single component within an endpoint.
919pub async fn restart_endpoint(
920    configuration: &configuration::Configuration,
921    endpoint_id: &str,
922    restart_endpoint_request: Option<crate::models::RestartEndpointRequest>,
923) -> Result<(), Error<RestartEndpointError>> {
924    let mut backoff = configuration.backoff.clone();
925    let mut refreshed_credentials = false;
926    let method = reqwest::Method::POST;
927    loop {
928        let result = restart_endpoint_inner(
929            configuration,
930            &mut backoff,
931            endpoint_id.clone(),
932            restart_endpoint_request.clone(),
933        )
934        .await;
935
936        match result {
937            Ok(result) => return Ok(result),
938            Err(Error::ResponseError(response)) => {
939                if !refreshed_credentials
940                    && matches!(
941                        response.status,
942                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
943                    )
944                {
945                    configuration.qcs_config.refresh().await?;
946                    refreshed_credentials = true;
947                    continue;
948                } else if let Some(duration) = response.retry_delay {
949                    tokio::time::sleep(duration).await;
950                    continue;
951                }
952
953                return Err(Error::ResponseError(response));
954            }
955            Err(Error::Reqwest(error)) => {
956                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
957                    tokio::time::sleep(duration).await;
958                    continue;
959                }
960
961                return Err(Error::Reqwest(error));
962            }
963            Err(Error::Io(error)) => {
964                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
965                    tokio::time::sleep(duration).await;
966                    continue;
967                }
968
969                return Err(Error::Io(error));
970            }
971            Err(error) => return Err(error),
972        }
973    }
974}