Added UI alert and circuit-breaker handlers for components that depend on Basket.api
This commit is contained in:
		
							parent
							
								
									f39fdb92ca
								
							
						
					
					
						commit
						d42033a83b
					
				@ -81,6 +81,14 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
 | 
			
		||||
 | 
			
		||||
                var response = await _client.SendAsync(requestMessage);
 | 
			
		||||
 | 
			
		||||
                // raise exception if HttpResponseCode 500 
 | 
			
		||||
                // needed for circuit breaker to track fails
 | 
			
		||||
 | 
			
		||||
                if (response.StatusCode == HttpStatusCode.InternalServerError)
 | 
			
		||||
                {
 | 
			
		||||
                    throw new HttpRequestException();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return await response.Content.ReadAsStringAsync();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -15,8 +15,6 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
 | 
			
		||||
                .UseFailing(options =>
 | 
			
		||||
                {
 | 
			
		||||
                    options.ConfigPath = "/Failing";                   
 | 
			
		||||
                    options.EndpointPaths = new List<string>()
 | 
			
		||||
                    { "/api/v1/basket/checkout", "/hc" };
 | 
			
		||||
                })
 | 
			
		||||
                .UseHealthChecks("/hc")
 | 
			
		||||
                .UseContentRoot(Directory.GetCurrentDirectory())
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ using Microsoft.eShopOnContainers.WebMVC.Services;
 | 
			
		||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
 | 
			
		||||
using Microsoft.AspNetCore.Authorization;
 | 
			
		||||
using Microsoft.AspNetCore.Authentication;
 | 
			
		||||
using Polly.CircuitBreaker;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
 | 
			
		||||
{
 | 
			
		||||
@ -25,17 +26,28 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<IActionResult> Index()
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var user = _appUserParser.Parse(HttpContext.User);
 | 
			
		||||
                var vm = await _basketSvc.GetBasket(user);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                return View(vm);
 | 
			
		||||
            }
 | 
			
		||||
            catch (BrokenCircuitException)
 | 
			
		||||
            {
 | 
			
		||||
                // Catch error when Basket.api is in circuit-opened mode                 
 | 
			
		||||
                HandleBrokenCircuitException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return View();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        public async Task<IActionResult> Index(Dictionary<string, int> quantities, string action)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var user = _appUserParser.Parse(HttpContext.User);
 | 
			
		||||
                var basket = await _basketSvc.SetQuantities(user, quantities);
 | 
			
		||||
@ -46,11 +58,19 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
 | 
			
		||||
                    var order = _basketSvc.MapBasketToOrder(basket);
 | 
			
		||||
                    return RedirectToAction("Create", "Order");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (BrokenCircuitException)
 | 
			
		||||
            {
 | 
			
		||||
                // Catch error when Basket.api is in circuit-opened mode                 
 | 
			
		||||
                HandleBrokenCircuitException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return View(vm);
 | 
			
		||||
            return View();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<IActionResult> AddToCart(CatalogItem productDetails)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                if (productDetails.Id != null)
 | 
			
		||||
                {
 | 
			
		||||
@ -68,5 +88,18 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
 | 
			
		||||
                }
 | 
			
		||||
                return RedirectToAction("Index", "Catalog");            
 | 
			
		||||
            }
 | 
			
		||||
            catch (BrokenCircuitException)
 | 
			
		||||
            {
 | 
			
		||||
                // Catch error when Basket.api is in circuit-opened mode                 
 | 
			
		||||
                HandleBrokenCircuitException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return RedirectToAction("Index", "Catalog");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void HandleBrokenCircuitException()
 | 
			
		||||
        {
 | 
			
		||||
            TempData["BasketInoperativeMsg"] = "Basket Service is inoperative, please try later on. (Business Msg Due to Circuit-Breaker)";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -41,6 +41,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
 | 
			
		||||
        public void ConfigureServices(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddMvc();            
 | 
			
		||||
            services.AddSession();
 | 
			
		||||
 | 
			
		||||
            if (Configuration.GetValue<string>("IsClusterEnv") == bool.TrueString)
 | 
			
		||||
            {
 | 
			
		||||
@ -104,6 +105,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
 | 
			
		||||
                app.UseExceptionHandler("/Catalog/Error");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            app.UseSession();
 | 
			
		||||
            app.UseStaticFiles();
 | 
			
		||||
 | 
			
		||||
            app.UseCookieAuthentication(new CookieAuthenticationOptions
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.ViewComponents
 | 
			
		||||
            {
 | 
			
		||||
                // Catch error when Basket.api is in circuit-opened mode                 
 | 
			
		||||
                ViewBag.IsBasketInoperative = true;
 | 
			
		||||
                vm.ItemsCount = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return View(vm);
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Polly.CircuitBreaker;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewComponents
 | 
			
		||||
{
 | 
			
		||||
@ -16,8 +17,19 @@ namespace Microsoft.eShopOnContainers.WebMVC.ViewComponents
 | 
			
		||||
 | 
			
		||||
        public async Task<IViewComponentResult> InvokeAsync(ApplicationUser user)
 | 
			
		||||
        {
 | 
			
		||||
            var item = await GetItemsAsync(user);
 | 
			
		||||
            return View(item);
 | 
			
		||||
            var vm = new Basket();
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                vm = await GetItemsAsync(user);
 | 
			
		||||
                return View(vm);
 | 
			
		||||
            }
 | 
			
		||||
            catch (BrokenCircuitException)
 | 
			
		||||
            {               
 | 
			
		||||
                // Catch error when Basket.api is in circuit-opened mode                 
 | 
			
		||||
                TempData["BasketInoperativeMsg"] = "Basket Service is inoperative, please try later on. (Business Msg Due to Circuit-Breaker)";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return View(vm);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        private Task<Basket> GetItemsAsync(ApplicationUser user) => _cartSvc.GetBasket(user);
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,15 @@
 | 
			
		||||
</section>
 | 
			
		||||
 | 
			
		||||
<div class="container">
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <br />
 | 
			
		||||
        @if(TempData.ContainsKey("BasketInoperativeMsg"))
 | 
			
		||||
        {
 | 
			
		||||
            <div class="alert alert-warning" role="alert">
 | 
			
		||||
                 @TempData["BasketInoperativeMsg"]
 | 
			
		||||
            </div>
 | 
			
		||||
        }
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    @if (Model.CatalogItems.Count() > 0)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -8,17 +8,20 @@
 | 
			
		||||
   asp-area="" 
 | 
			
		||||
   asp-controller="Cart" 
 | 
			
		||||
   asp-action="Index">    
 | 
			
		||||
    <div class="esh-basketstatus-image">
 | 
			
		||||
        <img src="~/images/cart.png" />
 | 
			
		||||
    </div>
 | 
			
		||||
    @if (ViewBag.IsBasketInoperative == true)
 | 
			
		||||
    {
 | 
			
		||||
        <div class="esh-basketstatus-image">
 | 
			
		||||
            <img src="~/images/cart-inoperative.png" />            
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="esh-basketstatus-badge-inoperative">
 | 
			
		||||
            @Model.ItemsCount
 | 
			
		||||
            X           
 | 
			
		||||
        </div>        
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        <div class="esh-basketstatus-image">
 | 
			
		||||
            <img src="~/images/cart.png" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="esh-basketstatus-badge">
 | 
			
		||||
            @Model.ItemsCount
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,24 @@
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<div class="container">
 | 
			
		||||
    @if (TempData.ContainsKey("BasketInoperativeMsg"))
 | 
			
		||||
    {
 | 
			
		||||
        <br />
 | 
			
		||||
        <div class="alert alert-warning" role="alert">
 | 
			
		||||
             @TempData["BasketInoperativeMsg"]
 | 
			
		||||
        </div>
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        <article class="esh-basket-titles row">
 | 
			
		||||
            <br />
 | 
			
		||||
            @if (TempData.ContainsKey("BasketInoperativeMsg"))
 | 
			
		||||
            {
 | 
			
		||||
                <div class="alert alert-warning" role="alert">
 | 
			
		||||
                     @TempData["BasketInoperativeMsg"]
 | 
			
		||||
                </div>
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            <section class="esh-basket-title col-xs-3">Product</section>
 | 
			
		||||
            <section class="esh-basket-title col-xs-3 hidden-lg-down"></section>
 | 
			
		||||
            <section class="esh-basket-title col-xs-2">Price</section>
 | 
			
		||||
@ -41,12 +58,10 @@
 | 
			
		||||
                    <div class="alert alert-warning esh-basket-margin12" role="alert"> Note that the price of this article changed in our Catalog. The old price when you originally added it to the basket was $ @item.OldUnitPrice </div>
 | 
			
		||||
                }
 | 
			
		||||
            </div>
 | 
			
		||||
        <br/>
 | 
			
		||||
        
 | 
			
		||||
            <br />
 | 
			
		||||
        }
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<div class="container">
 | 
			
		||||
        <div class="container">
 | 
			
		||||
            <article class="esh-basket-titles esh-basket-titles--clean row">
 | 
			
		||||
                <section class="esh-basket-title col-xs-10"></section>
 | 
			
		||||
                <section class="esh-basket-title col-xs-2">Total</section>
 | 
			
		||||
@ -68,4 +83,9 @@
 | 
			
		||||
                           value="[ Checkout ]" name="action" />
 | 
			
		||||
                </section>
 | 
			
		||||
            </article>
 | 
			
		||||
        </div>
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
@ -41,6 +41,7 @@
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.2" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.2" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.Session" Version="1.1.2" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.2" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.2" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.2" />
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/Web/WebMVC/wwwroot/images/cart-inoperative.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/Web/WebMVC/wwwroot/images/cart-inoperative.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 948 B  | 
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user