/// <summary> List repositories in this registry. </summary>
        /// <param name="cancellationToken"> The cancellation token to use. </param>
        /// <exception cref="RequestFailedException">Thrown when a failure is returned by the Container Registry service.</exception>
        public virtual AsyncPageable <string> GetRepositoryNamesAsync(CancellationToken cancellationToken = default)
        {
            async Task <Page <string> > FirstPageFunc(int?pageSizeHint)
            {
                using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ContainerRegistryClient)}.{nameof(GetRepositoryNames)}");
                scope.Start();
                try
                {
                    ResponseWithHeaders <Repositories, ContainerRegistryGetRepositoriesHeaders> response = await _restClient.GetRepositoriesAsync(last : null, n : pageSizeHint, cancellationToken).ConfigureAwait(false);

                    return(Page.FromValues(response.Value.RepositoriesValue, response.Headers.Link, response.GetRawResponse()));
                }
                catch (Exception e)
                {
                    scope.Failed(e);
                    throw;
                }
            }

            async Task <Page <string> > NextPageFunc(string continuationToken, int?pageSizeHint)
            {
                using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ContainerRegistryClient)}.{nameof(GetRepositoryNames)}");
                scope.Start();
                try
                {
                    string uriReference = ParseUriReferenceFromLinkHeader(continuationToken);
                    ResponseWithHeaders <Repositories, ContainerRegistryGetRepositoriesHeaders> response = await _restClient.GetRepositoriesNextPageAsync(uriReference, last : null, n : null, cancellationToken).ConfigureAwait(false);

                    return(Page.FromValues(response.Value.RepositoriesValue, response.Headers.Link, response.GetRawResponse()));
                }
                catch (Exception e)
                {
                    scope.Failed(e);
                    throw;
                }
            }

            return(PageableHelpers.CreateAsyncEnumerable(FirstPageFunc, NextPageFunc));
        }
        /// <summary>
        /// Upload an artifact blob.
        /// </summary>
        /// <param name="stream">The stream containing the blob data.</param>
        /// <param name="cancellationToken"> The cancellation token to use. </param>
        /// <returns></returns>
        public virtual async Task <Response <UploadBlobResult> > UploadBlobAsync(Stream stream, CancellationToken cancellationToken = default)
        {
            Argument.AssertNotNull(stream, nameof(stream));

            using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ContainerRegistryBlobClient)}.{nameof(UploadBlob)}");
            scope.Start();
            try
            {
                string digest = OciBlobDescriptor.ComputeDigest(stream);

                ResponseWithHeaders <ContainerRegistryBlobStartUploadHeaders> startUploadResult =
                    await _blobRestClient.StartUploadAsync(_repositoryName, cancellationToken).ConfigureAwait(false);

                ResponseWithHeaders <ContainerRegistryBlobUploadChunkHeaders> uploadChunkResult =
                    await _blobRestClient.UploadChunkAsync(startUploadResult.Headers.Location, stream, cancellationToken).ConfigureAwait(false);

                ResponseWithHeaders <ContainerRegistryBlobCompleteUploadHeaders> completeUploadResult =
                    await _blobRestClient.CompleteUploadAsync(digest, uploadChunkResult.Headers.Location, null, cancellationToken).ConfigureAwait(false);

                return(Response.FromValue(new UploadBlobResult(completeUploadResult.Headers.DockerContentDigest), completeUploadResult.GetRawResponse()));
            }
            catch (Exception e)
            {
                scope.Failed(e);
                throw;
            }
        }
        /// <summary>
        /// Download a blob that is part of an artifact.
        /// </summary>
        /// <param name="digest">The digest of the blob to download.</param>
        /// <param name="cancellationToken"> The cancellation token to use. </param>
        /// <returns></returns>
        public virtual async Task <Response <DownloadBlobResult> > DownloadBlobAsync(string digest, CancellationToken cancellationToken = default)
        {
            Argument.AssertNotNull(digest, nameof(digest));

            using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ContainerRegistryBlobClient)}.{nameof(DownloadBlob)}");
            scope.Start();
            try
            {
                ResponseWithHeaders <Stream, ContainerRegistryBlobGetBlobHeaders> blobResult = await _blobRestClient.GetBlobAsync(_repositoryName, digest, cancellationToken).ConfigureAwait(false);

                if (!ValidateDigest(blobResult.Value, digest))
                {
                    throw _clientDiagnostics.CreateRequestFailedException(blobResult,
                                                                          new ResponseError(null, "The requested digest does not match the digest of the received manifest."));
                }

                return(Response.FromValue(new DownloadBlobResult(digest, blobResult.Value), blobResult.GetRawResponse()));
            }
            catch (Exception e)
            {
                scope.Failed(e);
                throw;
            }
        }
        /// <summary>
        /// Uploads a manifest for an OCI Artifact.
        /// </summary>
        /// <param name="manifest">The manifest to upload.</param>
        /// <param name="options">Options for configuring the upload operation.</param>
        /// <param name="cancellationToken"> The cancellation token to use. </param>
        /// <returns></returns>
        public virtual Response <UploadManifestResult> UploadManifest(OciManifest manifest, UploadManifestOptions options = default, CancellationToken cancellationToken = default)
        {
            Argument.AssertNotNull(manifest, nameof(manifest));

            options ??= new UploadManifestOptions();

            using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ContainerRegistryBlobClient)}.{nameof(UploadManifest)}");
            scope.Start();
            try
            {
                Stream manifestStream = SerializeManifest(manifest);
                string manifestDigest = OciBlobDescriptor.ComputeDigest(manifestStream);
                string tagOrDigest    = options.Tag ?? manifestDigest;

                ResponseWithHeaders <ContainerRegistryCreateManifestHeaders> response = _restClient.CreateManifest(_repositoryName, tagOrDigest, manifestStream, ManifestMediaType.OciManifest.ToString(), cancellationToken);

                if (!manifestDigest.Equals(response.Headers.DockerContentDigest, StringComparison.Ordinal))
                {
                    throw _clientDiagnostics.CreateRequestFailedException(response,
                                                                          new ResponseError(null, "The digest in the response does not match the digest of the uploaded manifest."));
                }

                return(Response.FromValue(new UploadManifestResult(response.Headers.DockerContentDigest), response.GetRawResponse()));
            }
            catch (Exception e)
            {
                scope.Failed(e);
                throw;
            }
        }
        /// <summary>
        /// Uploads a manifest for an OCI artifact.
        /// </summary>
        /// <param name="manifestStream">The <see cref="Stream"/> manifest to upload.</param>
        /// <param name="options">Options for configuring the upload operation.</param>
        /// <param name="cancellationToken"> The cancellation token to use. </param>
        /// <returns></returns>
        public virtual async Task <Response <UploadManifestResult> > UploadManifestAsync(Stream manifestStream, UploadManifestOptions options = default, CancellationToken cancellationToken = default)
        {
            Argument.AssertNotNull(manifestStream, nameof(manifestStream));

            options ??= new UploadManifestOptions();

            using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ContainerRegistryBlobClient)}.{nameof(UploadManifest)}");
            scope.Start();
            try
            {
                using Stream stream = new MemoryStream();
                await manifestStream.CopyToAsync(stream).ConfigureAwait(false);

                manifestStream.Position = 0;
                stream.Position         = 0;

                string tagOrDigest = options.Tag ?? OciBlobDescriptor.ComputeDigest(manifestStream);
                ResponseWithHeaders <ContainerRegistryCreateManifestHeaders> response = await _restClient.CreateManifestAsync(_repositoryName, tagOrDigest, manifestStream, ManifestMediaType.OciManifest.ToString(), cancellationToken).ConfigureAwait(false);

                if (!ValidateDigest(stream, response.Headers.DockerContentDigest))
                {
                    throw _clientDiagnostics.CreateRequestFailedException(response,
                                                                          new ResponseError(null, "The digest in the response does not match the digest of the uploaded manifest."));
                }

                return(Response.FromValue(new UploadManifestResult(response.Headers.DockerContentDigest), response.GetRawResponse()));
            }
            catch (Exception e)
            {
                scope.Failed(e);
                throw;
            }
        }
        /// <summary>
        /// Get the status results for all submitted translation operations.
        /// </summary>
        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
        public virtual AsyncPageable <TranslationStatusResult> GetTranslationsAsync(CancellationToken cancellationToken = default)
        {
            async Task <Page <TranslationStatusResult> > FirstPageFunc(int?pageSizeHint)
            {
                using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(DocumentTranslationClient)}.{nameof(GetTranslations)}");
                scope.Start();

                try
                {
                    ResponseWithHeaders <TranslationsStatus, DocumentTranslationGetTranslationsStatusHeaders> response = await _serviceRestClient.GetTranslationsStatusAsync(cancellationToken : cancellationToken).ConfigureAwait(false);

                    return(Page.FromValues(response.Value.Value, response.Value.NextLink, response.GetRawResponse()));
                }
                catch (Exception e)
                {
                    scope.Failed(e);
                    throw;
                }
            }

            async Task <Page <TranslationStatusResult> > NextPageFunc(string nextLink, int?pageSizeHint)
            {
                using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(DocumentTranslationClient)}.{nameof(GetTranslations)}");
                scope.Start();

                try
                {
                    ResponseWithHeaders <TranslationsStatus, DocumentTranslationGetTranslationsStatusHeaders> response = await _serviceRestClient.GetTranslationsStatusNextPageAsync(nextLink, cancellationToken : cancellationToken).ConfigureAwait(false);

                    return(Page.FromValues(response.Value.Value, response.Value.NextLink, response.GetRawResponse()));
                }
                catch (Exception e)
                {
                    scope.Failed(e);
                    throw;
                }
            }

            return(PageableHelpers.CreateAsyncEnumerable(FirstPageFunc, NextPageFunc));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Retrieve a token from the STS service for the specified account identifier asynchronously.
        /// </summary>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns><see cref="Response{AccessToken}"/>.</returns>
        public virtual async Task <Response <AccessToken> > GetTokenAsync(CancellationToken cancellationToken = default)
        {
            MixedRealityTokenRequestOptions headerOptions = MixedRealityTokenRequestOptions.GenerateNew();

            using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(MixedRealityStsClient)}.{nameof(GetToken)}");
            scope.AddAttribute(nameof(headerOptions.ClientRequestId), headerOptions.ClientRequestId);
            scope.Start();

            try
            {
                ResponseWithHeaders <StsTokenResponseMessage, MixedRealityStsGetTokenHeaders> response = await _restClient.GetTokenAsync(AccountId, headerOptions, cancellationToken).ConfigureAwait(false);

                return(ResponseWithHeaders.FromValue(response.Value.ToAccessToken(), response.Headers, response.GetRawResponse()));
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
        }
        /// <summary>
        /// Get the status results for all submitted translation operations.
        /// </summary>
        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
        public virtual Pageable <TranslationStatusResult> GetTranslations(CancellationToken cancellationToken = default)
        {
            Page <TranslationStatusResult> FirstPageFunc(int?pageSizeHint)
            {
                using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(DocumentTranslationClient)}.{nameof(GetTranslations)}");
                scope.Start();

                try
                {
                    ResponseWithHeaders <BatchStatusResponse, DocumentTranslationGetOperationsHeaders> response = _serviceRestClient.GetOperations(cancellationToken: cancellationToken);
                    return(Page.FromValues(response.Value.Value, response.Value.NextLink, response.GetRawResponse()));
                }
                catch (Exception e)
                {
                    scope.Failed(e);
                    throw;
                }
            }

            Page <TranslationStatusResult> NextPageFunc(string nextLink, int?pageSizeHint)
            {
                using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(DocumentTranslationClient)}.{nameof(GetTranslations)}");
                scope.Start();

                try
                {
                    Response <BatchStatusResponse> response = _serviceRestClient.GetOperationsNextPage(nextLink, cancellationToken: cancellationToken);
                    return(Page.FromValues(response.Value.Value, response.Value.NextLink, response.GetRawResponse()));
                }
                catch (Exception e)
                {
                    scope.Failed(e);
                    throw;
                }
            }

            return(PageableHelpers.CreateEnumerable(FirstPageFunc, NextPageFunc));
        }
        /// <summary> List repositories. </summary>
        /// <param name="cancellationToken"> The cancellation token to use. </param>
        public virtual Pageable <string> GetRepositories(CancellationToken cancellationToken = default)
        {
            return(PageResponseEnumerator.CreateEnumerable((continuationToken, pageSizeHint) =>
            {
                using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ContainerRegistryClient)}.{nameof(GetRepositories)}");
                scope.Start();
                try
                {
                    ResponseWithHeaders <Repositories, RepositoryGetListHeaders> response =
                        _restClient.GetList(
                            continuationToken,
                            pageSizeHint,
                            cancellationToken);

                    string lastRepository = null;
                    if (!string.IsNullOrEmpty(response.Headers.Link))
                    {
                        Uri nextLink = new Uri(response.Headers.Link);
                        NameValueCollection queryParams = HttpUtility.ParseQueryString(nextLink.Query);
                        lastRepository = queryParams["last"];
                    }

                    return Page <string> .FromValues(response.Value.Names, lastRepository, response.GetRawResponse());
                }
                catch (Exception ex)
                {
                    scope.Failed(ex);
                    throw;
                }
            }));
        }
Exemplo n.º 10
0
        public virtual async Task <Response <DownloadBlobResult> > DownloadBlobAsync(string digest, DownloadBlobOptions options = default, CancellationToken cancellationToken = default)
        {
            options ??= new DownloadBlobOptions();
            ResponseWithHeaders <Stream, ContainerRegistryBlobGetBlobHeaders> blobResult = await _blobRestClient.GetBlobAsync(_repositoryName, digest, cancellationToken).ConfigureAwait(false);

            return(Response.FromValue(new DownloadBlobResult(digest, blobResult.Value), blobResult.GetRawResponse()));
        }