public void Should_call_onFallback_with_independent_context_for_independent_calls() { Func <Context, CancellationToken, Task <ResultPrimitive> > fallbackAction = (_, __) => Task.FromResult(ResultPrimitive.Substitute); IDictionary <ResultPrimitive, object> contextData = new Dictionary <ResultPrimitive, object>(); Func <DelegateResult <ResultPrimitive>, Context, Task> onFallbackAsync = (dr, ctx) => { contextData[dr.Result] = ctx["key"]; return(TaskHelper.EmptyTask); }; FallbackPolicy <ResultPrimitive> fallbackPolicy = Policy .HandleResult(ResultPrimitive.Fault) .OrResult(ResultPrimitive.FaultAgain) .FallbackAsync(fallbackAction, onFallbackAsync); fallbackPolicy.ExecuteAsync(ctx => { return(Task.FromResult(ResultPrimitive.Fault)); }, new { key = "value1" }.AsDictionary()) .Result .Should().Be(ResultPrimitive.Substitute); fallbackPolicy.ExecuteAsync(ctx => { return(Task.FromResult(ResultPrimitive.FaultAgain)); }, new { key = "value2" }.AsDictionary()) .Result .Should().Be(ResultPrimitive.Substitute); contextData.Count.Should().Be(2); contextData.Keys.Should().Contain(ResultPrimitive.Fault); contextData.Keys.Should().Contain(ResultPrimitive.FaultAgain); contextData[ResultPrimitive.Fault].Should().Be("value1"); contextData[ResultPrimitive.FaultAgain].Should().Be("value2"); }
public async Task Should_not_execute_fallback_when_execute_delegate_does_not_throw() { bool fallbackActionExecuted = false; Func <CancellationToken, Task> fallbackActionAsync = _ => { fallbackActionExecuted = true; return(TaskHelper.EmptyTask); }; FallbackPolicy fallbackPolicy = Policy .Handle <DivideByZeroException>() .FallbackAsync(fallbackActionAsync); await fallbackPolicy.ExecuteAsync(() => TaskHelper.EmptyTask); fallbackActionExecuted.Should().BeFalse(); }
public async Task Should_not_execute_fallback_when_executed_delegate_does_not_raise_fault() { bool fallbackActionExecuted = false; Func <CancellationToken, Task <ResultPrimitive> > fallbackAction = ct => { fallbackActionExecuted = true; return(Task.FromResult(ResultPrimitive.Substitute)); }; FallbackPolicy <ResultPrimitive> fallbackPolicy = Policy .HandleResult(ResultPrimitive.Fault) .FallbackAsync(fallbackAction); await fallbackPolicy.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good)); fallbackActionExecuted.Should().BeFalse(); }
public void HandleTransientHttpError_should_not_handle_HttpStatusCode_BadRequest() { bool policyHandled = false; FallbackPolicy <HttpResponseMessage> policy = HttpPolicyExtensions.HandleTransientHttpError() .FallbackAsync(token => { policyHandled = true; return(Task.FromResult <HttpResponseMessage>(null)); }); policy.ExecuteAsync(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest))); policyHandled.Should().BeFalse(); }
public void OrTransientHttpStatusCode_should_handle_HttpStatusCode_InternalServerError() { bool policyHandled = false; FallbackPolicy <HttpResponseMessage> policy = Policy.Handle <CustomException>().OrTransientHttpStatusCode() .FallbackAsync(token => { policyHandled = true; return(Task.FromResult <HttpResponseMessage>(null)); }); policy.ExecuteAsync(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.InternalServerError))); policyHandled.Should().BeTrue(); }
public void OrTransientHttpError_onGenericPolicyBuilder_should_not_handle_HttpStatusCode_BadRequest() { bool policyHandled = false; FallbackPolicy <HttpResponseMessage> policy = Policy <HttpResponseMessage> .Handle <CustomException>().OrTransientHttpError() .FallbackAsync(token => { policyHandled = true; return(Task.FromResult <HttpResponseMessage>(null)); }); policy.ExecuteAsync(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest))); policyHandled.Should().BeFalse(); }
public async Task Should_not_call_onFallback_when_executed_delegate_does_not_raise_fault() { Func <CancellationToken, Task <ResultPrimitive> > fallbackAction = ct => Task.FromResult(ResultPrimitive.Substitute); bool onFallbackExecuted = false; Func <DelegateResult <ResultPrimitive>, Task> onFallbackAsync = ct => { onFallbackExecuted = true; return(TaskHelper.EmptyTask); }; FallbackPolicy <ResultPrimitive> fallbackPolicy = Policy .HandleResult(ResultPrimitive.Fault) .FallbackAsync(fallbackAction, onFallbackAsync); await fallbackPolicy.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good)); onFallbackExecuted.Should().BeFalse(); }
public void Should_not_call_onFallback_when_execute_delegate_does_not_throw() { Func <CancellationToken, Task> fallbackActionAsync = _ => TaskHelper.EmptyTask; bool onFallbackExecuted = false; Func <Exception, Task> onFallbackAsync = ex => { onFallbackExecuted = true; return(TaskHelper.EmptyTask); }; FallbackPolicy fallbackPolicy = Policy .Handle <DivideByZeroException>() .FallbackAsync(fallbackActionAsync, onFallbackAsync); fallbackPolicy.ExecuteAsync(() => TaskHelper.EmptyTask); onFallbackExecuted.Should().BeFalse(); }
public async Task <IActionResult> Get(int id) { var httpClient = GetHttpClient(); string requestEndpoint = $"inventory/{id}"; var response = await _httpRequestFallbackPolicy.ExecuteAsync( () => _httpRetryPolicy.ExecuteAsync((() => _httpClient.GetAsync(requestEndpoint))) ); if (response.IsSuccessStatusCode) { int itemsInStock = JsonConvert.DeserializeObject <int>(await response.Content.ReadAsStringAsync()); return(Ok(itemsInStock)); } return(StatusCode((int)response.StatusCode, response.Content.ReadAsStringAsync())); }
public async Task Should_not_call_fallbackAction_with_the_fault_if_fault_unhandled() { DelegateResult <ResultPrimitive> fallbackOutcome = null; Func <DelegateResult <ResultPrimitive>, Context, CancellationToken, Task <ResultPrimitive> > fallbackAction = (outcome, ctx, ct) => { fallbackOutcome = outcome; return(Task.FromResult(ResultPrimitive.Substitute)); }; Func <DelegateResult <ResultPrimitive>, Context, Task> onFallback = (ex, ctx) => { return(TaskHelper.EmptyTask); }; FallbackPolicy <ResultPrimitive> fallbackPolicy = Policy <ResultPrimitive> .HandleResult(ResultPrimitive.Fault) .FallbackAsync(fallbackAction, onFallback); var result = await fallbackPolicy.ExecuteAsync(() => { return(Task.FromResult(ResultPrimitive.FaultAgain)); }); result.Should().Be(ResultPrimitive.FaultAgain); fallbackOutcome.Should().BeNull(); }
public async Task Should_call_onFallback_passing_result_triggering_fallback() { bool fallbackActionExecuted = false; Func <CancellationToken, Task <ResultClass> > fallbackAction = ct => { fallbackActionExecuted = true; return(Task.FromResult(new ResultClass(ResultPrimitive.Substitute))); }; ResultClass resultPassedToOnFallback = null; Func <DelegateResult <ResultClass>, Task> onFallbackAsync = r => { resultPassedToOnFallback = r.Result; return(TaskHelper.EmptyTask); }; FallbackPolicy <ResultClass> fallbackPolicy = Policy .HandleResult <ResultClass>(r => r.ResultCode == ResultPrimitive.Fault) .FallbackAsync(fallbackAction, onFallbackAsync); ResultClass resultFromDelegate = new ResultClass(ResultPrimitive.Fault); await fallbackPolicy.ExecuteAsync(() => { return(Task.FromResult(resultFromDelegate)); }); fallbackActionExecuted.Should().BeTrue(); resultPassedToOnFallback.Should().NotBeNull(); resultPassedToOnFallback.Should().Be(resultFromDelegate); }
public async Task Should_call_onFallback_passing_exception_triggering_fallback() { bool fallbackActionExecuted = false; Func <CancellationToken, Task> fallbackActionAsync = _ => { fallbackActionExecuted = true; return(TaskHelper.EmptyTask); }; Exception exceptionPassedToOnFallback = null; Func <Exception, Task> onFallbackAsync = ex => { exceptionPassedToOnFallback = ex; return(TaskHelper.EmptyTask); }; FallbackPolicy fallbackPolicy = Policy .Handle <ArgumentNullException>() .FallbackAsync(fallbackActionAsync, onFallbackAsync); Exception instanceToThrow = new ArgumentNullException("myParam"); await fallbackPolicy.ExecuteAsync(() => { throw instanceToThrow; }); fallbackActionExecuted.Should().BeTrue(); exceptionPassedToOnFallback.Should().BeOfType <ArgumentNullException>(); exceptionPassedToOnFallback.Should().Be(instanceToThrow); }
public void Should_call_fallbackAction_with_the_passed_context() { IDictionary <string, object> contextData = null; Func <Context, CancellationToken, Task <ResultPrimitive> > fallbackActionAsync = (ctx, ct) => { contextData = ctx; return(Task.FromResult(ResultPrimitive.Substitute)); }; Func <DelegateResult <ResultPrimitive>, Context, Task> onFallbackAsync = (dr, ctx) => TaskHelper.EmptyTask; FallbackPolicy <ResultPrimitive> fallbackPolicy = Policy .HandleResult(ResultPrimitive.Fault) .FallbackAsync(fallbackActionAsync, onFallbackAsync); fallbackPolicy.ExecuteAsync(ctx => { return(Task.FromResult(ResultPrimitive.Fault)); }, new { key1 = "value1", key2 = "value2" }.AsDictionary()) .Result .Should().Be(ResultPrimitive.Substitute); contextData.Should() .ContainKeys("key1", "key2").And .ContainValues("value1", "value2"); }
public async Task <IActionResult> Get(int id) { var httpClient = _httpClientFactory.CreateClient("InventoryClient"); string requestEndpoint = $"timeout/inventory/{id}"; HttpResponseMessage response = await _httpRequestFallbackPolicy.ExecuteAsync(() => _httpRetryPolicy.ExecuteAsync(() => _timeoutPolicy.ExecuteAsync( async token => await httpClient.GetAsync(requestEndpoint, token), CancellationToken.None))); if (response.IsSuccessStatusCode) { int itemsInStock = JsonConvert.DeserializeObject <int>(await response.Content.ReadAsStringAsync()); return(Ok(itemsInStock)); } if (response.Content != null) { return(StatusCode((int)response.StatusCode, response.Content.ReadAsStringAsync())); } return(StatusCode((int)response.StatusCode)); }