From 704e6ae69333551e3d7b91b361e60211e035430e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduard=20Tom=C3=A0s?= Date: Fri, 2 Feb 2018 15:55:33 +0000 Subject: [PATCH] Finished purchase-bff implementation and ocelot rerouting --- docker-compose.override.yml | 3 - src/Apigw/OcelotApiGw/Program.cs | 13 ++- .../configuration/configuration.json | 98 ++++++++++++++----- .../Resilience.Http/ResilientHttpClient.cs | 5 + .../Resilience.Http/StandardHttpClient.cs | 5 + .../Controllers/BasketController.cs | 4 + src/Web/WebMVC/AppSettings.cs | 3 - src/Web/WebMVC/Services/BasketService.cs | 21 ++-- src/Web/WebMVC/Services/CatalogService.cs | 2 +- src/Web/WebMVC/Services/OrderingService.cs | 2 +- 10 files changed, 108 insertions(+), 48 deletions(-) diff --git a/docker-compose.override.yml b/docker-compose.override.yml index bf6a80691..1a8d9c284 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -134,9 +134,6 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - CatalogUrl=http://apigw/purchase-bff/catalog - - OrderingUrl=http://ordering.api - - BasketUrl=http://basket.api - PurchaseUrl=http://apigw/purchase-bff - LocationsUrl=http://locations.api - IdentityUrl=http://10.0.75.1:5105 # Local Mac: Use http://docker.for.mac.localhost:5105 || Local Windows: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser. || #Remote access: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser. diff --git a/src/Apigw/OcelotApiGw/Program.cs b/src/Apigw/OcelotApiGw/Program.cs index bd5230b96..782681901 100644 --- a/src/Apigw/OcelotApiGw/Program.cs +++ b/src/Apigw/OcelotApiGw/Program.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; namespace OcelotApiGw { @@ -17,10 +18,14 @@ namespace OcelotApiGw BuildWebHost(args).Run(); } - public static IWebHost BuildWebHost(string[] args) => - WebHost.CreateDefaultBuilder(args) + public static IWebHost BuildWebHost(string[] args) + { + var builder = WebHost.CreateDefaultBuilder(args); + builder.ConfigureServices(s => s.AddSingleton(builder)) .ConfigureAppConfiguration(ic => ic.AddJsonFile(Path.Combine("configuration", "configuration.json"))) - .UseStartup() - .Build(); + .UseStartup(); + var host = builder.Build(); + return host; + } } } diff --git a/src/Apigw/OcelotApiGw/configuration/configuration.json b/src/Apigw/OcelotApiGw/configuration/configuration.json index cc2defca6..2d5e6c8f7 100644 --- a/src/Apigw/OcelotApiGw/configuration/configuration.json +++ b/src/Apigw/OcelotApiGw/configuration/configuration.json @@ -1,20 +1,44 @@ { "ReRoutes": [ { - "DownstreamPathTemplate": "/{everything}", + "DownstreamPathTemplate": "/api/{version}/{everything}", "DownstreamScheme": "http", - "DownstreamHost": "catalog.api", - "DownstreamPort": 80, - "UpstreamPathTemplate": "/purchase-bff/catalog/{everything}", + "DownstreamHostAndPorts": [ + { + "Host": "catalog.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/purchase-bff/api/{version}/c/{everything}", "UpstreamHttpMethod": [ "GET" ] }, { - "DownstreamPathTemplate": "/{everything}", + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "basket.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/purchase-bff/api/{version}/b/{everything}", + "UpstreamHttpMethod": [], + "AuthenticationOptions": { + "AuthenticationProviderKey": "IdentityApiKey", + "AllowedScopes": [] + } + }, + { + "DownstreamPathTemplate": "/api/{version}/{everything}", "DownstreamScheme": "http", - "DownstreamHost": "basket.api", - "DownstreamPort": 80, - "UpstreamPathTemplate": "/purchase-bff/basket/{everything}", - "UpstreamHttpMethod": [ "GET" ], + "DownstreamHostAndPorts": [ + { + "Host": "ordering.api", + "Port": 80 + } + ], + "UpstreamPathTemplate": "/purchase-bff/api/{version}/o/{everything}", + "UpstreamHttpMethod": [], "AuthenticationOptions": { "AuthenticationProviderKey": "IdentityApiKey", "AllowedScopes": [] @@ -23,8 +47,12 @@ { "DownstreamPathTemplate": "/{everything}", "DownstreamScheme": "http", - "DownstreamHost": "purchasebff", - "DownstreamPort": 80, + "DownstreamHostAndPorts": [ + { + "Host": "purchasebff", + "Port": 80 + } + ], "UpstreamPathTemplate": "/purchase-bff/{everything}", "UpstreamHttpMethod": [ "POST", "PUT", "GET" ], "AuthenticationOptions": { @@ -35,48 +63,72 @@ { "DownstreamPathTemplate": "/{everything}", "DownstreamScheme": "http", - "DownstreamHost": "ordering.api", - "DownstreamPort": 80, + "DownstreamHostAndPorts": [ + { + "Host": "ordering.api", + "Port": 80 + } + ], "UpstreamPathTemplate": "/orders-api/{everything}", "UpstreamHttpMethod": [] }, { "DownstreamPathTemplate": "/{everything}", "DownstreamScheme": "http", - "DownstreamHost": "basket.api", - "DownstreamPort": 80, + "DownstreamHostAndPorts": [ + { + "Host": "basket.api", + "Port": 80 + } + ], "UpstreamPathTemplate": "/basket-api/{everything}", "UpstreamHttpMethod": [] }, { "DownstreamPathTemplate": "/{everything}", "DownstreamScheme": "http", - "DownstreamHost": "catalog.api", - "DownstreamPort": 80, + "DownstreamHostAndPorts": [ + { + "Host": "catalog.api", + "Port": 80 + } + ], "UpstreamPathTemplate": "/catalog-api/{everything}", "UpstreamHttpMethod": [] }, { "DownstreamPathTemplate": "/{everything}", "DownstreamScheme": "http", - "DownstreamHost": "marketing.api", - "DownstreamPort": 80, + "DownstreamHostAndPorts": [ + { + "Host": "marketing.api", + "Port": 80 + } + ], "UpstreamPathTemplate": "/marketing-api/{everything}", "UpstreamHttpMethod": [] }, { "DownstreamPathTemplate": "/{everything}", "DownstreamScheme": "http", - "DownstreamHost": "payment.api", - "DownstreamPort": 80, + "DownstreamHostAndPorts": [ + { + "Host": "payment.api", + "Port": 80 + } + ], "UpstreamPathTemplate": "/payment-api/{everything}", "UpstreamHttpMethod": [] }, { "DownstreamPathTemplate": "/{everything}", "DownstreamScheme": "http", - "DownstreamHost": "locations.api", - "DownstreamPort": 80, + "DownstreamHostAndPorts": [ + { + "Host": "locations.api", + "Port": 80 + } + ], "UpstreamPathTemplate": "/location-api/{everything}", "UpstreamHttpMethod": [] } diff --git a/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs b/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs index 18051a501..9fa38ee8d 100644 --- a/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs +++ b/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs @@ -97,6 +97,11 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http throw new HttpRequestException(); } + if (!response.IsSuccessStatusCode) + { + return null; + } + return await response.Content.ReadAsStringAsync(); }); } diff --git a/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs b/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs index a5f6a63c4..578168bff 100644 --- a/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs +++ b/src/BuildingBlocks/Resilience/Resilience.Http/StandardHttpClient.cs @@ -36,6 +36,11 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http var response = await _client.SendAsync(requestMessage); + if (!response.IsSuccessStatusCode) + { + return null; + } + return await response.Content.ReadAsStringAsync(); } diff --git a/src/Services/Basket/Basket.API/Controllers/BasketController.cs b/src/Services/Basket/Basket.API/Controllers/BasketController.cs index 11ecac7c2..48ad68903 100644 --- a/src/Services/Basket/Basket.API/Controllers/BasketController.cs +++ b/src/Services/Basket/Basket.API/Controllers/BasketController.cs @@ -34,6 +34,10 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers public async Task Get(string id) { var basket = await _repository.GetBasketAsync(id); + if (basket == null) + { + return NotFound(); + } return Ok(basket); } diff --git a/src/Web/WebMVC/AppSettings.cs b/src/Web/WebMVC/AppSettings.cs index 18db7d4bf..d235910b0 100644 --- a/src/Web/WebMVC/AppSettings.cs +++ b/src/Web/WebMVC/AppSettings.cs @@ -8,9 +8,6 @@ namespace Microsoft.eShopOnContainers.WebMVC public class AppSettings { public Connectionstrings ConnectionStrings { get; set; } - public string CatalogUrl { get; set; } - public string OrderingUrl { get; set; } - public string BasketUrl { get; set; } public string MarketingUrl { get; set; } public string LocationsUrl { get; set; } diff --git a/src/Web/WebMVC/Services/BasketService.cs b/src/Web/WebMVC/Services/BasketService.cs index 208ea71ad..54287a796 100644 --- a/src/Web/WebMVC/Services/BasketService.cs +++ b/src/Web/WebMVC/Services/BasketService.cs @@ -16,7 +16,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services { private readonly IOptionsSnapshot _settings; private readonly IHttpClient _apiClient; - private readonly string _remoteServiceBaseUrl; + private readonly string _basketByPassUrl; private readonly string _purchaseUrl; private readonly IHttpContextAccessor _httpContextAccesor; @@ -26,7 +26,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services IHttpContextAccessor httpContextAccesor, IHttpClient httpClient) { _settings = settings; - _remoteServiceBaseUrl = $"{_settings.Value.BasketUrl}/api/v1/basket"; + _basketByPassUrl = $"{_settings.Value.PurchaseUrl}/api/v1/b/basket"; _purchaseUrl = $"{_settings.Value.PurchaseUrl}/api/v1"; _httpContextAccesor = httpContextAccesor; _apiClient = httpClient; @@ -35,24 +35,19 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public async Task GetBasket(ApplicationUser user) { var token = await GetUserTokenAsync(); - var getBasketUri = API.Basket.GetBasket(_remoteServiceBaseUrl, user.Id); + var getBasketUri = API.Basket.GetBasket(_basketByPassUrl, user.Id); var dataString = await _apiClient.GetStringAsync(getBasketUri, token); - // Use the ?? Null conditional operator to simplify the initialization of response - var response = JsonConvert.DeserializeObject(dataString) ?? - new Basket() - { - BuyerId = user.Id - }; - - return response; + return string.IsNullOrEmpty(dataString) ? + new Basket() { BuyerId = user.Id} : + JsonConvert.DeserializeObject(dataString); } public async Task UpdateBasket(Basket basket) { var token = await GetUserTokenAsync(); - var updateBasketUri = API.Basket.UpdateBasket(_remoteServiceBaseUrl); + var updateBasketUri = API.Basket.UpdateBasket(_basketByPassUrl); var response = await _apiClient.PostAsync(updateBasketUri, basket, token); @@ -64,7 +59,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public async Task Checkout(BasketDTO basket) { var token = await GetUserTokenAsync(); - var updateBasketUri = API.Basket.CheckoutBasket(_remoteServiceBaseUrl); + var updateBasketUri = API.Basket.CheckoutBasket(_basketByPassUrl); var response = await _apiClient.PostAsync(updateBasketUri, basket, token); diff --git a/src/Web/WebMVC/Services/CatalogService.cs b/src/Web/WebMVC/Services/CatalogService.cs index 2af428e2e..5b6fbe26b 100644 --- a/src/Web/WebMVC/Services/CatalogService.cs +++ b/src/Web/WebMVC/Services/CatalogService.cs @@ -25,7 +25,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services _apiClient = httpClient; _logger = logger; - _remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/"; + _remoteServiceBaseUrl = $"{_settings.Value.PurchaseUrl}/api/v1/c/catalog/"; } public async Task GetCatalogItems(int page, int take, int? brand, int? type) diff --git a/src/Web/WebMVC/Services/OrderingService.cs b/src/Web/WebMVC/Services/OrderingService.cs index f36f1410d..ec9d2e8fd 100644 --- a/src/Web/WebMVC/Services/OrderingService.cs +++ b/src/Web/WebMVC/Services/OrderingService.cs @@ -21,7 +21,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public OrderingService(IOptionsSnapshot settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient) { - _remoteServiceBaseUrl = $"{settings.Value.OrderingUrl}/api/v1/orders"; + _remoteServiceBaseUrl = $"{settings.Value.PurchaseUrl}/api/v1/o/orders"; _settings = settings; _httpContextAccesor = httpContextAccesor; _apiClient = httpClient;