Example #1
0
 /// <summary>
 /// An extenstion method on HttpClient that sends a request to <c>client</c>, using
 /// the request type (Get, Put, Post) specified by <c>invocation</c>.
 /// </summary>
 /// <param name="client">The target client.</param>
 /// <param name="invocation">A delegate that issues the required request type.</param>
 /// <param name="requestUrn">The URN representing the request.</param>
 /// <returns>The client's response  as a <see cref="HttpResponseMessage"/>.</returns>
 ///
 public static Task <HttpResponseMessage> Invoke(this HttpClient client,
                                                 HttpClientHelpers.EndPointInvocation invocation,
                                                 string requestUrn,
                                                 StringContent content = null)
 {
     return(invocation(client, requestUrn, content));
 }
Example #2
0
        /// <summary>
        /// Makes a call to the specified endpoint of Accounts API, using the specified Invocation (Get, Put or Post).
        /// Content can be passed for Put and Post as <see cref="StringContent"/>.
        /// </summary>
        /// <param name="httpClient">The HttpClient instance serving as <c>this</c>.</param>
        /// <param name="invocation">A delegate that will pass the </param>
        /// <param name="requestUrn">The URN to be appended to the Accounts API URL in order to
        /// obtain the full request URL.</param>
        /// <param name="content">The content, if any.  Only used if <c>invocation</c> is
        /// <see cref="HttpClientHelpers.Put"/> or <see cref="HttpClientHelpers.Post"/></param>
        /// <returns>An object representing the response by the Accounts API.</returns>
        /// <example>
        /// var response = InvokeManagementApi(Put, "accounts/credit/1234?sum=100");
        ///
        /// Where "1234" is an account number and "100" is the sum to be credited to that account.
        /// </example>
        public static async Task <HttpResponseMessage> InvokeApiAsync(this HttpClient httpClient,
                                                                      HttpClientHelpers.EndPointInvocation invocation,
                                                                      string requestUrn,
                                                                      StringContent content = null)
        {
            var response = await httpClient.Invoke(invocation, requestUrn, content);

            return(response);
        }
Example #3
0
        /// <summary>
        /// Makes a call to the specified endpoint of Accounts API, using the specified Invocation (Get, Put or Post).
        /// This call only supports requests that can be fully encoded in the URL.
        /// </summary>
        /// <param name="invocation">A delegate that will pass the </param>
        /// <param name="requestUrn">The URN to be appended to the Accounts API URL in order to
        /// obtain the full request URL.</param>
        /// <returns>An object representing the response by the Accounts API.</returns>
        /// <example>
        /// var response = await InvokeApiAsync(Put, "accounts/credit/1234?sum=100");
        ///
        /// Where "1234" is an account number and "100" is the sum to be credited to that account.
        /// </example>
        private async Task <HttpResponseMessage> InvokeApiAsync(HttpClientHelpers.EndPointInvocation invocation, string requestUrn)
        {
            HttpResponseMessage response;

            var accessToken = TokenManager.GetAccessTokens().AccessToken;

            using (var apiClient = new AccountsApiClient(_accountsApiUrl, accessToken))
            {
                response = await apiClient.Invoke(invocation, requestUrn);
            }

            return(response);
        }
Example #4
0
        /// <summary>
        /// Submits a request URL to the Accounts API. Contains the retry logic required in order to
        /// deal with expired Access/Refresh Tokens.
        /// </summary>
        /// <param name="invocation">The calling method (Get, Put, or Post).</param>
        /// <param name="requestUrn">The request to be submitted to the Accounts API.
        /// See: <see cref="InvokeApiAsync(HttpClientHelpers.EndPointInvocation,string)"/>
        /// </param>
        /// <param name="userCredentialsCallback">
        /// A delegate that can be invoked to obtain username/password credentials from the user.
        /// </param>
        /// <returns>The response from the Accounts API.</returns>
        ///
        private async Task <HttpResponseMessage> InvokeApiAsync(HttpClientHelpers.EndPointInvocation invocation,
                                                                string requestUrn,
                                                                UserCredentialsCallback userCredentialsCallback)
        {
            // ReSharper disable once NotAccessedVariable
            AccessTokenPair accessTokens;

            //--------------------------------------------------------------------------------------------
            // Have we been authenticated?  Check the Token Manager for an Access Token. If we don't have
            // one, go get one.
            //--------------------------------------------------------------------------------------------

            // ReSharper disable once RedundantAssignment
            if ((accessTokens = TokenManager.GetAccessTokens()).IsNull())
            {
                var(username, password) = await userCredentialsCallback();

                await GetAndStoreApiAccessTokens(username, password);
            }

            // TODO handle failure

            //--------------------------------------------------------------------------------------------
            // We have an Access Token; issue the request to the Accounts API.
            //--------------------------------------------------------------------------------------------

            var response = await InvokeApiAsync(invocation, requestUrn);

            //--------------------------------------------------------------------------------------------
            // Did the request fail?
            //--------------------------------------------------------------------------------------------

            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.StatusCode);

                //------------------------------------------------------------------------------------------
                // Failed. Was it because our access token timed out?
                //------------------------------------------------------------------------------------------

                if (response.IsAccessTokenExpired())
                {
                    //----------------------------------------------------------------------------------------
                    // Yes. Use our refresh token to get a new access token.
                    //----------------------------------------------------------------------------------------

                    // ReSharper disable once NotAccessedVariable
                    var accessToken = await GetAndStoreApiAccessTokens();

                    //----------------------------------------------------------------------------------------
                    // Re-submit the original request with the new access token.
                    //----------------------------------------------------------------------------------------

                    response = await InvokeApiAsync(invocation, requestUrn);

                    //----------------------------------------------------------------------------------------
                    // Is the Accounts API still reporting an expired token?
                    //----------------------------------------------------------------------------------------

                    if (response.IsAccessTokenExpired())
                    {
                        //--------------------------------------------------------------------------------------
                        // Yes. Apparently, our refresh token has expired too. At this point we must ask the
                        // user to re-authenticate with their username/password. Use the caller-provided
                        // callback to obtain them.
                        //--------------------------------------------------------------------------------------

                        var(username, password) = await userCredentialsCallback();

                        //--------------------------------------------------------------------------------------
                        // Try to get a new access token one more time, using the user's credentials.
                        //--------------------------------------------------------------------------------------

                        // ReSharper disable once RedundantAssignment
                        accessToken = await GetAndStoreApiAccessTokens(username, password);

                        //--------------------------------------------------------------------------------------
                        // Either that worked, or it didn't. Either way, we're done here.  Return the final
                        // response to the caller.
                        //--------------------------------------------------------------------------------------

                        response = await InvokeApiAsync(invocation, requestUrn);
                    }
                }
            }

            return(response);
        }