commit
						06e641a97f
					
				@ -10,7 +10,6 @@ namespace OcelotApiGw
 | 
			
		||||
{
 | 
			
		||||
    public class Startup
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        private readonly IConfiguration _cfg;
 | 
			
		||||
 | 
			
		||||
        public Startup(IConfiguration configuration)
 | 
			
		||||
@ -65,6 +64,7 @@ namespace OcelotApiGw
 | 
			
		||||
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 | 
			
		||||
        {
 | 
			
		||||
            var pathBase = _cfg["PATH_BASE"];
 | 
			
		||||
 | 
			
		||||
            if (!string.IsNullOrEmpty(pathBase))
 | 
			
		||||
            {
 | 
			
		||||
                app.UsePathBase(pathBase);
 | 
			
		||||
 | 
			
		||||
@ -5,16 +5,19 @@ using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
 | 
			
		||||
{
 | 
			
		||||
    [Route("api/v1/[controller]")]
 | 
			
		||||
    [Authorize]
 | 
			
		||||
    public class BasketController : Controller
 | 
			
		||||
    [ApiController]
 | 
			
		||||
    public class BasketController : ControllerBase
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ICatalogService _catalog;
 | 
			
		||||
        private readonly IBasketService _basket;
 | 
			
		||||
 | 
			
		||||
        public BasketController(ICatalogService catalogService, IBasketService basketService)
 | 
			
		||||
        {
 | 
			
		||||
            _catalog = catalogService;
 | 
			
		||||
@ -23,22 +26,24 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
 | 
			
		||||
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [HttpPut]
 | 
			
		||||
        public async Task<IActionResult> UpdateAllBasket([FromBody] UpdateBasketRequest data)
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<ActionResult<BasketData>> UpdateAllBasketAsync([FromBody] UpdateBasketRequest data)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            if (data.Items == null || !data.Items.Any())
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest("Need to pass at least one basket line");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Retrieve the current basket
 | 
			
		||||
            var currentBasket = await _basket.GetById(data.BuyerId);
 | 
			
		||||
            var currentBasket = await _basket.GetByIdAsync(data.BuyerId);
 | 
			
		||||
 | 
			
		||||
            if (currentBasket == null)
 | 
			
		||||
            {
 | 
			
		||||
                currentBasket = new BasketData(data.BuyerId);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var catalogItems = await _catalog.GetCatalogItems(data.Items.Select(x => x.ProductId));
 | 
			
		||||
            var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId));
 | 
			
		||||
            var newBasket = new BasketData(data.BuyerId);
 | 
			
		||||
 | 
			
		||||
            foreach (var bitem in data.Items)
 | 
			
		||||
@ -60,13 +65,16 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await _basket.Update(newBasket);
 | 
			
		||||
            return Ok(newBasket);
 | 
			
		||||
            await _basket.UpdateAsync(newBasket);
 | 
			
		||||
 | 
			
		||||
            return newBasket;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpPut]
 | 
			
		||||
        [Route("items")]
 | 
			
		||||
        public async Task<IActionResult> UpdateQuantities([FromBody] UpdateBasketItemsRequest data)
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<ActionResult<BasketData>> UpdateQuantitiesAsync([FromBody] UpdateBasketItemsRequest data)
 | 
			
		||||
        {
 | 
			
		||||
            if (!data.Updates.Any())
 | 
			
		||||
            {
 | 
			
		||||
@ -74,7 +82,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Retrieve the current basket
 | 
			
		||||
            var currentBasket = await _basket.GetById(data.BasketId);
 | 
			
		||||
            var currentBasket = await _basket.GetByIdAsync(data.BasketId);
 | 
			
		||||
            if (currentBasket == null)
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest($"Basket with id {data.BasketId} not found.");
 | 
			
		||||
@ -84,21 +92,26 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
 | 
			
		||||
            foreach (var update in data.Updates)
 | 
			
		||||
            {
 | 
			
		||||
                var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId);
 | 
			
		||||
 | 
			
		||||
                if (basketItem == null)
 | 
			
		||||
                {
 | 
			
		||||
                    return BadRequest($"Basket item with id {update.BasketItemId} not found");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                basketItem.Quantity = update.NewQty;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Save the updated basket
 | 
			
		||||
            await _basket.Update(currentBasket);
 | 
			
		||||
            return Ok(currentBasket);
 | 
			
		||||
            await _basket.UpdateAsync(currentBasket);
 | 
			
		||||
 | 
			
		||||
            return currentBasket;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("items")]
 | 
			
		||||
        public async Task<IActionResult> AddBasketItem([FromBody] AddBasketItemRequest data)
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<ActionResult> AddBasketItemAsync([FromBody] AddBasketItemRequest data)
 | 
			
		||||
        {
 | 
			
		||||
            if (data == null || data.Quantity == 0)
 | 
			
		||||
            {
 | 
			
		||||
@ -106,12 +119,12 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Step 1: Get the item from catalog
 | 
			
		||||
            var item = await _catalog.GetCatalogItem(data.CatalogItemId);
 | 
			
		||||
            var item = await _catalog.GetCatalogItemAsync(data.CatalogItemId);
 | 
			
		||||
 | 
			
		||||
            //item.PictureUri = 
 | 
			
		||||
 | 
			
		||||
            // Step 2: Get current basket status
 | 
			
		||||
            var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId);
 | 
			
		||||
            var currentBasket = (await _basket.GetByIdAsync(data.BasketId)) ?? new BasketData(data.BasketId);
 | 
			
		||||
            // Step 3: Merge current status with new product
 | 
			
		||||
            currentBasket.Items.Add(new BasketDataItem()
 | 
			
		||||
            {
 | 
			
		||||
@ -124,8 +137,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Step 4: Update basket
 | 
			
		||||
            await _basket.Update(currentBasket);
 | 
			
		||||
 | 
			
		||||
            await _basket.UpdateAsync(currentBasket);
 | 
			
		||||
 | 
			
		||||
            return Ok();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -1,19 +1,20 @@
 | 
			
		||||
using Microsoft.AspNetCore.Authorization;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
 | 
			
		||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
 | 
			
		||||
{
 | 
			
		||||
    [Route("api/v1/[controller]")]
 | 
			
		||||
    [Authorize]
 | 
			
		||||
    public class OrderController : Controller
 | 
			
		||||
    [ApiController]
 | 
			
		||||
    public class OrderController : ControllerBase
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IBasketService _basketService;
 | 
			
		||||
        private readonly IOrderApiClient _orderClient;
 | 
			
		||||
 | 
			
		||||
        public OrderController(IBasketService basketService, IOrderApiClient orderClient)
 | 
			
		||||
        {
 | 
			
		||||
            _basketService = basketService;
 | 
			
		||||
@ -22,21 +23,23 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
 | 
			
		||||
 | 
			
		||||
        [Route("draft/{basketId}")]
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        public async Task<IActionResult> GetOrderDraft(string basketId)
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType(typeof(OrderData), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<ActionResult<OrderData>> GetOrderDraftAsync(string basketId)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(basketId))
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest("Need a valid basketid");
 | 
			
		||||
            }
 | 
			
		||||
            // Get the basket data and build a order draft based on it
 | 
			
		||||
            var basket = await _basketService.GetById(basketId);
 | 
			
		||||
            var basket = await _basketService.GetByIdAsync(basketId);
 | 
			
		||||
 | 
			
		||||
            if (basket == null)
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest($"No basket found for id {basketId}");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var orderDraft = await _orderClient.GetOrderDraftFromBasket(basket);
 | 
			
		||||
            return Ok(orderDraft);
 | 
			
		||||
            return await _orderClient.GetOrderDraftFromBasketAsync(basket);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
 | 
			
		||||
            _urls = config.Value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<BasketData> GetById(string id)
 | 
			
		||||
        public async Task<BasketData> GetByIdAsync(string id)
 | 
			
		||||
        {
 | 
			
		||||
            var data = await _httpClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id));
 | 
			
		||||
 | 
			
		||||
@ -31,7 +31,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
 | 
			
		||||
            return basket;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task Update(BasketData currentBasket)
 | 
			
		||||
        public async Task UpdateAsync(BasketData currentBasket)
 | 
			
		||||
        {
 | 
			
		||||
            var basketContent = new StringContent(JsonConvert.SerializeObject(currentBasket), System.Text.Encoding.UTF8, "application/json");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
 | 
			
		||||
            _urls = config.Value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<CatalogItem> GetCatalogItem(int id)
 | 
			
		||||
        public async Task<CatalogItem> GetCatalogItemAsync(int id)
 | 
			
		||||
        {
 | 
			
		||||
            var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id));
 | 
			
		||||
            var catalogItem = JsonConvert.DeserializeObject<CatalogItem>(stringContent);
 | 
			
		||||
@ -30,7 +30,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
 | 
			
		||||
            return catalogItem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<IEnumerable<CatalogItem>> GetCatalogItems(IEnumerable<int> ids)
 | 
			
		||||
        public async Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids)
 | 
			
		||||
        {
 | 
			
		||||
            var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids));
 | 
			
		||||
            var catalogItems = JsonConvert.DeserializeObject<CatalogItem[]>(stringContent);
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,13 @@
 | 
			
		||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
 | 
			
		||||
{
 | 
			
		||||
    public interface IBasketService
 | 
			
		||||
    {
 | 
			
		||||
        Task<BasketData> GetById(string id);
 | 
			
		||||
        Task Update(BasketData currentBasket);
 | 
			
		||||
        Task<BasketData> GetByIdAsync(string id);
 | 
			
		||||
 | 
			
		||||
        Task UpdateAsync(BasketData currentBasket);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,13 @@
 | 
			
		||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
 | 
			
		||||
{
 | 
			
		||||
    public interface ICatalogService
 | 
			
		||||
    {
 | 
			
		||||
        Task<CatalogItem> GetCatalogItem(int id);
 | 
			
		||||
        Task<IEnumerable<CatalogItem>> GetCatalogItems(IEnumerable<int> ids);
 | 
			
		||||
        Task<CatalogItem> GetCatalogItemAsync(int id);
 | 
			
		||||
 | 
			
		||||
        Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,10 @@
 | 
			
		||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
 | 
			
		||||
{
 | 
			
		||||
    public interface IOrderApiClient
 | 
			
		||||
    {
 | 
			
		||||
        Task<OrderData> GetOrderDraftFromBasket(BasketData basket);
 | 
			
		||||
        Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
 | 
			
		||||
            _urls = config.Value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<OrderData> GetOrderDraftFromBasket(BasketData basket)
 | 
			
		||||
        public async Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket)
 | 
			
		||||
        {
 | 
			
		||||
            var uri = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft();
 | 
			
		||||
            var content = new StringContent(JsonConvert.SerializeObject(basket), System.Text.Encoding.UTF8, "application/json");
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
 | 
			
		||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters;
 | 
			
		||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure;
 | 
			
		||||
@ -53,9 +54,14 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
 | 
			
		||||
            {
 | 
			
		||||
                app.UseDeveloperExceptionPage();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
 | 
			
		||||
                app.UseHsts();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            app.UseAuthentication();
 | 
			
		||||
 | 
			
		||||
            app.UseHttpsRedirection();
 | 
			
		||||
            app.UseMvc();
 | 
			
		||||
 | 
			
		||||
            app.UseSwagger().UseSwaggerUI(c =>
 | 
			
		||||
@ -77,7 +83,8 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
 | 
			
		||||
            services.AddOptions();
 | 
			
		||||
            services.Configure<UrlsConfig>(configuration.GetSection("urls"));
 | 
			
		||||
 | 
			
		||||
            services.AddMvc();
 | 
			
		||||
            services.AddMvc()
 | 
			
		||||
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
 | 
			
		||||
 | 
			
		||||
            services.AddSwaggerGen(options =>
 | 
			
		||||
            {
 | 
			
		||||
@ -120,12 +127,14 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
 | 
			
		||||
        {
 | 
			
		||||
            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
 | 
			
		||||
            var identityUrl = configuration.GetValue<string>("urls:identity");
 | 
			
		||||
 | 
			
		||||
            services.AddAuthentication(options =>
 | 
			
		||||
            {
 | 
			
		||||
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
 | 
			
		||||
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
 | 
			
		||||
 | 
			
		||||
            }).AddJwtBearer(options =>
 | 
			
		||||
            })
 | 
			
		||||
            .AddJwtBearer(options =>
 | 
			
		||||
            {
 | 
			
		||||
                options.Authority = identityUrl;
 | 
			
		||||
                options.RequireHttpsMetadata = false;
 | 
			
		||||
@ -143,6 +152,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
 | 
			
		||||
 | 
			
		||||
            return services;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IServiceCollection AddHttpServices(this IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            //register delegating handlers
 | 
			
		||||
@ -163,8 +173,6 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
 | 
			
		||||
                   .AddPolicyHandler(GetRetryPolicy())
 | 
			
		||||
                   .AddPolicyHandler(GetCircuitBreakerPolicy());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            return services;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -174,7 +182,6 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
 | 
			
		||||
              .HandleTransientHttpError()
 | 
			
		||||
              .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
 | 
			
		||||
              .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
 | 
			
		||||
 | 
			
		||||
@ -5,16 +5,19 @@ using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
 | 
			
		||||
{
 | 
			
		||||
    [Route("api/v1/[controller]")]
 | 
			
		||||
    [Authorize]
 | 
			
		||||
    public class BasketController : Controller
 | 
			
		||||
    [ApiController]
 | 
			
		||||
    public class BasketController : ControllerBase
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ICatalogService _catalog;
 | 
			
		||||
        private readonly IBasketService _basket;
 | 
			
		||||
 | 
			
		||||
        public BasketController(ICatalogService catalogService, IBasketService basketService)
 | 
			
		||||
        {
 | 
			
		||||
            _catalog = catalogService;
 | 
			
		||||
@ -23,22 +26,23 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
 | 
			
		||||
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [HttpPut]
 | 
			
		||||
        public async Task<IActionResult> UpdateAllBasket([FromBody] UpdateBasketRequest data)
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<ActionResult<BasketData>> UpdateAllBasketAsync([FromBody] UpdateBasketRequest data)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            if (data.Items == null || !data.Items.Any())
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest("Need to pass at least one basket line");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Retrieve the current basket
 | 
			
		||||
            var currentBasket = await _basket.GetById(data.BuyerId);
 | 
			
		||||
            var currentBasket = await _basket.GetByIdAsync(data.BuyerId);
 | 
			
		||||
            if (currentBasket == null)
 | 
			
		||||
            {
 | 
			
		||||
                currentBasket = new BasketData(data.BuyerId);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var catalogItems = await _catalog.GetCatalogItems(data.Items.Select(x => x.ProductId));
 | 
			
		||||
            var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId));
 | 
			
		||||
            var newBasket = new BasketData(data.BuyerId);
 | 
			
		||||
 | 
			
		||||
            foreach (var bitem in data.Items)
 | 
			
		||||
@ -60,13 +64,16 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await _basket.Update(newBasket);
 | 
			
		||||
            return Ok(newBasket);
 | 
			
		||||
            await _basket.UpdateAsync(newBasket);
 | 
			
		||||
 | 
			
		||||
            return newBasket;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpPut]
 | 
			
		||||
        [Route("items")]
 | 
			
		||||
        public async Task<IActionResult> UpdateQuantities([FromBody] UpdateBasketItemsRequest data)
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<ActionResult<BasketData>> UpdateQuantitiesAsync([FromBody] UpdateBasketItemsRequest data)
 | 
			
		||||
        {
 | 
			
		||||
            if (!data.Updates.Any())
 | 
			
		||||
            {
 | 
			
		||||
@ -74,7 +81,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Retrieve the current basket
 | 
			
		||||
            var currentBasket = await _basket.GetById(data.BasketId);
 | 
			
		||||
            var currentBasket = await _basket.GetByIdAsync(data.BasketId);
 | 
			
		||||
            if (currentBasket == null)
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest($"Basket with id {data.BasketId} not found.");
 | 
			
		||||
@ -92,13 +99,16 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Save the updated basket
 | 
			
		||||
            await _basket.Update(currentBasket);
 | 
			
		||||
            return Ok(currentBasket);
 | 
			
		||||
            await _basket.UpdateAsync(currentBasket);
 | 
			
		||||
 | 
			
		||||
            return currentBasket;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("items")]
 | 
			
		||||
        public async Task<IActionResult> AddBasketItem([FromBody] AddBasketItemRequest data)
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<ActionResult> AddBasketItemAsync([FromBody] AddBasketItemRequest data)
 | 
			
		||||
        {
 | 
			
		||||
            if (data == null || data.Quantity == 0)
 | 
			
		||||
            {
 | 
			
		||||
@ -106,12 +116,12 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Step 1: Get the item from catalog
 | 
			
		||||
            var item = await _catalog.GetCatalogItem(data.CatalogItemId);
 | 
			
		||||
            var item = await _catalog.GetCatalogItemAsync(data.CatalogItemId);
 | 
			
		||||
 | 
			
		||||
            //item.PictureUri = 
 | 
			
		||||
 | 
			
		||||
            // Step 2: Get current basket status
 | 
			
		||||
            var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId);
 | 
			
		||||
            var currentBasket = (await _basket.GetByIdAsync(data.BasketId)) ?? new BasketData(data.BasketId);
 | 
			
		||||
            // Step 3: Merge current status with new product
 | 
			
		||||
            currentBasket.Items.Add(new BasketDataItem()
 | 
			
		||||
            {
 | 
			
		||||
@ -124,8 +134,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Step 4: Update basket
 | 
			
		||||
            await _basket.Update(currentBasket);
 | 
			
		||||
 | 
			
		||||
            await _basket.UpdateAsync(currentBasket);
 | 
			
		||||
 | 
			
		||||
            return Ok();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,19 @@
 | 
			
		||||
using Microsoft.AspNetCore.Authorization;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
 | 
			
		||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
 | 
			
		||||
{
 | 
			
		||||
    [Route("api/v1/[controller]")]
 | 
			
		||||
    [Authorize]
 | 
			
		||||
    public class OrderController : Controller
 | 
			
		||||
    [ApiController]
 | 
			
		||||
    public class OrderController : ControllerBase
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IBasketService _basketService;
 | 
			
		||||
        private readonly IOrderApiClient _orderClient;
 | 
			
		||||
@ -22,21 +25,23 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
 | 
			
		||||
 | 
			
		||||
        [Route("draft/{basketId}")]
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        public async Task<IActionResult> GetOrderDraft(string basketId)
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType(typeof(OrderData), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<ActionResult<OrderData>> GetOrderDraftAsync(string basketId)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(basketId))
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest("Need a valid basketid");
 | 
			
		||||
            }
 | 
			
		||||
            // Get the basket data and build a order draft based on it
 | 
			
		||||
            var basket = await _basketService.GetById(basketId);
 | 
			
		||||
            var basket = await _basketService.GetByIdAsync(basketId);
 | 
			
		||||
 | 
			
		||||
            if (basket == null)
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest($"No basket found for id {basketId}");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var orderDraft = await _orderClient.GetOrderDraftFromBasket(basket);
 | 
			
		||||
            return Ok(orderDraft);
 | 
			
		||||
            return await _orderClient.GetOrderDraftFromBasketAsync(basket);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,6 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
 | 
			
		||||
{
 | 
			
		||||
    public class BasketService : IBasketService
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        private readonly HttpClient _apiClient;
 | 
			
		||||
        private readonly ILogger<BasketService> _logger;
 | 
			
		||||
        private readonly UrlsConfig _urls;
 | 
			
		||||
@ -22,18 +21,19 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
 | 
			
		||||
            _urls = config.Value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<BasketData> GetById(string id)
 | 
			
		||||
        public async Task<BasketData> GetByIdAsync(string id)
 | 
			
		||||
        {
 | 
			
		||||
            var data = await _apiClient.GetStringAsync(_urls.Basket +  UrlsConfig.BasketOperations.GetItemById(id));
 | 
			
		||||
            var basket = !string.IsNullOrEmpty(data) ? JsonConvert.DeserializeObject<BasketData>(data) : null;
 | 
			
		||||
 | 
			
		||||
            return basket;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task Update(BasketData currentBasket)
 | 
			
		||||
        public async Task UpdateAsync(BasketData currentBasket)
 | 
			
		||||
        {
 | 
			
		||||
            var basketContent = new StringContent(JsonConvert.SerializeObject(currentBasket), System.Text.Encoding.UTF8, "application/json");
 | 
			
		||||
 | 
			
		||||
            var data = await _apiClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), basketContent);
 | 
			
		||||
            await _apiClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), basketContent);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,6 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
 | 
			
		||||
{
 | 
			
		||||
    public class CatalogService : ICatalogService
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        private readonly HttpClient _httpClient;
 | 
			
		||||
        private readonly ILogger<CatalogService> _logger;
 | 
			
		||||
        private readonly UrlsConfig _urls;
 | 
			
		||||
@ -23,20 +22,18 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
 | 
			
		||||
            _urls = config.Value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<CatalogItem> GetCatalogItem(int id)
 | 
			
		||||
        public async Task<CatalogItem> GetCatalogItemAsync(int id)
 | 
			
		||||
        {
 | 
			
		||||
            var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id));
 | 
			
		||||
            var catalogItem = JsonConvert.DeserializeObject<CatalogItem>(stringContent);
 | 
			
		||||
 | 
			
		||||
            return catalogItem;
 | 
			
		||||
            return JsonConvert.DeserializeObject<CatalogItem>(stringContent);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<IEnumerable<CatalogItem>> GetCatalogItems(IEnumerable<int> ids)
 | 
			
		||||
        public async Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids)
 | 
			
		||||
        {
 | 
			
		||||
            var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemsById(ids));
 | 
			
		||||
            var catalogItems = JsonConvert.DeserializeObject<CatalogItem[]>(stringContent);
 | 
			
		||||
 | 
			
		||||
            return catalogItems;
 | 
			
		||||
            return JsonConvert.DeserializeObject<CatalogItem[]>(stringContent);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,12 @@
 | 
			
		||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
 | 
			
		||||
{
 | 
			
		||||
    public interface IBasketService
 | 
			
		||||
    {
 | 
			
		||||
        Task<BasketData> GetById(string id);
 | 
			
		||||
        Task Update(BasketData currentBasket);
 | 
			
		||||
        Task<BasketData> GetByIdAsync(string id);
 | 
			
		||||
 | 
			
		||||
        Task UpdateAsync(BasketData currentBasket);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,13 @@
 | 
			
		||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
 | 
			
		||||
{
 | 
			
		||||
    public interface ICatalogService
 | 
			
		||||
    {
 | 
			
		||||
        Task<CatalogItem> GetCatalogItem(int id);
 | 
			
		||||
        Task<IEnumerable<CatalogItem>> GetCatalogItems(IEnumerable<int> ids);
 | 
			
		||||
        Task<CatalogItem> GetCatalogItemAsync(int id);
 | 
			
		||||
 | 
			
		||||
        Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,10 @@
 | 
			
		||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
 | 
			
		||||
{
 | 
			
		||||
    public interface IOrderApiClient
 | 
			
		||||
    {
 | 
			
		||||
        Task<OrderData> GetOrderDraftFromBasket(BasketData basket);
 | 
			
		||||
        Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,6 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
 | 
			
		||||
{
 | 
			
		||||
    public class OrderApiClient : IOrderApiClient
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        private readonly HttpClient _apiClient;
 | 
			
		||||
        private readonly ILogger<OrderApiClient> _logger;
 | 
			
		||||
        private readonly UrlsConfig _urls;
 | 
			
		||||
@ -22,7 +21,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
 | 
			
		||||
            _urls = config.Value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<OrderData> GetOrderDraftFromBasket(BasketData basket)
 | 
			
		||||
        public async Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket)
 | 
			
		||||
        {
 | 
			
		||||
            var url = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft();
 | 
			
		||||
            var content = new StringContent(JsonConvert.SerializeObject(basket), System.Text.Encoding.UTF8, "application/json");
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
 | 
			
		||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters;
 | 
			
		||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure;
 | 
			
		||||
@ -53,18 +54,22 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator
 | 
			
		||||
            {
 | 
			
		||||
                app.UseDeveloperExceptionPage();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
 | 
			
		||||
                app.UseHsts();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            app.UseAuthentication();
 | 
			
		||||
 | 
			
		||||
            app.UseHttpsRedirection();
 | 
			
		||||
            app.UseMvc();
 | 
			
		||||
 | 
			
		||||
            app.UseSwagger().UseSwaggerUI(c =>
 | 
			
		||||
           {
 | 
			
		||||
               c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1");
 | 
			
		||||
               //c.ConfigureOAuth2("Microsoft.eShopOnContainers.Web.Shopping.HttpAggregatorwaggerui", "", "", "Purchase BFF Swagger UI");
 | 
			
		||||
           });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            app.UseSwagger()
 | 
			
		||||
                .UseSwaggerUI(c =>
 | 
			
		||||
                {
 | 
			
		||||
                    c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1");
 | 
			
		||||
                    //c.ConfigureOAuth2("Microsoft.eShopOnContainers.Web.Shopping.HttpAggregatorwaggerui", "", "", "Purchase BFF Swagger UI");
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -99,12 +104,14 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator
 | 
			
		||||
 | 
			
		||||
            return services;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddOptions();
 | 
			
		||||
            services.Configure<UrlsConfig>(configuration.GetSection("urls"));
 | 
			
		||||
 | 
			
		||||
            services.AddMvc();
 | 
			
		||||
            services.AddMvc()
 | 
			
		||||
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
 | 
			
		||||
 | 
			
		||||
            services.AddSwaggerGen(options =>
 | 
			
		||||
            {
 | 
			
		||||
@ -177,6 +184,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator
 | 
			
		||||
              .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
 | 
			
		||||
        {
 | 
			
		||||
            return HttpPolicyExtensions
 | 
			
		||||
 | 
			
		||||
@ -13,54 +13,44 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
 | 
			
		||||
{
 | 
			
		||||
    [Route("api/v1/[controller]")]
 | 
			
		||||
    [Authorize]
 | 
			
		||||
    public class BasketController : Controller
 | 
			
		||||
    [ApiController]
 | 
			
		||||
    public class BasketController : ControllerBase
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IBasketRepository _repository;
 | 
			
		||||
        private readonly IIdentityService _identitySvc;
 | 
			
		||||
        private readonly IIdentityService _identityService;
 | 
			
		||||
        private readonly IEventBus _eventBus;
 | 
			
		||||
 | 
			
		||||
        public BasketController(IBasketRepository repository,
 | 
			
		||||
            IIdentityService identityService,
 | 
			
		||||
            IEventBus eventBus)
 | 
			
		||||
        public BasketController(IBasketRepository repository, IIdentityService identityService, IEventBus eventBus)
 | 
			
		||||
        {
 | 
			
		||||
            _repository = repository;
 | 
			
		||||
            _identitySvc = identityService;
 | 
			
		||||
            _identityService = identityService;
 | 
			
		||||
            _eventBus = eventBus;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // GET /id
 | 
			
		||||
        [HttpGet("{id}")]
 | 
			
		||||
        [ProducesResponseType(typeof(CustomerBasket), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> Get(string id)
 | 
			
		||||
        public async Task<ActionResult<CustomerBasket>> GetBasketByIdAsync(string id)
 | 
			
		||||
        {
 | 
			
		||||
            var basket = await _repository.GetBasketAsync(id);
 | 
			
		||||
            if (basket == null)
 | 
			
		||||
            {
 | 
			
		||||
                return Ok(new CustomerBasket(id) { });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok(basket);
 | 
			
		||||
            return basket ?? new CustomerBasket(id);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // POST /value
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [ProducesResponseType(typeof(CustomerBasket), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> Post([FromBody]CustomerBasket value)
 | 
			
		||||
        public async Task<ActionResult<CustomerBasket>> UpdateBasketAsync([FromBody]CustomerBasket value)
 | 
			
		||||
        {
 | 
			
		||||
            var basket = await _repository.UpdateBasketAsync(value);
 | 
			
		||||
 | 
			
		||||
            return Ok(basket);
 | 
			
		||||
            return await _repository.UpdateBasketAsync(value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Route("checkout")]
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.Accepted)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        public async Task<IActionResult> Checkout([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId)
 | 
			
		||||
        public async Task<ActionResult> CheckoutAsync([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId)
 | 
			
		||||
        {
 | 
			
		||||
            var userId = _identitySvc.GetUserIdentity();
 | 
			
		||||
            var userId = _identityService.GetUserIdentity();
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            basketCheckout.RequestId = (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) ?
 | 
			
		||||
                guid : basketCheckout.RequestId;
 | 
			
		||||
 | 
			
		||||
@ -80,17 +70,17 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
 | 
			
		||||
            // Once basket is checkout, sends an integration event to
 | 
			
		||||
            // ordering.api to convert basket to order and proceeds with
 | 
			
		||||
            // order creation process
 | 
			
		||||
            _eventBus.Publish(eventMessage);            
 | 
			
		||||
            _eventBus.Publish(eventMessage);
 | 
			
		||||
 | 
			
		||||
            return Accepted();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // DELETE api/values/5
 | 
			
		||||
        [HttpDelete("{id}")]
 | 
			
		||||
        public void Delete(string id)
 | 
			
		||||
        [ProducesResponseType(typeof(void), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task DeleteBasketByIdAsync(string id)
 | 
			
		||||
        {
 | 
			
		||||
            _repository.DeleteBasketAsync(id);
 | 
			
		||||
            await _repository.DeleteBasketAsync(id);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,6 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Model
 | 
			
		||||
    public class RedisBasketRepository : IBasketRepository
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ILogger<RedisBasketRepository> _logger;
 | 
			
		||||
 | 
			
		||||
        private readonly ConnectionMultiplexer _redis;
 | 
			
		||||
        private readonly IDatabase _database;
 | 
			
		||||
 | 
			
		||||
@ -30,12 +29,14 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Model
 | 
			
		||||
        {
 | 
			
		||||
            var server = GetServer();          
 | 
			
		||||
            var data = server.Keys();
 | 
			
		||||
 | 
			
		||||
            return data?.Select(k => k.ToString());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<CustomerBasket> GetBasketAsync(string customerId)
 | 
			
		||||
        {
 | 
			
		||||
            var data = await _database.StringGetAsync(customerId);
 | 
			
		||||
 | 
			
		||||
            if (data.IsNullOrEmpty)
 | 
			
		||||
            {
 | 
			
		||||
                return null;
 | 
			
		||||
@ -47,6 +48,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Model
 | 
			
		||||
        public async Task<CustomerBasket> UpdateBasketAsync(CustomerBasket basket)
 | 
			
		||||
        {
 | 
			
		||||
            var created = await _database.StringSetAsync(basket.BuyerId, JsonConvert.SerializeObject(basket));
 | 
			
		||||
 | 
			
		||||
            if (!created)
 | 
			
		||||
            {
 | 
			
		||||
                _logger.LogInformation("Problem occur persisting the item.");
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.Azure.ServiceBus;
 | 
			
		||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
 | 
			
		||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
 | 
			
		||||
@ -51,11 +52,13 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
 | 
			
		||||
 | 
			
		||||
            // Add framework services.
 | 
			
		||||
            services.AddMvc(options =>
 | 
			
		||||
            {
 | 
			
		||||
                options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
			
		||||
                options.Filters.Add(typeof(ValidateModelStateFilter));
 | 
			
		||||
                {
 | 
			
		||||
                    options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
			
		||||
                    options.Filters.Add(typeof(ValidateModelStateFilter));
 | 
			
		||||
 | 
			
		||||
            }).AddControllersAsServices();
 | 
			
		||||
                })
 | 
			
		||||
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
 | 
			
		||||
                .AddControllersAsServices();
 | 
			
		||||
 | 
			
		||||
            ConfigureAuthService(services);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -44,10 +44,10 @@ namespace UnitTest.Basket.Application
 | 
			
		||||
            //Act
 | 
			
		||||
            var basketController = new BasketController(
 | 
			
		||||
                _basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
 | 
			
		||||
            var actionResult = await basketController.Get(fakeCustomerId) as OkObjectResult;
 | 
			
		||||
            var actionResult = await basketController.GetBasketByIdAsync(fakeCustomerId);
 | 
			
		||||
 | 
			
		||||
            //Assert
 | 
			
		||||
            Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
 | 
			
		||||
            Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK);
 | 
			
		||||
            Assert.Equal(((CustomerBasket)actionResult.Value).BuyerId, fakeCustomerId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -67,10 +67,10 @@ namespace UnitTest.Basket.Application
 | 
			
		||||
            var basketController = new BasketController(
 | 
			
		||||
                _basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
 | 
			
		||||
 | 
			
		||||
            var actionResult = await basketController.Post(fakeCustomerBasket) as OkObjectResult;
 | 
			
		||||
            var actionResult = await basketController.UpdateBasketAsync(fakeCustomerBasket);
 | 
			
		||||
 | 
			
		||||
            //Assert
 | 
			
		||||
            Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
 | 
			
		||||
            Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK);
 | 
			
		||||
            Assert.Equal(((CustomerBasket)actionResult.Value).BuyerId, fakeCustomerId);
 | 
			
		||||
        }        
 | 
			
		||||
 | 
			
		||||
@ -86,7 +86,7 @@ namespace UnitTest.Basket.Application
 | 
			
		||||
            var basketController = new BasketController(
 | 
			
		||||
                _basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
 | 
			
		||||
 | 
			
		||||
            var result = await basketController.Checkout(new BasketCheckout(), Guid.NewGuid().ToString()) as BadRequestResult;
 | 
			
		||||
            var result = await basketController.CheckoutAsync(new BasketCheckout(), Guid.NewGuid().ToString()) as BadRequestResult;
 | 
			
		||||
            Assert.NotNull(result);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -114,7 +114,7 @@ namespace UnitTest.Basket.Application
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            //Act
 | 
			
		||||
            var result = await basketController.Checkout(new BasketCheckout(), Guid.NewGuid().ToString()) as AcceptedResult;
 | 
			
		||||
            var result = await basketController.CheckoutAsync(new BasketCheckout(), Guid.NewGuid().ToString()) as AcceptedResult;
 | 
			
		||||
 | 
			
		||||
            _serviceBusMock.Verify(mock => mock.Publish(It.IsAny<UserCheckoutAcceptedIntegrationEvent>()), Times.Once);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
            _catalogIntegrationEventService = catalogIntegrationEventService ?? throw new ArgumentNullException(nameof(catalogIntegrationEventService));
 | 
			
		||||
            _settings = settings.Value;
 | 
			
		||||
 | 
			
		||||
            ((DbContext)context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
 | 
			
		||||
            context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // GET api/v1/[controller]/items[?pageSize=3&pageIndex=10]
 | 
			
		||||
@ -36,11 +36,19 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
        [Route("items")]
 | 
			
		||||
        [ProducesResponseType(typeof(PaginatedItemsViewModel<CatalogItem>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        [ProducesResponseType(typeof(IEnumerable<CatalogItem>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> Items([FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0, [FromQuery] string ids = null)
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        public async Task<IActionResult> ItemsAsync([FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0, string ids = null)
 | 
			
		||||
        {
 | 
			
		||||
            if (!string.IsNullOrEmpty(ids))
 | 
			
		||||
            {
 | 
			
		||||
                return GetItemsByIds(ids);
 | 
			
		||||
                var items = await GetItemsByIdsAsync(ids);
 | 
			
		||||
 | 
			
		||||
                if (!items.Any())
 | 
			
		||||
                {
 | 
			
		||||
                    return BadRequest("ids value invalid. Must be comma-separated list of numbers");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return Ok(items);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var totalItems = await _catalogContext.CatalogItems
 | 
			
		||||
@ -54,37 +62,36 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
 | 
			
		||||
            itemsOnPage = ChangeUriPlaceholder(itemsOnPage);
 | 
			
		||||
 | 
			
		||||
            var model = new PaginatedItemsViewModel<CatalogItem>(
 | 
			
		||||
                pageIndex, pageSize, totalItems, itemsOnPage);
 | 
			
		||||
            var model = new PaginatedItemsViewModel<CatalogItem>(pageIndex, pageSize, totalItems, itemsOnPage);
 | 
			
		||||
 | 
			
		||||
            return Ok(model);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private IActionResult GetItemsByIds(string ids)
 | 
			
		||||
        private async Task<List<CatalogItem>> GetItemsByIdsAsync(string ids)
 | 
			
		||||
        {
 | 
			
		||||
            var numIds = ids.Split(',')
 | 
			
		||||
                .Select(id => (Ok: int.TryParse(id, out int x), Value: x));
 | 
			
		||||
            var numIds = ids.Split(',').Select(id => (Ok: int.TryParse(id, out int x), Value: x));
 | 
			
		||||
 | 
			
		||||
            if (!numIds.All(nid => nid.Ok))
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest("ids value invalid. Must be comma-separated list of numbers");
 | 
			
		||||
                return new List<CatalogItem>();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var idsToSelect = numIds
 | 
			
		||||
                .Select(id => id.Value);
 | 
			
		||||
 | 
			
		||||
            var items = _catalogContext.CatalogItems.Where(ci => idsToSelect.Contains(ci.Id)).ToList();
 | 
			
		||||
            var items = await _catalogContext.CatalogItems.Where(ci => idsToSelect.Contains(ci.Id)).ToListAsync();
 | 
			
		||||
 | 
			
		||||
            items = ChangeUriPlaceholder(items);
 | 
			
		||||
 | 
			
		||||
            return Ok(items);
 | 
			
		||||
            return items;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [Route("items/{id:int}")]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType(typeof(CatalogItem), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> GetItemById(int id)
 | 
			
		||||
        public async Task<ActionResult<CatalogItem>> ItemByIdAsync(int id)
 | 
			
		||||
        {
 | 
			
		||||
            if (id <= 0)
 | 
			
		||||
            {
 | 
			
		||||
@ -95,11 +102,12 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
 | 
			
		||||
            var baseUri = _settings.PicBaseUrl;
 | 
			
		||||
            var azureStorageEnabled = _settings.AzureStorageEnabled;
 | 
			
		||||
 | 
			
		||||
            item.FillProductUrl(baseUri, azureStorageEnabled: azureStorageEnabled);
 | 
			
		||||
 | 
			
		||||
            if (item != null)
 | 
			
		||||
            {
 | 
			
		||||
                return Ok(item);
 | 
			
		||||
                return item;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return NotFound();
 | 
			
		||||
@ -107,11 +115,10 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
 | 
			
		||||
        // GET api/v1/[controller]/items/withname/samplename[?pageSize=3&pageIndex=10]
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [Route("[action]/withname/{name:minlength(1)}")]
 | 
			
		||||
        [Route("items/withname/{name:minlength(1)}")]
 | 
			
		||||
        [ProducesResponseType(typeof(PaginatedItemsViewModel<CatalogItem>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> Items(string name, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0)
 | 
			
		||||
        public async Task<ActionResult<PaginatedItemsViewModel<CatalogItem>>> ItemsWithNameAsync(string name, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            var totalItems = await _catalogContext.CatalogItems
 | 
			
		||||
                .Where(c => c.Name.StartsWith(name))
 | 
			
		||||
                .LongCountAsync();
 | 
			
		||||
@ -124,17 +131,14 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
 | 
			
		||||
            itemsOnPage = ChangeUriPlaceholder(itemsOnPage);
 | 
			
		||||
 | 
			
		||||
            var model = new PaginatedItemsViewModel<CatalogItem>(
 | 
			
		||||
                pageIndex, pageSize, totalItems, itemsOnPage);
 | 
			
		||||
 | 
			
		||||
            return Ok(model);
 | 
			
		||||
            return new PaginatedItemsViewModel<CatalogItem>(pageIndex, pageSize, totalItems, itemsOnPage);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // GET api/v1/[controller]/items/type/1/brand[?pageSize=3&pageIndex=10]
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [Route("[action]/type/{catalogTypeId}/brand/{catalogBrandId:int?}")]
 | 
			
		||||
        [Route("items/type/{catalogTypeId}/brand/{catalogBrandId:int?}")]
 | 
			
		||||
        [ProducesResponseType(typeof(PaginatedItemsViewModel<CatalogItem>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> Items(int catalogTypeId, int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0)
 | 
			
		||||
        public async Task<ActionResult<PaginatedItemsViewModel<CatalogItem>>> ItemsByTypeIdAndBrandIdAsync(int catalogTypeId, int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0)
 | 
			
		||||
        {
 | 
			
		||||
            var root = (IQueryable<CatalogItem>)_catalogContext.CatalogItems;
 | 
			
		||||
 | 
			
		||||
@ -155,16 +159,14 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
 | 
			
		||||
            itemsOnPage = ChangeUriPlaceholder(itemsOnPage);
 | 
			
		||||
 | 
			
		||||
            var model = new PaginatedItemsViewModel<CatalogItem>(
 | 
			
		||||
                pageIndex, pageSize, totalItems, itemsOnPage);
 | 
			
		||||
 | 
			
		||||
            return Ok(model);
 | 
			
		||||
            return new PaginatedItemsViewModel<CatalogItem>(pageIndex, pageSize, totalItems, itemsOnPage);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // GET api/v1/[controller]/items/type/all/brand[?pageSize=3&pageIndex=10]
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [Route("[action]/type/all/brand/{catalogBrandId:int?}")]
 | 
			
		||||
        [Route("items/type/all/brand/{catalogBrandId:int?}")]
 | 
			
		||||
        [ProducesResponseType(typeof(PaginatedItemsViewModel<CatalogItem>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> Items(int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0)
 | 
			
		||||
        public async Task<ActionResult<PaginatedItemsViewModel<CatalogItem>>> ItemsByBrandIdAsync(int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0)
 | 
			
		||||
        {
 | 
			
		||||
            var root = (IQueryable<CatalogItem>)_catalogContext.CatalogItems;
 | 
			
		||||
 | 
			
		||||
@ -183,34 +185,25 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
 | 
			
		||||
            itemsOnPage = ChangeUriPlaceholder(itemsOnPage);
 | 
			
		||||
 | 
			
		||||
            var model = new PaginatedItemsViewModel<CatalogItem>(
 | 
			
		||||
                pageIndex, pageSize, totalItems, itemsOnPage);
 | 
			
		||||
 | 
			
		||||
            return Ok(model);
 | 
			
		||||
            return new PaginatedItemsViewModel<CatalogItem>(pageIndex, pageSize, totalItems, itemsOnPage);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // GET api/v1/[controller]/CatalogTypes
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [Route("[action]")]
 | 
			
		||||
        [ProducesResponseType(typeof(List<CatalogItem>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> CatalogTypes()
 | 
			
		||||
        [Route("catalogtypes")]
 | 
			
		||||
        [ProducesResponseType(typeof(List<CatalogType>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<ActionResult<List<CatalogType>>> CatalogTypesAsync()
 | 
			
		||||
        {
 | 
			
		||||
            var items = await _catalogContext.CatalogTypes
 | 
			
		||||
                .ToListAsync();
 | 
			
		||||
 | 
			
		||||
            return Ok(items);
 | 
			
		||||
            return await _catalogContext.CatalogTypes.ToListAsync();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // GET api/v1/[controller]/CatalogBrands
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [Route("[action]")]
 | 
			
		||||
        [ProducesResponseType(typeof(List<CatalogItem>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> CatalogBrands()
 | 
			
		||||
        [Route("catalogbrands")]
 | 
			
		||||
        [ProducesResponseType(typeof(List<CatalogBrand>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<ActionResult<List<CatalogBrand>>> CatalogBrandsAsync()
 | 
			
		||||
        {
 | 
			
		||||
            var items = await _catalogContext.CatalogBrands
 | 
			
		||||
                .ToListAsync();
 | 
			
		||||
 | 
			
		||||
            return Ok(items);
 | 
			
		||||
            return await _catalogContext.CatalogBrands.ToListAsync();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //PUT api/v1/[controller]/items
 | 
			
		||||
@ -218,10 +211,9 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
        [HttpPut]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.Created)]
 | 
			
		||||
        public async Task<IActionResult> UpdateProduct([FromBody]CatalogItem productToUpdate)
 | 
			
		||||
        public async Task<ActionResult> UpdateProductAsync([FromBody]CatalogItem productToUpdate)
 | 
			
		||||
        {
 | 
			
		||||
            var catalogItem = await _catalogContext.CatalogItems
 | 
			
		||||
                .SingleOrDefaultAsync(i => i.Id == productToUpdate.Id);
 | 
			
		||||
            var catalogItem = await _catalogContext.CatalogItems.SingleOrDefaultAsync(i => i.Id == productToUpdate.Id);
 | 
			
		||||
 | 
			
		||||
            if (catalogItem == null)
 | 
			
		||||
            {
 | 
			
		||||
@ -231,7 +223,6 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
            var oldPrice = catalogItem.Price;
 | 
			
		||||
            var raiseProductPriceChangedEvent = oldPrice != productToUpdate.Price;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // Update current product
 | 
			
		||||
            catalogItem = productToUpdate;
 | 
			
		||||
            _catalogContext.CatalogItems.Update(catalogItem);
 | 
			
		||||
@ -252,14 +243,14 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
                await _catalogContext.SaveChangesAsync();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return CreatedAtAction(nameof(GetItemById), new { id = productToUpdate.Id }, null);
 | 
			
		||||
            return CreatedAtAction(nameof(ItemByIdAsync), new { id = productToUpdate.Id }, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //POST api/v1/[controller]/items
 | 
			
		||||
        [Route("items")]
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.Created)]
 | 
			
		||||
        public async Task<IActionResult> CreateProduct([FromBody]CatalogItem product)
 | 
			
		||||
        public async Task<ActionResult> CreateProductAsync([FromBody]CatalogItem product)
 | 
			
		||||
        {
 | 
			
		||||
            var item = new CatalogItem
 | 
			
		||||
            {
 | 
			
		||||
@ -270,18 +261,20 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
                PictureFileName = product.PictureFileName,
 | 
			
		||||
                Price = product.Price
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            _catalogContext.CatalogItems.Add(item);
 | 
			
		||||
 | 
			
		||||
            await _catalogContext.SaveChangesAsync();
 | 
			
		||||
 | 
			
		||||
            return CreatedAtAction(nameof(GetItemById), new { id = item.Id }, null);
 | 
			
		||||
            return CreatedAtAction(nameof(ItemByIdAsync), new { id = item.Id }, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //DELETE api/v1/[controller]/id
 | 
			
		||||
        [Route("{id}")]
 | 
			
		||||
        [HttpDelete]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.NoContent)]
 | 
			
		||||
        public async Task<IActionResult> DeleteProduct(int id)
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
 | 
			
		||||
        public async Task<ActionResult> DeleteProductAsync(int id)
 | 
			
		||||
        {
 | 
			
		||||
            var product = _catalogContext.CatalogItems.SingleOrDefault(x => x.Id == id);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,8 +9,9 @@ using System.Threading.Tasks;
 | 
			
		||||
// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
 | 
			
		||||
 | 
			
		||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
{ 
 | 
			
		||||
    public class PicController : Controller
 | 
			
		||||
{
 | 
			
		||||
    [ApiController]
 | 
			
		||||
    public class PicController : ControllerBase
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IHostingEnvironment _env;
 | 
			
		||||
        private readonly CatalogContext _catalogContext;
 | 
			
		||||
@ -27,7 +28,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        // GET: /<controller>/
 | 
			
		||||
        public async Task<IActionResult> GetImage(int catalogItemId)
 | 
			
		||||
        public async Task<ActionResult> GetImageAsync(int catalogItemId)
 | 
			
		||||
        {
 | 
			
		||||
            if (catalogItemId <= 0)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
@ -139,9 +139,11 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            services.AddMvc(options =>
 | 
			
		||||
            {
 | 
			
		||||
                options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
			
		||||
            }).AddControllersAsServices();
 | 
			
		||||
                {
 | 
			
		||||
                    options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
			
		||||
                })
 | 
			
		||||
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
 | 
			
		||||
                .AddControllersAsServices();
 | 
			
		||||
 | 
			
		||||
            services.AddCors(options =>
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.DataProtection;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Identity;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.eShopOnContainers.Services.Identity.API.Certificates;
 | 
			
		||||
using Microsoft.eShopOnContainers.Services.Identity.API.Data;
 | 
			
		||||
@ -52,7 +53,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API
 | 
			
		||||
 | 
			
		||||
            services.Configure<AppSettings>(Configuration);
 | 
			
		||||
 | 
			
		||||
            services.AddMvc();
 | 
			
		||||
            services.AddMvc()
 | 
			
		||||
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
 | 
			
		||||
 | 
			
		||||
            if (Configuration.GetValue<string>("IsClusterEnv") == bool.TrueString)
 | 
			
		||||
            {
 | 
			
		||||
@ -159,6 +161,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API
 | 
			
		||||
            // Adds IdentityServer
 | 
			
		||||
            app.UseIdentityServer();
 | 
			
		||||
 | 
			
		||||
            app.UseHttpsRedirection();
 | 
			
		||||
            app.UseMvc(routes =>
 | 
			
		||||
            {
 | 
			
		||||
                routes.MapRoute(
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,7 @@ namespace Locations.API.Controllers
 | 
			
		||||
{
 | 
			
		||||
    [Route("api/v1/[controller]")]
 | 
			
		||||
    [Authorize]
 | 
			
		||||
    [ApiController]
 | 
			
		||||
    public class LocationsController : ControllerBase
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ILocationsService _locationsService;
 | 
			
		||||
@ -27,30 +28,27 @@ namespace Locations.API.Controllers
 | 
			
		||||
        [Route("user/{userId:guid}")]
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [ProducesResponseType(typeof(UserLocation), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> GetUserLocation(Guid userId)
 | 
			
		||||
        public async Task<ActionResult<UserLocation>> GetUserLocationAsync(Guid userId)
 | 
			
		||||
        {
 | 
			
		||||
            var userLocation = await _locationsService.GetUserLocation(userId.ToString());
 | 
			
		||||
            return Ok(userLocation);
 | 
			
		||||
            return await _locationsService.GetUserLocationAsync(userId.ToString());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //GET api/v1/[controller]/
 | 
			
		||||
        [Route("")]
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        //[ProducesResponseType(typeof(List<Locations>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> GetAllLocations()
 | 
			
		||||
        [ProducesResponseType(typeof(List<Microsoft.eShopOnContainers.Services.Locations.API.Model.Locations>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<ActionResult<List<Microsoft.eShopOnContainers.Services.Locations.API.Model.Locations>>> GetAllLocationsAsync()
 | 
			
		||||
        {
 | 
			
		||||
            var locations = await _locationsService.GetAllLocation();
 | 
			
		||||
            return Ok(locations);
 | 
			
		||||
            return await _locationsService.GetAllLocationAsync();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //GET api/v1/[controller]/1
 | 
			
		||||
        [Route("{locationId}")]
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        //[ProducesResponseType(typeof(List<Locations>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> GetLocation(int locationId)
 | 
			
		||||
        [ProducesResponseType(typeof(Microsoft.eShopOnContainers.Services.Locations.API.Model.Locations), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<ActionResult<Microsoft.eShopOnContainers.Services.Locations.API.Model.Locations>> GetLocationAsync(int locationId)
 | 
			
		||||
        {
 | 
			
		||||
            var location = await _locationsService.GetLocation(locationId);
 | 
			
		||||
            return Ok(location);
 | 
			
		||||
            return await _locationsService.GetLocationAsync(locationId);
 | 
			
		||||
        }
 | 
			
		||||
         
 | 
			
		||||
        //POST api/v1/[controller]/
 | 
			
		||||
@ -58,14 +56,17 @@ namespace Locations.API.Controllers
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.OK)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        public async Task<IActionResult> CreateOrUpdateUserLocation([FromBody]LocationRequest newLocReq)
 | 
			
		||||
        public async Task<ActionResult> CreateOrUpdateUserLocationAsync([FromBody]LocationRequest newLocReq)
 | 
			
		||||
        {
 | 
			
		||||
            var userId = _identityService.GetUserIdentity();
 | 
			
		||||
            var result = await _locationsService.AddOrUpdateUserLocation(userId, newLocReq);
 | 
			
		||||
           
 | 
			
		||||
            return result ? 
 | 
			
		||||
                (IActionResult)Ok() : 
 | 
			
		||||
                (IActionResult)BadRequest();
 | 
			
		||||
            var result = await _locationsService.AddOrUpdateUserLocationAsync(userId, newLocReq);
 | 
			
		||||
 | 
			
		||||
            if (!result)
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,12 +7,12 @@
 | 
			
		||||
 | 
			
		||||
    public interface ILocationsService
 | 
			
		||||
    {
 | 
			
		||||
        Task<Locations> GetLocation(int locationId);
 | 
			
		||||
        Task<Locations> GetLocationAsync(int locationId);
 | 
			
		||||
 | 
			
		||||
        Task<UserLocation> GetUserLocation(string id);
 | 
			
		||||
        Task<UserLocation> GetUserLocationAsync(string id);
 | 
			
		||||
 | 
			
		||||
        Task<List<Locations>> GetAllLocation();
 | 
			
		||||
        Task<List<Locations>> GetAllLocationAsync();
 | 
			
		||||
 | 
			
		||||
        Task<bool> AddOrUpdateUserLocation(string userId, LocationRequest locRequest);
 | 
			
		||||
        Task<bool> AddOrUpdateUserLocationAsync(string userId, LocationRequest locRequest);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -21,22 +21,22 @@
 | 
			
		||||
            _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<Locations> GetLocation(int locationId)
 | 
			
		||||
        public async Task<Locations> GetLocationAsync(int locationId)
 | 
			
		||||
        {
 | 
			
		||||
            return await _locationsRepository.GetAsync(locationId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<UserLocation> GetUserLocation(string userId)
 | 
			
		||||
        public async Task<UserLocation> GetUserLocationAsync(string userId)
 | 
			
		||||
        {
 | 
			
		||||
            return await _locationsRepository.GetUserLocationAsync(userId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<List<Locations>> GetAllLocation()
 | 
			
		||||
        public async Task<List<Locations>> GetAllLocationAsync()
 | 
			
		||||
        {
 | 
			
		||||
            return await _locationsRepository.GetLocationListAsync();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<bool> AddOrUpdateUserLocation(string userId, LocationRequest currentPosition)
 | 
			
		||||
        public async Task<bool> AddOrUpdateUserLocationAsync(string userId, LocationRequest currentPosition)
 | 
			
		||||
        {            
 | 
			
		||||
            // Get the list of ordered regions the user currently is within
 | 
			
		||||
            var currentUserAreaLocationList = await _locationsRepository.GetCurrentUserRegionsListAsync(currentPosition);
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.Azure.ServiceBus;
 | 
			
		||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
 | 
			
		||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
 | 
			
		||||
@ -43,9 +44,11 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API
 | 
			
		||||
            RegisterAppInsights(services);
 | 
			
		||||
 | 
			
		||||
            services.AddMvc(options =>
 | 
			
		||||
            {
 | 
			
		||||
                options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
			
		||||
            }).AddControllersAsServices();
 | 
			
		||||
                {
 | 
			
		||||
                    options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
			
		||||
                })
 | 
			
		||||
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
 | 
			
		||||
                .AddControllersAsServices();
 | 
			
		||||
 | 
			
		||||
            ConfigureAuthService(services);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,8 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
 | 
			
		||||
    [Route("api/v1/[controller]")]
 | 
			
		||||
    [Authorize]
 | 
			
		||||
    public class CampaignsController : Controller
 | 
			
		||||
    [ApiController]
 | 
			
		||||
    public class CampaignsController : ControllerBase
 | 
			
		||||
    {
 | 
			
		||||
        private readonly MarketingContext _context;
 | 
			
		||||
        private readonly MarketingSettings _settings;
 | 
			
		||||
@ -40,43 +41,37 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [ProducesResponseType(typeof(List<CampaignDTO>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> GetAllCampaigns()
 | 
			
		||||
        public async Task<ActionResult<List<CampaignDTO>>> GetAllCampaignsAsync()
 | 
			
		||||
        {
 | 
			
		||||
            var campaignList = await _context.Campaigns
 | 
			
		||||
                .ToListAsync();
 | 
			
		||||
            var campaignList = await _context.Campaigns.ToListAsync();
 | 
			
		||||
 | 
			
		||||
            if (campaignList is null)
 | 
			
		||||
            {
 | 
			
		||||
                return Ok();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var campaignDtoList = MapCampaignModelListToDtoList(campaignList);
 | 
			
		||||
 | 
			
		||||
            return Ok(campaignDtoList);
 | 
			
		||||
            return MapCampaignModelListToDtoList(campaignList);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpGet("{id:int}")]
 | 
			
		||||
        [ProducesResponseType(typeof(CampaignDTO), (int)HttpStatusCode.OK)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
 | 
			
		||||
        public async Task<IActionResult> GetCampaignById(int id)
 | 
			
		||||
        public async Task<ActionResult<CampaignDTO>> GetCampaignByIdAsync(int id)
 | 
			
		||||
        {
 | 
			
		||||
            var campaign = await _context.Campaigns
 | 
			
		||||
                .SingleOrDefaultAsync(c => c.Id == id);
 | 
			
		||||
            var campaign = await _context.Campaigns.SingleOrDefaultAsync(c => c.Id == id);
 | 
			
		||||
 | 
			
		||||
            if (campaign is null)
 | 
			
		||||
            {
 | 
			
		||||
                return NotFound();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var campaignDto = MapCampaignModelToDto(campaign);
 | 
			
		||||
 | 
			
		||||
            return Ok(campaignDto);
 | 
			
		||||
            return MapCampaignModelToDto(campaign);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.Created)]
 | 
			
		||||
        public async Task<IActionResult> CreateCampaign([FromBody] CampaignDTO campaignDto)
 | 
			
		||||
        public async Task<ActionResult> CreateCampaignAsync([FromBody] CampaignDTO campaignDto)
 | 
			
		||||
        {
 | 
			
		||||
            if (campaignDto is null)
 | 
			
		||||
            {
 | 
			
		||||
@ -88,14 +83,14 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
            await _context.Campaigns.AddAsync(campaign);
 | 
			
		||||
            await _context.SaveChangesAsync();
 | 
			
		||||
 | 
			
		||||
            return CreatedAtAction(nameof(GetCampaignById), new { id = campaign.Id }, null);
 | 
			
		||||
            return CreatedAtAction(nameof(GetCampaignByIdAsync), new { id = campaign.Id }, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpPut("{id:int}")]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.Created)]
 | 
			
		||||
        public async Task<IActionResult> UpdateCampaign(int id, [FromBody] CampaignDTO campaignDto)
 | 
			
		||||
        public async Task<ActionResult> UpdateCampaignAsync(int id, [FromBody] CampaignDTO campaignDto)
 | 
			
		||||
        {
 | 
			
		||||
            if (id < 1 || campaignDto is null)
 | 
			
		||||
            {
 | 
			
		||||
@ -116,14 +111,14 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
 | 
			
		||||
            await _context.SaveChangesAsync();
 | 
			
		||||
 | 
			
		||||
            return CreatedAtAction(nameof(GetCampaignById), new { id = campaignToUpdate.Id }, null);
 | 
			
		||||
            return CreatedAtAction(nameof(GetCampaignByIdAsync), new { id = campaignToUpdate.Id }, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpDelete("{id:int}")]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.NoContent)]
 | 
			
		||||
        public async Task<IActionResult> Delete(int id)
 | 
			
		||||
        public async Task<ActionResult> DeleteCampaignByIdAsync(int id)
 | 
			
		||||
        {
 | 
			
		||||
            if (id < 1)
 | 
			
		||||
            {
 | 
			
		||||
@ -131,6 +126,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var campaignToDelete = await _context.Campaigns.FindAsync(id);
 | 
			
		||||
 | 
			
		||||
            if (campaignToDelete is null)
 | 
			
		||||
            {
 | 
			
		||||
                return NotFound();
 | 
			
		||||
@ -144,7 +140,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
 | 
			
		||||
        [HttpGet("user")]
 | 
			
		||||
        [ProducesResponseType(typeof(PaginatedItemsViewModel<CampaignDTO>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> GetCampaignsByUserId( int pageSize = 10, int pageIndex = 0)
 | 
			
		||||
        public async Task<ActionResult<PaginatedItemsViewModel<CampaignDTO>>> GetCampaignsByUserIdAsync( int pageSize = 10, int pageIndex = 0)
 | 
			
		||||
        {
 | 
			
		||||
            var userId = _identityService.GetUserIdentity();
 | 
			
		||||
 | 
			
		||||
@ -169,21 +165,17 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
                    var userCampaignDtoList = MapCampaignModelListToDtoList(userCampaignList);
 | 
			
		||||
                    campaignDtoList.AddRange(userCampaignDtoList);
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var totalItems = campaignDtoList.Count();
 | 
			
		||||
 | 
			
		||||
            campaignDtoList = campaignDtoList
 | 
			
		||||
                .Skip(pageSize * pageIndex)
 | 
			
		||||
                .Take(pageSize).ToList();
 | 
			
		||||
 | 
			
		||||
            var model = new PaginatedItemsViewModel<CampaignDTO>(
 | 
			
		||||
                pageIndex, pageSize, totalItems, campaignDtoList);
 | 
			
		||||
 | 
			
		||||
            return Ok(model);
 | 
			
		||||
            return new PaginatedItemsViewModel<CampaignDTO>(pageIndex, pageSize, totalItems, campaignDtoList);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private List<CampaignDTO> MapCampaignModelListToDtoList(List<Campaign> campaignList)
 | 
			
		||||
        {
 | 
			
		||||
            var campaignDtoList = new List<CampaignDTO>();
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,8 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
    [Authorize]
 | 
			
		||||
    public class LocationsController : Controller
 | 
			
		||||
    [ApiController]
 | 
			
		||||
    public class LocationsController : ControllerBase
 | 
			
		||||
    {
 | 
			
		||||
        private readonly MarketingContext _context;
 | 
			
		||||
 | 
			
		||||
@ -25,7 +26,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
 | 
			
		||||
        [ProducesResponseType(typeof(UserLocationRuleDTO),(int)HttpStatusCode.OK)]
 | 
			
		||||
        public IActionResult GetLocationByCampaignAndLocationRuleId(int campaignId, 
 | 
			
		||||
        public ActionResult<UserLocationRuleDTO> GetLocationByCampaignAndLocationRuleId(int campaignId, 
 | 
			
		||||
            int userLocationRuleId)
 | 
			
		||||
        {
 | 
			
		||||
            if (campaignId < 1 || userLocationRuleId < 1)
 | 
			
		||||
@ -42,9 +43,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
                return NotFound();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var locationDto = MapUserLocationRuleModelToDto(location);
 | 
			
		||||
 | 
			
		||||
            return Ok(locationDto);
 | 
			
		||||
            return MapUserLocationRuleModelToDto(location);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
@ -52,7 +51,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.OK)]
 | 
			
		||||
        [ProducesResponseType(typeof(List<UserLocationRuleDTO>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public IActionResult GetAllLocationsByCampaignId(int campaignId)
 | 
			
		||||
        public ActionResult<List<UserLocationRuleDTO>> GetAllLocationsByCampaignId(int campaignId)
 | 
			
		||||
        {
 | 
			
		||||
            if (campaignId < 1)
 | 
			
		||||
            {
 | 
			
		||||
@ -69,17 +68,14 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
                return Ok();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var locationDtoList = MapUserLocationRuleModelListToDtoList(locationList);
 | 
			
		||||
 | 
			
		||||
            return Ok(locationDtoList);
 | 
			
		||||
            return MapUserLocationRuleModelListToDtoList(locationList);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("api/v1/campaigns/{campaignId:int}/locations")]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.Created)]
 | 
			
		||||
        public async Task<IActionResult> CreateLocation(int campaignId, 
 | 
			
		||||
            [FromBody] UserLocationRuleDTO locationRuleDto)
 | 
			
		||||
        public async Task<ActionResult> CreateLocationAsync(int campaignId, [FromBody] UserLocationRuleDTO locationRuleDto)
 | 
			
		||||
        {
 | 
			
		||||
            if (campaignId < 1 || locationRuleDto is null)
 | 
			
		||||
            {
 | 
			
		||||
@ -100,7 +96,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
        [Route("api/v1/campaigns/{campaignId:int}/locations/{userLocationRuleId:int}")]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
 | 
			
		||||
        public async Task<IActionResult> DeleteLocationById(int campaignId, int userLocationRuleId)
 | 
			
		||||
        public async Task<ActionResult> DeleteLocationByIdAsync(int campaignId, int userLocationRuleId)
 | 
			
		||||
        {
 | 
			
		||||
            if (campaignId < 1 || userLocationRuleId < 1)
 | 
			
		||||
            {
 | 
			
		||||
@ -122,8 +118,6 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers
 | 
			
		||||
            return NoContent();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private List<UserLocationRuleDTO> MapUserLocationRuleModelListToDtoList(List<UserLocationRule> userLocationRuleList)
 | 
			
		||||
        {
 | 
			
		||||
            var userLocationRuleDtoList = new List<UserLocationRuleDTO>();
 | 
			
		||||
 | 
			
		||||
@ -4,8 +4,8 @@
 | 
			
		||||
    using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
    using System.IO;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public class PicController : Controller
 | 
			
		||||
    [ApiController]
 | 
			
		||||
    public class PicController : ControllerBase
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IHostingEnvironment _env;
 | 
			
		||||
        public PicController(IHostingEnvironment env)
 | 
			
		||||
@ -15,7 +15,7 @@
 | 
			
		||||
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [Route("api/v1/campaigns/{campaignId:int}/pic")]
 | 
			
		||||
        public IActionResult GetImage(int campaignId)
 | 
			
		||||
        public ActionResult GetImage(int campaignId)
 | 
			
		||||
        {
 | 
			
		||||
            var webRoot = _env.WebRootPath;
 | 
			
		||||
            var path = Path.Combine(webRoot, campaignId + ".png");
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@
 | 
			
		||||
    using Microsoft.ApplicationInsights.Extensibility;
 | 
			
		||||
    using Microsoft.ApplicationInsights.ServiceFabric;
 | 
			
		||||
    using Microsoft.AspNetCore.Authentication.JwtBearer;
 | 
			
		||||
    using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
    using Microsoft.EntityFrameworkCore.Diagnostics;
 | 
			
		||||
    using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Middlewares;
 | 
			
		||||
    using RabbitMQ.Client;
 | 
			
		||||
@ -53,7 +54,9 @@
 | 
			
		||||
            services.AddMvc(options =>
 | 
			
		||||
            {
 | 
			
		||||
                options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
			
		||||
            }).AddControllersAsServices();  //Injecting Controllers themselves thru DIFor further info see: http://docs.autofac.org/en/latest/integration/aspnetcore.html#controllers-as-services
 | 
			
		||||
            })
 | 
			
		||||
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
 | 
			
		||||
            .AddControllersAsServices();  //Injecting Controllers themselves thru DIFor further info see: http://docs.autofac.org/en/latest/integration/aspnetcore.html#controllers-as-services
 | 
			
		||||
 | 
			
		||||
            services.Configure<MarketingSettings>(Configuration);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
 | 
			
		||||
    [Route("api/v1/[controller]")]
 | 
			
		||||
    [Authorize]
 | 
			
		||||
    [ApiController]
 | 
			
		||||
    public class OrdersController : Controller
 | 
			
		||||
    public class OrdersController : ControllerBase
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IMediator _mediator;
 | 
			
		||||
        private readonly IOrderQueries _orderQueries;
 | 
			
		||||
@ -23,7 +23,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
 | 
			
		||||
 | 
			
		||||
        public OrdersController(IMediator mediator, IOrderQueries orderQueries, IIdentityService identityService)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
 | 
			
		||||
            _orderQueries = orderQueries ?? throw new ArgumentNullException(nameof(orderQueries));
 | 
			
		||||
            _identityService = identityService ?? throw new ArgumentNullException(nameof(identityService));
 | 
			
		||||
@ -33,84 +32,89 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
 | 
			
		||||
        [HttpPut]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.OK)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        public async Task<IActionResult> CancelOrder([FromBody]CancelOrderCommand command, [FromHeader(Name = "x-requestid")] string requestId)
 | 
			
		||||
        public async Task<IActionResult> CancelOrderAsync([FromBody]CancelOrderCommand command, [FromHeader(Name = "x-requestid")] string requestId)
 | 
			
		||||
        {
 | 
			
		||||
            bool commandResult = false;
 | 
			
		||||
 | 
			
		||||
            if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty)
 | 
			
		||||
            {
 | 
			
		||||
                var requestCancelOrder = new IdentifiedCommand<CancelOrderCommand, bool>(command, guid);
 | 
			
		||||
                commandResult = await _mediator.Send(requestCancelOrder);
 | 
			
		||||
            }
 | 
			
		||||
           
 | 
			
		||||
            return commandResult ? (IActionResult)Ok() : (IActionResult)BadRequest();
 | 
			
		||||
 | 
			
		||||
            if (!commandResult)
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Route("ship")]
 | 
			
		||||
        [HttpPut]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.OK)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
 | 
			
		||||
        public async Task<IActionResult> ShipOrder([FromBody]ShipOrderCommand command, [FromHeader(Name = "x-requestid")] string requestId)
 | 
			
		||||
        public async Task<IActionResult> ShipOrderAsync([FromBody]ShipOrderCommand command, [FromHeader(Name = "x-requestid")] string requestId)
 | 
			
		||||
        {
 | 
			
		||||
            bool commandResult = false;
 | 
			
		||||
 | 
			
		||||
            if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty)
 | 
			
		||||
            {
 | 
			
		||||
                var requestShipOrder = new IdentifiedCommand<ShipOrderCommand, bool>(command, guid);
 | 
			
		||||
                commandResult = await _mediator.Send(requestShipOrder);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return commandResult ? (IActionResult)Ok() : (IActionResult)BadRequest();
 | 
			
		||||
            if (!commandResult)
 | 
			
		||||
            {
 | 
			
		||||
                return BadRequest();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Route("{orderId:int}")]
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [ProducesResponseType(typeof(Order),(int)HttpStatusCode.OK)]
 | 
			
		||||
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
 | 
			
		||||
        public async Task<IActionResult> GetOrder(int orderId)
 | 
			
		||||
        public async Task<ActionResult> GetOrderAsync(int orderId)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var order = await _orderQueries
 | 
			
		||||
                    .GetOrderAsync(orderId);
 | 
			
		||||
                var order = await _orderQueries.GetOrderAsync(orderId);
 | 
			
		||||
 | 
			
		||||
                return Ok(order);
 | 
			
		||||
            }
 | 
			
		||||
            catch (KeyNotFoundException)
 | 
			
		||||
            catch
 | 
			
		||||
            {
 | 
			
		||||
                return NotFound();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Route("")]
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [ProducesResponseType(typeof(IEnumerable<OrderSummary>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> GetOrders()
 | 
			
		||||
        public async Task<ActionResult<IEnumerable<OrderSummary>>> GetOrdersAsync()
 | 
			
		||||
        {
 | 
			
		||||
            var userid = _identityService.GetUserIdentity();
 | 
			
		||||
            var orders = await _orderQueries.GetOrdersFromUserAsync(Guid.Parse(userid));
 | 
			
		||||
 | 
			
		||||
            return Ok(orders);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Route("cardtypes")]
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [ProducesResponseType(typeof(IEnumerable<CardType>), (int)HttpStatusCode.OK)]
 | 
			
		||||
        public async Task<IActionResult> GetCardTypes()
 | 
			
		||||
        public async Task<ActionResult<IEnumerable<CardType>>> GetCardTypesAsync()
 | 
			
		||||
        {
 | 
			
		||||
            var cardTypes = await _orderQueries
 | 
			
		||||
                .GetCardTypesAsync();
 | 
			
		||||
            var cardTypes = await _orderQueries.GetCardTypesAsync();
 | 
			
		||||
 | 
			
		||||
            return Ok(cardTypes);
 | 
			
		||||
        }        
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Route("draft")]
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        public async Task<IActionResult> GetOrderDraftFromBasketData([FromBody] CreateOrderDraftCommand createOrderDraftCommand)
 | 
			
		||||
        public async Task<ActionResult<OrderDraftDTO>> CreateOrderDraftFromBasketDataAsync([FromBody] CreateOrderDraftCommand createOrderDraftCommand)
 | 
			
		||||
        {
 | 
			
		||||
            var draft  = await _mediator.Send(createOrderDraftCommand);
 | 
			
		||||
            return Ok(draft);
 | 
			
		||||
            return await _mediator.Send(createOrderDraftCommand);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -154,9 +154,11 @@
 | 
			
		||||
        {
 | 
			
		||||
            // Add framework services.
 | 
			
		||||
            services.AddMvc(options =>
 | 
			
		||||
            {
 | 
			
		||||
                options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
			
		||||
            }).AddControllersAsServices();  //Injecting Controllers themselves thru DI
 | 
			
		||||
                {
 | 
			
		||||
                    options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
			
		||||
                })
 | 
			
		||||
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
 | 
			
		||||
                .AddControllersAsServices();  //Injecting Controllers themselves thru DI
 | 
			
		||||
                                            //For further info see: http://docs.autofac.org/en/latest/integration/aspnetcore.html#controllers-as-services
 | 
			
		||||
 | 
			
		||||
            services.AddCors(options =>
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ namespace UnitTest.Ordering.Application
 | 
			
		||||
 | 
			
		||||
            //Act
 | 
			
		||||
            var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
 | 
			
		||||
            var actionResult = await orderController.CancelOrder(new CancelOrderCommand(1), Guid.NewGuid().ToString()) as OkResult;
 | 
			
		||||
            var actionResult = await orderController.CancelOrderAsync(new CancelOrderCommand(1), Guid.NewGuid().ToString()) as OkResult;
 | 
			
		||||
 | 
			
		||||
            //Assert
 | 
			
		||||
            Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
 | 
			
		||||
@ -52,7 +52,7 @@ namespace UnitTest.Ordering.Application
 | 
			
		||||
 | 
			
		||||
            //Act
 | 
			
		||||
            var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
 | 
			
		||||
            var actionResult = await orderController.CancelOrder(new CancelOrderCommand(1), String.Empty) as BadRequestResult;
 | 
			
		||||
            var actionResult = await orderController.CancelOrderAsync(new CancelOrderCommand(1), String.Empty) as BadRequestResult;
 | 
			
		||||
 | 
			
		||||
            //Assert
 | 
			
		||||
            Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.BadRequest);
 | 
			
		||||
@ -67,7 +67,7 @@ namespace UnitTest.Ordering.Application
 | 
			
		||||
 | 
			
		||||
            //Act
 | 
			
		||||
            var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
 | 
			
		||||
            var actionResult = await orderController.ShipOrder(new ShipOrderCommand(1), Guid.NewGuid().ToString()) as OkResult;
 | 
			
		||||
            var actionResult = await orderController.ShipOrderAsync(new ShipOrderCommand(1), Guid.NewGuid().ToString()) as OkResult;
 | 
			
		||||
 | 
			
		||||
            //Assert
 | 
			
		||||
            Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
 | 
			
		||||
@ -83,7 +83,7 @@ namespace UnitTest.Ordering.Application
 | 
			
		||||
 | 
			
		||||
            //Act
 | 
			
		||||
            var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
 | 
			
		||||
            var actionResult = await orderController.ShipOrder(new ShipOrderCommand(1), String.Empty) as BadRequestResult;
 | 
			
		||||
            var actionResult = await orderController.ShipOrderAsync(new ShipOrderCommand(1), String.Empty) as BadRequestResult;
 | 
			
		||||
 | 
			
		||||
            //Assert
 | 
			
		||||
            Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.BadRequest);
 | 
			
		||||
@ -103,10 +103,10 @@ namespace UnitTest.Ordering.Application
 | 
			
		||||
 | 
			
		||||
            //Act
 | 
			
		||||
            var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
 | 
			
		||||
            var actionResult = await orderController.GetOrders() as OkObjectResult;
 | 
			
		||||
            var actionResult = await orderController.GetOrdersAsync();
 | 
			
		||||
 | 
			
		||||
            //Assert
 | 
			
		||||
            Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
 | 
			
		||||
            Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@ -120,7 +120,7 @@ namespace UnitTest.Ordering.Application
 | 
			
		||||
 | 
			
		||||
            //Act
 | 
			
		||||
            var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
 | 
			
		||||
            var actionResult = await orderController.GetOrder(fakeOrderId) as OkObjectResult;
 | 
			
		||||
            var actionResult = await orderController.GetOrderAsync(fakeOrderId) as OkObjectResult;
 | 
			
		||||
 | 
			
		||||
            //Assert
 | 
			
		||||
            Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
 | 
			
		||||
@ -136,10 +136,10 @@ namespace UnitTest.Ordering.Application
 | 
			
		||||
 | 
			
		||||
            //Act
 | 
			
		||||
            var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
 | 
			
		||||
            var actionResult = await orderController.GetCardTypes() as OkObjectResult;
 | 
			
		||||
            var actionResult = await orderController.GetCardTypesAsync();
 | 
			
		||||
 | 
			
		||||
            //Assert
 | 
			
		||||
            Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
 | 
			
		||||
            Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.DataProtection;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.eShopOnContainers.WebMVC.Services;
 | 
			
		||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
@ -59,6 +60,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                app.UseExceptionHandler("/Error");
 | 
			
		||||
                app.UseHsts();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var pathBase = Configuration["PATH_BASE"];
 | 
			
		||||
@ -87,6 +89,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
 | 
			
		||||
 | 
			
		||||
            WebContextSeed.Seed(app, env, loggerFactory);
 | 
			
		||||
 | 
			
		||||
            app.UseHttpsRedirection();
 | 
			
		||||
            app.UseMvc(routes =>
 | 
			
		||||
            {
 | 
			
		||||
                routes.MapRoute(
 | 
			
		||||
@ -149,7 +152,8 @@ namespace Microsoft.eShopOnContainers.WebMVC
 | 
			
		||||
            services.AddOptions();
 | 
			
		||||
            services.Configure<AppSettings>(configuration);
 | 
			
		||||
 | 
			
		||||
            services.AddMvc();
 | 
			
		||||
            services.AddMvc()
 | 
			
		||||
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
 | 
			
		||||
 | 
			
		||||
            services.AddSession();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Antiforgery;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.DataProtection;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Microsoft.Extensions.HealthChecks;
 | 
			
		||||
@ -71,6 +72,7 @@ namespace eShopConContainers.WebSPA
 | 
			
		||||
            services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
 | 
			
		||||
 | 
			
		||||
            services.AddMvc()
 | 
			
		||||
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
 | 
			
		||||
                .AddJsonOptions(options =>
 | 
			
		||||
                {
 | 
			
		||||
                    options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
 | 
			
		||||
@ -89,6 +91,11 @@ namespace eShopConContainers.WebSPA
 | 
			
		||||
            {
 | 
			
		||||
                app.UseDeveloperExceptionPage();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
 | 
			
		||||
                app.UseHsts();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Configure XSRF middleware, This pattern is for SPA style applications where XSRF token is added on Index page 
 | 
			
		||||
            // load and passed back token on every subsequent async request            
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging;
 | 
			
		||||
using WebStatus.Extensions;
 | 
			
		||||
using Microsoft.ApplicationInsights.Extensibility;
 | 
			
		||||
using Microsoft.ApplicationInsights.ServiceFabric;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
 | 
			
		||||
namespace WebStatus
 | 
			
		||||
{
 | 
			
		||||
@ -50,7 +51,8 @@ namespace WebStatus
 | 
			
		||||
                checks.AddUrlCheckIfNotNull(Configuration["spa"], TimeSpan.Zero); //No cache for this HealthCheck, better just for demos 
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            services.AddMvc();
 | 
			
		||||
            services.AddMvc()
 | 
			
		||||
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
 | 
			
		||||
@ -66,6 +68,8 @@ namespace WebStatus
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                app.UseExceptionHandler("/Home/Error");
 | 
			
		||||
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
 | 
			
		||||
                app.UseHsts();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var pathBase = Configuration["PATH_BASE"];
 | 
			
		||||
@ -74,13 +78,14 @@ namespace WebStatus
 | 
			
		||||
                app.UsePathBase(pathBase);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
 | 
			
		||||
            app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200));
 | 
			
		||||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
 | 
			
		||||
 | 
			
		||||
            app.UseStaticFiles();
 | 
			
		||||
 | 
			
		||||
            app.UseHttpsRedirection();
 | 
			
		||||
 | 
			
		||||
            app.UseMvc(routes =>
 | 
			
		||||
            {
 | 
			
		||||
                routes.MapRoute(
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user