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