public async Task <IActionResult> RegisterUser([FromBody] UserInfo userInfo) { HttpResponseMessage response; PolicyDefinitions polly = new PolicyDefinitions(); var sqlBreakerPolicy = polly.sqlCircuitBreakerPolicy(); try { if (ModelState.IsValid) { //try //{ // await sqlBreakerPolicy.ExecuteAsync(async () => // { _db.UserInfo.Add(userInfo); await _db.SaveChangesAsync(); // }); //} //catch (Exception ex) //{ // _logger.LogError(ex.ToString()); // return BadRequest(ex.ToString()); //} } try { response = await _notificationClient.SendNotification(userInfo.EmailAddress); } catch (Exception ex) { _logger.LogError(ex.ToString()); return(BadRequest(ex.ToString())); } if (response.IsSuccessStatusCode) { string confirmation = await response.Content.ReadAsStringAsync(); if (confirmation.Contains("http://notification")) { return(BadRequest("Docker Service is down")); } return(Ok(confirmation)); } } catch (Exception ex) { if (ex.ToString().Contains("The circuit is now open")) { //Return default value on exception. _logger.LogError(ex.ToString()); return(BadRequest("Circuit Breaker Policy Invoke to Open State.")); } else if (ex.ToString().Contains("Polly.Bulkhead.BulkheadRejectedException")) { _logger.LogError(ex.ToString()); return(BadRequest("Bulkhead Isolation Policy Invoked.")); } else { _logger.LogError(ex.ToString()); return(BadRequest(ex.ToString())); } } _logger.LogError("Unknown Exception Occurred."); return(BadRequest("Unknown Exception Occurred.")); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.Configure <IISOptions>(options => { options.AutomaticAuthentication = false; }); //Register Repository BL service services.AddScoped <IUserBL, UserBL>(); //Add Entity Framework services.AddDbContext <GabDbContext>(options => { options.UseSqlServer(Configuration.GetConnectionString("RegistrationDB"), sqlServerOptionsAction: sqlOptions => { sqlOptions.EnableRetryOnFailure( maxRetryCount: 3, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); }); }); // Add Cors services.AddCors(o => o.AddPolicy("CorsPolicy", builder => { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); })); //Add Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "Registration API", Version = "v1" }); }); //Define Polly Policies inline right now - Refactor after POC to put into Policy Registry Class Library. Create methods where settings such as Timeout, Exponential Retry & Circuit Breaker Sync and Advanced Sync settings can be configurable. PolicyDefinitions policyHelper = new PolicyDefinitions(); var registry = services.AddPolicyRegistry(); registry.Add("timeoutPolicy", policyHelper.timeOutPolicy(30)); registry.Add("fallbackPolicy", policyHelper.fallBackPolicy("Circuit Breaker Invoked")); registry.Add("retryPolicy", policyHelper.waitAndRetry()); registry.Add("bulkheadPolicy", policyHelper.bulkHeadIsolation(80, 2)); registry.Add("circuitBreakerPolicy", policyHelper.circuitBreakerPolicy(3, 15)); //Typed Singleton HttpClient Handler and Apply Polly Policies - Switched to Typed Client for the POC services.AddHttpClient <INotificationClient, NotificationClient>() .AddPolicyHandlerFromRegistry("bulkheadPolicy") .AddPolicyHandlerFromRegistry("timeoutPolicy") .AddPolicyHandlerFromRegistry("fallbackPolicy") .AddPolicyHandlerFromRegistry("retryPolicy") .AddPolicyHandlerFromRegistry("circuitBreakerPolicy"); //Configure Health Check API - Heartbeat Probe on service dependencies services.AddHealthChecks() .AddApplicationInsightsPublisher() .AddDbContextCheck <GabDbContext>("SQL DB") .AddUrlGroup(new Uri("http://notification"), "NOTIFICATION API"); services.AddApplicationInsightsTelemetry(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }