private void ValidateOperation(BarionOperation operation) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } if (operation.RelativeUri == null) { throw new ArgumentNullException(nameof(operation.RelativeUri)); } if (operation.RelativeUri.IsAbsoluteUri) { throw new ArgumentException("operation.RelativeUri should be a relative Uri.", nameof(operation.RelativeUri)); } if (operation.ResultType == null) { throw new ArgumentNullException(nameof(operation.ResultType)); } if (!operation.ResultType.GetTypeInfo().IsSubclassOf(typeof(BarionOperationResult))) { throw new ArgumentException("ResultType should be a subclass of BarionOperationResult.", nameof(operation.ResultType)); } if (operation.Method == null) { throw new ArgumentNullException(nameof(operation.Method)); } }
/// <summary> /// Executes a Barion operation. /// </summary> /// <param name="operation">The Barion operation to execute.</param> /// <param name="cancellationToken">The cancellation token to cancel operation.</param> /// <returns>Returns System.Threading.Tasks.Task`1.The task object representing the asynchronous operation.</returns> public async Task <BarionOperationResult> ExecuteAsync(BarionOperation operation, CancellationToken cancellationToken) { CheckDisposed(); ValidateOperation(operation); operation.POSKey = _settings.POSKey; return(await SendWithRetry(operation, cancellationToken)); }
/// <summary> /// Executes a Barion operation. /// </summary> /// <typeparam name="TResult">The type of the result of the Barion operation.</typeparam> /// <param name="operation">The Barion operation to execute.</param> /// <param name="cancellationToken">The cancellation token to cancel operation.</param> /// <returns>Returns System.Threading.Tasks.Task`1.The task object representing the asynchronous operation.</returns> public async Task <TResult> ExecuteAsync <TResult>(BarionOperation operation, CancellationToken cancellationToken) where TResult : BarionOperationResult { if (typeof(TResult) != operation.ResultType) { throw new InvalidOperationException("TResult should be equal to the ResultType of the operation."); } return(await ExecuteAsync(operation, cancellationToken) as TResult); }
private async Task <BarionOperationResult> SendWithRetry(BarionOperation operation, CancellationToken cancellationToken) { var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); SetTimeout(linkedCts); var shouldRetry = false; uint currentRetryCount = 0; TimeSpan retryInterval = TimeSpan.Zero; BarionOperationResult result = null; do { var message = PrepareHttpRequestMessage(operation); try { var responseMessage = await _httpClient.SendAsync(message, linkedCts.Token); result = await CreateResultFromResponseMessage(responseMessage, operation); if (!result.IsOperationSuccessful) { shouldRetry = _retryPolicy.CreateInstance().ShouldRetry(currentRetryCount, responseMessage.StatusCode, out retryInterval); } } catch (Exception ex) { shouldRetry = _retryPolicy.CreateInstance().ShouldRetry(currentRetryCount, ex, out retryInterval); if (!shouldRetry) { throw; } } if (shouldRetry) { await Task.Delay(retryInterval); currentRetryCount++; } } while (shouldRetry && !linkedCts.IsCancellationRequested); return(result); }
private HttpRequestMessage PrepareHttpRequestMessage(BarionOperation operation) { var message = new HttpRequestMessage(operation.Method, new Uri(_settings.BaseUrl, operation.RelativeUri)); if (operation.Method == HttpMethod.Post || operation.Method == HttpMethod.Put) { var body = JsonConvert.SerializeObject(operation, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Converters = new List <JsonConverter> { new StringEnumConverter(), new CultureInfoJsonConverter() } }); message.Content = new StringContent(body, Encoding.UTF8, "application/json"); } return(message); }
private async Task <BarionOperationResult> CreateResultFromResponseMessage(HttpResponseMessage responseMessage, BarionOperation operation) { var response = await responseMessage.Content.ReadAsStringAsync(); var operationResult = (BarionOperationResult)JsonConvert.DeserializeObject(response, operation.ResultType, new JsonSerializerSettings { Converters = new List <JsonConverter> { new StringEnumConverter { AllowIntegerValues = false }, new CultureInfoJsonConverter() } }); if (operationResult == null) { return(CreateFailedOperationResult(operation.ResultType, "Deserialized result was null")); } if (!responseMessage.IsSuccessStatusCode && operationResult.Errors == null) { return(CreateFailedOperationResult(operation.ResultType, responseMessage.StatusCode.ToString(), responseMessage.ReasonPhrase, response)); } operationResult.IsOperationSuccessful = responseMessage.IsSuccessStatusCode && (operationResult.Errors == null || !operationResult.Errors.Any()); return(operationResult); }
/// <summary> /// Executes a Barion operation. /// </summary> /// <param name="operation">The Barion operation to execute.</param> /// <returns>Returns System.Threading.Tasks.Task`1.The task object representing the asynchronous operation.</returns> public async Task <BarionOperationResult> ExecuteAsync(BarionOperation operation) { return(await ExecuteAsync(operation, default(CancellationToken))); }