예제 #1
0
        public async Task <TResponse> Handle <TResponse>(PEXARequestBase request, WCAUser user, CancellationToken cancellationToken)
            where TResponse : class
        {
            var pexaApiToken = await _mediator.Send(new PexaApiTokenQuery()
            {
                AuthenticatedUser = user
            });

            if (pexaApiToken != null)
            {
                _telemetryLogger.TrackTrace("Retrieved PEXA API token from credentials store", WCASeverityLevel.Verbose,
                                            new Dictionary <string, string> {
                    { "accessToken", pexaApiToken.AccessToken },
                    { "accessTokenExpiryUtc", pexaApiToken.AccessTokenExpiryUtc.ToString() },
                });
            }

            if (pexaApiTokenIsValid(pexaApiToken))
            {
                try
                {
                    request.BearerToken = pexaApiToken.AccessToken;
                    return(await Handle <TResponse>(request, cancellationToken));
                }
                catch (PEXAException ex)
                {
                    if (pexaApiToken.IsFromCache && (ex.StatusCode == StatusCodes.Status401Unauthorized || ex.StatusCode == StatusCodes.Status403Forbidden))
                    {
                        var pexaTokenFromVault = await _mediator.Send(new PexaApiTokenQuery()
                        {
                            AuthenticatedUser = user, BypassAndUpdateCache = true
                        });

                        if (pexaTokenFromVault.AccessToken != pexaApiToken.AccessToken && pexaApiTokenIsValid(pexaTokenFromVault))
                        {
                            // Access token from vault is different to the cached version, so try with that token before failing
                            request.BearerToken = pexaTokenFromVault.AccessToken;

                            return(await Handle <TResponse>(request, cancellationToken));
                        }

                        throw new MissingOrInvalidPexaApiTokenException(user);
                    }
                    else if (ex.StatusCode == StatusCodes.Status400BadRequest)
                    {
                        throw new PexaBadRequestResponseException("Encountered an error during PEXA request", ex);
                    }
                    else
                    {
                        throw new PexaUnexpectedErrorResponseException("Encountered unexpected error during PEXA request", ex);
                    }
                }
            }

            throw new MissingOrInvalidPexaApiTokenException(user);
        }
예제 #2
0
        private async Task <HttpResponseMessage> SendApiRequest(PEXARequestBase pexaRequest, CancellationToken cancellationToken)
        {
            if (pexaRequest is null)
            {
                throw new ArgumentNullException(nameof(pexaRequest));
            }

            if (string.IsNullOrEmpty(pexaRequest.BearerToken))
            {
                throw new ArgumentException(nameof(pexaRequest.BearerToken));
            }

            var urlBuilder = new System.Text.StringBuilder();

            switch (PEXAEnvironment)
            {
            case PEXAEnvironment.Test:
                urlBuilder.Append(_testApiUrlBase);
                break;

            case PEXAEnvironment.Production:
                urlBuilder.Append(_prodApiUrlBase);
                break;

            default:
                throw new InvalidDataException("Unknown PEXAEnvironment.");
            }

            urlBuilder.Append(pexaRequest.Path);

            var client_ = _httpClient;

            using (var httpRequest = new HttpRequestMessage())
            {
                httpRequest.Content = pexaRequest.Content;
                httpRequest.Method  = pexaRequest.HttpMethod;
                httpRequest.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/xml"));
                httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", pexaRequest.BearerToken);

                // TODO: Determine if this needs to be implemented
                // PrepareRequest(client_, request_, urlBuilder_);

                var url_ = urlBuilder.ToString();
                httpRequest.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);

                // TODO: Determine if this needs to be implemented
                // PrepareRequest(client_, request_, url_);

                return(await client_.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(true));
            }
        }
예제 #3
0
        public async Task <TResponse> Handle <TResponse>(PEXARequestBase request, CancellationToken cancellationToken)
            where TResponse : class
        {
            if (request is null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            var response = await SendApiRequest(request, cancellationToken);

            try
            {
                var headers = System.Linq.Enumerable.ToDictionary(response.Headers, h_ => h_.Key, h_ => h_.Value);
                if (response.Content != null && response.Content.Headers != null)
                {
                    foreach (var item_ in response.Content.Headers)
                    {
                        headers[item_.Key] = item_.Value;
                    }
                }

                var status_ = ((int)response.StatusCode).ToString(CultureInfo.InvariantCulture);
                if (status_ == "200" || status_ == "206")
                {
                    if (response.Content == null)
                    {
                        return(null);
                    }

                    var workspaceCreationResponseSerializer = new XmlSerializer(typeof(TResponse));
                    using (var contentStream = await response.Content.ReadAsStreamAsync())
                        using (var xmlReader = XmlReader.Create(contentStream))
                        {
                            return((TResponse)workspaceCreationResponseSerializer.Deserialize(xmlReader));
                        }
                }
                else if (status_ == "400")
                {
                    if (response.Content == null)
                    {
                        throw new PEXAException();
                    }

                    using (var contentStream = await response.Content.ReadAsStreamAsync())
                        using (var xmlReader = XmlReader.Create(contentStream))
                        {
                            ExceptionResponse exceptionResponse;
                            if (request.Version == 1)
                            {
                                var exceptionResponseSerializerv1 = new XmlSerializer(typeof(ExceptionResponsev1));
                                exceptionResponse = (ExceptionResponse)exceptionResponseSerializerv1.Deserialize(xmlReader);
                            }
                            else
                            {
                                var exceptionResponseSerializerv2 = new XmlSerializer(typeof(ExceptionResponsev2));
                                exceptionResponse = (ExceptionResponse)exceptionResponseSerializerv2.Deserialize(xmlReader);
                            }

                            if (xmlReader != null)
                            {
                                xmlReader.Dispose();
                            }

                            throw new PEXAException(exceptionResponse);
                        }
                }
                else if (status_ == "401")
                {
                    var responseData_ = response.Content == null ? null : await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                    throw new PEXAException("Unauthenticated", (int)response.StatusCode, responseData_, headers, null);
                }
                else if (status_ == "403")
                {
                    var responseData_ = response.Content == null ? null : await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                    throw new PEXAException("Forbidden", (int)response.StatusCode, responseData_, headers, null);
                }
                else if (status_ != "200" && status_ != "204")
                {
                    var responseData_ = response.Content == null ? null : await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                    throw new PEXAException("The HTTP status code of the response was not expected (" + (int)response.StatusCode + ").", (int)response.StatusCode, responseData_, headers, null);
                }

                return(null);
            }
            finally
            {
                if (response != null)
                {
                    response.Dispose();
                }
            }
        }
예제 #4
0
 private async Task <TResponse> Handle <TResponse>(PEXARequestBase request, CancellationToken cancellationToken)
     where TResponse : class
 {
     return(await _pEXAService.Handle <TResponse>(request, cancellationToken));
 }