/// <summary>
        /// Prepare and send an HTTP API call to obtain a authenticate a set of credentials with the OpenStack Identity
        /// Service V2.
        /// </summary>
        /// <param name="service">The <see cref="IIdentityService"/> instance.</param>
        /// <param name="request">An <seealso cref="AuthenticationRequest"/> object containing the credentials to
        /// authenticate.</param>
        /// <param name="cancellationToken">The <seealso cref="CancellationToken"/> that the task will observe.</param>
        /// <returns>
        /// A <seealso cref="Task"/> representing the asynchronous operation. When the task completes successfully, the
        /// <see cref="Task{TResult}.Result"/> property will contain an <see cref="Access"/> instance containing the
        /// authentication details.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <para>If <paramref name="service"/> is <see langword="null"/>.</para>
        /// </exception>
        /// <exception cref="HttpWebException">
        /// If an error occurs during an HTTP request as part of preparing or sending the API call.
        /// </exception>
        /// <seealso cref="IIdentityService.PrepareAuthenticateAsync"/>
        /// <seealso href="http://developer.openstack.org/api-ref-identity-v2.html#identity-auth-v2">Tokens (Identity API v2.0 - OpenStack Complete API Reference)</seealso>
        public static Task <Access> AuthenticateAsync(this IIdentityService service, AuthenticationRequest request, CancellationToken cancellationToken)
        {
            if (service == null)
            {
                throw new ArgumentNullException("service");
            }

            return(TaskBlocks.Using(
                       () => service.PrepareAuthenticateAsync(request, cancellationToken),
                       task => task.Result.SendAsync(cancellationToken).Select(innerTask => innerTask.Result.Item2.Access)));
        }
        /// <summary>
        /// Prepare and send an HTTP API call to obtain a list of API versions available at the current endpoint for a
        /// service.
        /// </summary>
        /// <param name="service">The <see cref="IBaseIdentityService"/> instance.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
        /// <returns>
        /// A <seealso cref="Task"/> representing the asynchronous operation. When the task completes successfully, the
        /// <see cref="Task{TResult}.Result"/> property will contain the first page of results describing the API
        /// versions available at the current endpoint.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// if <paramref name="service"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="HttpWebException">
        /// If an error occurred during an HTTP request while preparing or sending the HTTP API call.
        /// </exception>
        /// <seealso cref="IBaseIdentityService.PrepareListApiVersionsAsync"/>
        /// <seealso href="http://developer.openstack.org/api-ref-identity-v2.html#identity-v2-versions">API versions (Identity API v2.0 - OpenStack Complete API Reference)</seealso>
        /// <seealso href="http://developer.openstack.org/api-ref-identity-v3.html#versions-identity-v3">API versions (Identity API v3 - OpenStack Complete API Reference)</seealso>
        public static Task <ReadOnlyCollectionPage <ApiVersion> > ListApiVersionsAsync(this IBaseIdentityService service, CancellationToken cancellationToken)
        {
            if (service == null)
            {
                throw new ArgumentNullException("service");
            }

            return(TaskBlocks.Using(
                       () => service.PrepareListApiVersionsAsync(cancellationToken),
                       task => task.Result.SendAsync(cancellationToken).Select(innerTask => innerTask.Result.Item2)));
        }
Exemple #3
0
        /// <summary>
        /// Gets the next page in the paginated collection.
        /// </summary>
        /// <param name="page">A page in the collection.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
        /// <returns>
        /// <para>A <see cref="Task"/> object representing the asynchronous operation. When the task
        /// completes successfully, the <see cref="Task{TResult}.Result"/> property will contain
        /// a collection containing the next page of results.</para>
        /// </returns>
        /// <exception cref="ArgumentNullException">If <paramref name="page"/> is <see langword="null"/>.</exception>
        /// <exception cref="InvalidOperationException">If <see cref="ReadOnlyCollectionPage{T}.CanHaveNextPage"/> is
        /// <see langword="false"/>.</exception>
        /// <exception cref="WebException">If the HTTP request does not return successfully.</exception>
        public static Task <ReadOnlyCollectionPage <T> > GetNextPageAsync <T>(this ReadOnlyCollectionPage <T> page, CancellationToken cancellationToken)
        {
            if (page == null)
            {
                throw new ArgumentNullException("page");
            }

            return(TaskBlocks.Using(
                       () => page.PrepareGetNextPageAsync(cancellationToken),
                       task => task.Result.SendAsync(cancellationToken).Select(innerTask => innerTask.Result.Item2)));
        }
        public Task <string> GetStringAsync(Uri requestUri)
        {
            Func <Task <HttpResponseMessage> > resource            = () => GetAsync(requestUri, HttpCompletionOption.ResponseContentRead);
            Func <Task <HttpResponseMessage>, Task <string> > body =
                respTask => {
                var resp = respTask.Result;
                resp.EnsureSuccessStatusCode();
                return(resp.Content.ReadAsStringAsync());
            };

            return(TaskBlocks.Using(resource, body));
        }
        /// <summary>
        /// Prepare and send an HTTP API call to obtain information about a particular version of the API available at
        /// the current endpoint for the service.
        /// </summary>
        /// <param name="service">The <see cref="IBaseIdentityService"/> instance.</param>
        /// <param name="apiVersionId">The unique ID of the API version.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
        /// <returns>
        /// A <seealso cref="Task"/> representing the asynchronous operation. When the task completes successfully, the
        /// <see cref="Task{TResult}.Result"/> property will contain an <see cref="ApiVersion"/> instance describing the
        /// specified version of the API.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <para>If <paramref name="service"/> is <see langword="null"/>.</para>
        /// <para>-or-</para>
        /// <para>If <paramref name="apiVersionId"/> is <see langword="null"/>.</para>
        /// </exception>
        /// <exception cref="HttpWebException">
        /// If an error occurred during an HTTP request while preparing or sending the HTTP API call.
        /// </exception>
        /// <seealso cref="BaseIdentityServiceExtensions.GetApiVersionAsync"/>
        /// <seealso href="http://developer.openstack.org/api-ref-identity-v2.html#identity-v2-versions">API versions (Identity API v2.0 - OpenStack Complete API Reference)</seealso>
        /// <seealso href="http://developer.openstack.org/api-ref-identity-v3.html#versions-identity-v3">API versions (Identity API v3 - OpenStack Complete API Reference)</seealso>
        public static Task <ApiVersion> GetApiVersionAsync(this IBaseIdentityService service, ApiVersionId apiVersionId, CancellationToken cancellationToken)
        {
            if (service == null)
            {
                throw new ArgumentNullException("service");
            }
            if (apiVersionId == null)
            {
                throw new ArgumentNullException("apiVersionId");
            }

            return(TaskBlocks.Using(
                       () => service.PrepareGetApiVersionAsync(apiVersionId, cancellationToken),
                       task => task.Result.SendAsync(cancellationToken).Select(innerTask => innerTask.Result.Item2.Version)));
        }
        /// <summary>
        /// Prepare and send an HTTP API call to obtain details for a specific extension available for the current
        /// OpenStack Identity Service V2 endpoint.
        /// </summary>
        /// <param name="service">The <see cref="IIdentityService"/> instance.</param>
        /// <param name="alias">The unique alias identifying the extension.</param>
        /// <param name="cancellationToken">The <seealso cref="CancellationToken"/> that the task will observe.</param>
        /// <returns>
        /// A <seealso cref="Task"/> representing the asynchronous operation. When the task completes successfully, the
        /// <see cref="Task{TResult}.Result"/> property will contain an <see cref="Extension"/> instance describing the
        /// extension.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <para>If <paramref name="service"/> is <see langword="null"/>.</para>
        /// <para>-or-</para>
        /// <para>If <paramref name="alias"/> is <see langword="null"/>.</para>
        /// </exception>
        /// <exception cref="HttpWebException">
        /// If an error occurs during an HTTP request as part of preparing or sending the API call.
        /// </exception>
        /// <seealso cref="IIdentityService.PrepareGetExtensionAsync"/>
        /// <seealso href="http://developer.openstack.org/api-ref-identity-v2.html#identity-api-extensions">Extensions (Identity API v2.0 - OpenStack Complete API Reference)</seealso>
        public static Task <Extension> GetExtensionAsync(this IIdentityService service, ExtensionAlias alias, CancellationToken cancellationToken)
        {
            if (service == null)
            {
                throw new ArgumentNullException("service");
            }
            if (alias == null)
            {
                throw new ArgumentNullException("alias");
            }

            return(TaskBlocks.Using(
                       () => service.PrepareGetExtensionAsync(alias, cancellationToken),
                       task => task.Result.SendAsync(cancellationToken).Select(innerTask => innerTask.Result.Item2.Extension)));
        }
Exemple #7
0
        Task <HttpResponseMessage> SendAsyncWorker(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
        {
            var currentSource = this.cts;
            Func <Task <CancellationTokenSource> > acquireResource = () => Task.FromResult(CancellationTokenSource.CreateLinkedTokenSource(currentSource.Token, cancellationToken));
            Func <Task <CancellationTokenSource>, Task <HttpResponseMessage> > body =
                resourceTask =>
            {
                var lcts = resourceTask.Result;
                lcts.CancelAfter(timeout);

                var task = base.SendAsync(request, lcts.Token);
                if (task == null)
                {
                    throw new InvalidOperationException("Handler failed to return a value");
                }

                return(task.Then(
                           responseTask =>
                {
                    var response = responseTask.Result;
                    if (response == null)
                    {
                        throw new InvalidOperationException("Handler failed to return a response");
                    }

                    //
                    // Read the content when default HttpCompletionOption.ResponseContentRead is set
                    //
                    if (response.Content != null && (completionOption & HttpCompletionOption.ResponseHeadersRead) == 0)
                    {
                        return response.Content.LoadIntoBufferAsync(MaxResponseContentBufferSize)
                        .Select(_ => response);
                    }

                    return Task.FromResult(response);
                })
                       .Finally(_ => GC.KeepAlive(currentSource)));
            };

            return(TaskBlocks.Using(acquireResource, body));
        }
#pragma warning restore 1998

        #region UsingAsyncBuildingBlock
        public Task Using(StringBuilder builder)
        {
            return(TaskBlocks.Using(
                       () => AcquireResourceAsync(builder),
                       task => task.Result.WriteAsync(SampleText)));
        }
        protected internal override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (disposed != 0)
            {
                throw new ObjectDisposedException(GetType().ToString());
            }

            Interlocked.Exchange(ref sentRequest, 1);
            wrequest = CreateWebRequest(request);

            Task intermediate;

            if (request.Content != null)
            {
                AddContentHeaders(wrequest, request.Content.Headers);

                intermediate = wrequest.GetRequestStreamAsync()
                               .Then(streamTask => request.Content.CopyToAsync(streamTask.Result).Finally(_ => streamTask.Result.Dispose()));
            }
            else if (HttpMethod.Post.Equals(request.Method) || HttpMethod.Put.Equals(request.Method) || HttpMethod.Delete.Equals(request.Method))
            {
                // Explicitly set this to make sure we're sending a "Content-Length: 0" header.
                // This fixes the issue that's been reported on the forums:
                // http://forums.xamarin.com/discussion/17770/length-required-error-in-http-post-since-latest-release
                wrequest.ContentLength = 0;
                intermediate           = Task.FromResult(default(VoidResult));
            }
            else
            {
                intermediate = Task.FromResult(default(VoidResult));
            }

            HttpWebResponse            wresponse = null;
            Func <Task <IDisposable> > resource  =
                () => Task.FromResult <IDisposable>(cancellationToken.Register(l => ((HttpWebRequest)l).Abort(), wrequest));
            Func <Task <IDisposable>, Task> body =
                _ =>
            {
                return(wrequest.GetResponseAsync().Select(task => wresponse = (HttpWebResponse)task.Result)
                       .Catch <WebException>(
                           (task, we) =>
                {
                    if (we.Status == WebExceptionStatus.ProtocolError)
                    {
                        // HttpClient shouldn't throw exceptions for these errors
                        wresponse = (HttpWebResponse)we.Response;
                    }
                    else if (we.Status != WebExceptionStatus.RequestCanceled)
                    {
                        // propagate the antecedent
                        return task;
                    }

                    return Task.FromResult(default(VoidResult));
                })
                       .Then(
                           task =>
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return Task.FromCanceled <HttpResponseMessage>(cancellationToken);
                    }
                    else
                    {
                        return Task.FromResult(default(VoidResult));
                    }
                }));
            };

            return(intermediate
                   .Then(_ => TaskBlocks.Using(resource, body))
                   .Select(_ => CreateResponseMessage(wresponse, request, cancellationToken)));
        }
#pragma warning restore 1998

        #region UsingWithResultAsyncBuildingBlock
        public Task <string> UsingWithResult()
        {
            return(TaskBlocks.Using(
                       () => AcquireResourceAsync(),
                       task => task.Result.ReadToEndAsync()));
        }