add grpc basket
This commit is contained in:
parent
568dabcea0
commit
fe0fd36e0f
@ -219,6 +219,7 @@ services:
|
||||
- MarketingUrlHC=http://marketing.api/hc
|
||||
- PaymentUrlHC=http://payment.api/hc
|
||||
- LocationUrlHC=http://locations.api/hc
|
||||
- IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
|
||||
ports:
|
||||
- "5200:80"
|
||||
volumes:
|
||||
@ -235,6 +236,7 @@ services:
|
||||
- MarketingUrlHC=http://marketing.api/hc
|
||||
- PaymentUrlHC=http://payment.api/hc
|
||||
- LocationUrlHC=http://locations.api/hc
|
||||
- IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
|
||||
ports:
|
||||
- "5201:80"
|
||||
volumes:
|
||||
@ -251,6 +253,7 @@ services:
|
||||
- MarketingUrlHC=http://marketing.api/hc
|
||||
- PaymentUrlHC=http://payment.api/hc
|
||||
- LocationUrlHC=http://locations.api/hc
|
||||
- IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
|
||||
ports:
|
||||
- "5202:80"
|
||||
volumes:
|
||||
@ -267,6 +270,7 @@ services:
|
||||
- MarketingUrlHC=http://marketing.api/hc
|
||||
- PaymentUrlHC=http://payment.api/hc
|
||||
- LocationUrlHC=http://locations.api/hc
|
||||
- IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
|
||||
ports:
|
||||
- "5203:80"
|
||||
volumes:
|
||||
@ -286,6 +290,7 @@ services:
|
||||
- MarketingUrlHC=http://marketing.api/hc
|
||||
- PaymentUrlHC=http://payment.api/hc
|
||||
- LocationUrlHC=http://locations.api/hc
|
||||
- IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
|
||||
ports:
|
||||
- "5120:80"
|
||||
|
||||
@ -303,6 +308,7 @@ services:
|
||||
- MarketingUrlHC=http://marketing.api/hc
|
||||
- PaymentUrlHC=http://payment.api/hc
|
||||
- LocationUrlHC=http://locations.api/hc
|
||||
- IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
|
||||
ports:
|
||||
- "5121:80"
|
||||
|
||||
|
@ -3,7 +3,6 @@ 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;
|
||||
@ -36,7 +35,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
|
||||
}
|
||||
|
||||
// Retrieve the current basket
|
||||
var basket = await _basket.GetByIdAsync(data.BuyerId) ?? new BasketData(data.BuyerId);
|
||||
var basket = await _basket.GetById(data.BuyerId) ?? new BasketData(data.BuyerId);
|
||||
|
||||
var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId));
|
||||
|
||||
@ -76,7 +75,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
|
||||
}
|
||||
|
||||
// Retrieve the current basket
|
||||
var currentBasket = await _basket.GetByIdAsync(data.BasketId);
|
||||
var currentBasket = await _basket.GetById(data.BasketId);
|
||||
if (currentBasket == null)
|
||||
{
|
||||
return BadRequest($"Basket with id {data.BasketId} not found.");
|
||||
@ -118,7 +117,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
|
||||
//item.PictureUri =
|
||||
|
||||
// Step 2: Get current basket status
|
||||
var currentBasket = (await _basket.GetByIdAsync(data.BasketId)) ?? new BasketData(data.BasketId);
|
||||
var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId);
|
||||
// Step 3: Merge current status with new product
|
||||
currentBasket.Items.Add(new BasketDataItem()
|
||||
{
|
||||
|
@ -32,7 +32,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
|
||||
return BadRequest("Need a valid basketid");
|
||||
}
|
||||
// Get the basket data and build a order draft based on it
|
||||
var basket = await _basketService.GetByIdAsync(basketId);
|
||||
var basket = await _basketService.GetById(basketId);
|
||||
|
||||
if (basket == null)
|
||||
{
|
||||
|
@ -1,8 +1,8 @@
|
||||
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
|
||||
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
|
||||
FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
|
||||
WORKDIR /src
|
||||
|
||||
COPY scripts scripts/
|
||||
|
@ -1,7 +1,7 @@
|
||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters
|
||||
{
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Swashbuckle.AspNetCore.Swagger;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -10,7 +10,7 @@
|
||||
{
|
||||
public class AuthorizeCheckOperationFilter : IOperationFilter
|
||||
{
|
||||
public void Apply(Operation operation, OperationFilterContext context)
|
||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||
{
|
||||
// Check for authorize attribute
|
||||
var hasAuthorize = context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any() ||
|
||||
@ -18,14 +18,19 @@
|
||||
|
||||
if (!hasAuthorize) return;
|
||||
|
||||
operation.Responses.TryAdd("401", new Response { Description = "Unauthorized" });
|
||||
operation.Responses.TryAdd("403", new Response { Description = "Forbidden" });
|
||||
operation.Responses.TryAdd("401", new OpenApiResponse { Description = "Unauthorized" });
|
||||
operation.Responses.TryAdd("403", new OpenApiResponse { Description = "Forbidden" });
|
||||
|
||||
operation.Security = new List<IDictionary<string, IEnumerable<string>>>
|
||||
var oAuthScheme = new OpenApiSecurityScheme
|
||||
{
|
||||
new Dictionary<string, IEnumerable<string>>
|
||||
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
|
||||
};
|
||||
|
||||
operation.Security = new List<OpenApiSecurityRequirement>
|
||||
{
|
||||
{ "oauth2", new [] { "Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator" } }
|
||||
new OpenApiSecurityRequirement
|
||||
{
|
||||
[ oAuthScheme ] = new [] { "Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator" }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
@ -8,18 +9,22 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure
|
||||
{
|
||||
public class HttpClientAuthorizationDelegatingHandler
|
||||
: DelegatingHandler
|
||||
public class HttpClientAuthorizationDelegatingHandler : DelegatingHandler
|
||||
{
|
||||
private readonly IHttpContextAccessor _httpContextAccesor;
|
||||
private readonly ILogger<HttpClientAuthorizationDelegatingHandler> _logger;
|
||||
|
||||
public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccesor)
|
||||
public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccesor, ILogger<HttpClientAuthorizationDelegatingHandler> logger)
|
||||
{
|
||||
_httpContextAccesor = httpContextAccesor;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
request.Version = new System.Version(2, 0);
|
||||
request.Method = HttpMethod.Get;
|
||||
|
||||
var authorizationHeader = _httpContextAccesor.HttpContext
|
||||
.Request.Headers["Authorization"];
|
||||
|
||||
@ -35,6 +40,8 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastruct
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
}
|
||||
|
||||
_logger.LogInformation("@@@@@@@@@@@@@@@@@ {@request}", request);
|
||||
|
||||
return await base.SendAsync(request, cancellationToken);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!--<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(NetCoreTargetVersion)</TargetFramework>
|
||||
@ -17,6 +17,10 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Uris" Version="$(AspNetCore_HealthChecks_Uris)" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="$(AspNetCore_HealthChecks_UI_Client)" />
|
||||
<PackageReference Include="Grpc.AspNetCore.Server.ClientFactory" Version="$(Grpc_AspNetCore_Server_ClientFactory)" />
|
||||
<PackageReference Include="Google.Protobuf" Version="$(Google_Protobuf)" />
|
||||
<PackageReference Include="Grpc.Core" Version="1.22.0" />
|
||||
<PackageReference Include="Grpc.Tools" Version="$(Grpc_Tools)" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="$(Microsoft_AspNetCore_Diagnostics_HealthChecks)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="$(Microsoft_Extensions_Diagnostics_HealthChecks)" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="$(Serilog_AspNetCore)" />
|
||||
@ -24,41 +28,16 @@
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="$(Swashbuckle_AspNetCore)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="$(Microsoft_Extensions_Http_Polly)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(Microsoft_AspNetCore_Authentication_JwtBearer)" />
|
||||
<PackageReference Include="System.Net.Http.WinHttpHandler" Version="4.5.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\BuildingBlocks\Devspaces.Support\Devspaces.Support.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>-->
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<AssemblyName>Mobile.Shopping.HttpAggregator</AssemblyName>
|
||||
<RootNamespace>Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator</RootNamespace>
|
||||
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Uris" Version="2.2.2" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="2.2.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\BuildingBlocks\Devspaces.Support\Devspaces.Support.csproj" />
|
||||
<Protobuf Include="..\..\..\Services\Basket\Basket.API\Proto\basket.proto" GrpcServices="Client" />
|
||||
<Protobuf Include="..\..\..\Services\Catalog\Catalog.API\Proto\catalog.proto" GrpcServices="Client" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -1,13 +1,21 @@
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Serilog;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
private static IConfiguration _configuration;
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
_configuration = GetConfiguration();
|
||||
|
||||
BuildWebHost(args).Run();
|
||||
}
|
||||
|
||||
@ -24,6 +32,20 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
|
||||
ReloadOnChange = false
|
||||
});
|
||||
})
|
||||
.ConfigureKestrel(options =>
|
||||
{
|
||||
var ports = GetDefinedPorts(_configuration);
|
||||
|
||||
options.Listen(IPAddress.Any, ports.httpPort, listenOptions =>
|
||||
{
|
||||
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
|
||||
});
|
||||
|
||||
options.Listen(IPAddress.Any, ports.grpcPort, listenOptions =>
|
||||
{
|
||||
listenOptions.Protocols = HttpProtocols.Http2;
|
||||
});
|
||||
})
|
||||
.UseStartup<Startup>()
|
||||
.UseSerilog((builderContext, config) =>
|
||||
{
|
||||
@ -33,5 +55,24 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
|
||||
.WriteTo.Console();
|
||||
})
|
||||
.Build();
|
||||
|
||||
private static IConfiguration GetConfiguration()
|
||||
{
|
||||
var builder = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
|
||||
.AddEnvironmentVariables();
|
||||
|
||||
var config = builder.Build();
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
private static (int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config)
|
||||
{
|
||||
var grpcPort = config.GetValue("GRPC_PORT", 5001);
|
||||
var port = config.GetValue("PORT", 80);
|
||||
return (port, grpcPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +1,130 @@
|
||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
||||
using grpc;
|
||||
using Grpc.Net.Client;
|
||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using static grpc.Basket;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
||||
{
|
||||
public class BasketService : IBasketService
|
||||
{
|
||||
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly ILogger<BasketService> _logger;
|
||||
private readonly UrlsConfig _urls;
|
||||
private readonly ILogger<BasketService> _logger;
|
||||
|
||||
public BasketService(HttpClient httpClient, ILogger<BasketService> logger, IOptions<UrlsConfig> config)
|
||||
public BasketService(HttpClient httpClient, IOptions<UrlsConfig> config, ILogger<BasketService> logger)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_logger = logger;
|
||||
_urls = config.Value;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<BasketData> GetByIdAsync(string id)
|
||||
public async Task<BasketData> GetById(string id)
|
||||
{
|
||||
var data = await _httpClient.GetStringAsync(_urls.Basket + UrlsConfig.BasketOperations.GetItemById(id));
|
||||
_logger.LogInformation("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GetById @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
|
||||
var basket = !string.IsNullOrEmpty(data) ? JsonConvert.DeserializeObject<BasketData>(data) : null;
|
||||
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
|
||||
|
||||
return basket;
|
||||
_logger.LogInformation("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Http2UnencryptedSupport disable @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
|
||||
_httpClient.BaseAddress = new Uri("http://localhost:5001");
|
||||
|
||||
_logger.LogInformation("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ {_httpClient.BaseAddress} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", _httpClient.BaseAddress);
|
||||
|
||||
var client = GrpcClient.Create<BasketClient>(_httpClient);
|
||||
|
||||
_logger.LogInformation("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ client create @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
|
||||
var response = await client.GetBasketByIdAsync(new BasketRequest { Id = id });
|
||||
|
||||
_logger.LogInformation("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ call grpc server @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
|
||||
_logger.LogInformation("############## DATA: {@a}", response.Buyerid);
|
||||
|
||||
//if (streaming.IsCompleted)
|
||||
//{
|
||||
// _logger.LogInformation("############## DATA: {@a}", streaming.GetResult());
|
||||
//}
|
||||
//var streaming = client.GetBasketById(new BasketRequest { Id = id });
|
||||
|
||||
|
||||
//var status = streaming.GetStatus();
|
||||
|
||||
//if (status.StatusCode == Grpc.Core.StatusCode.OK)
|
||||
//{
|
||||
// return null;
|
||||
//}
|
||||
|
||||
return null;
|
||||
//return MapToBasketData(response.ResponseStream);
|
||||
}
|
||||
|
||||
public async Task UpdateAsync(BasketData currentBasket)
|
||||
{
|
||||
var basketContent = new StringContent(JsonConvert.SerializeObject(currentBasket), System.Text.Encoding.UTF8, "application/json");
|
||||
_httpClient.BaseAddress = new Uri(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket());
|
||||
|
||||
var data = await _httpClient.PostAsync(_urls.Basket + UrlsConfig.BasketOperations.UpdateBasket(), basketContent);
|
||||
var client = GrpcClient.Create<BasketClient>(_httpClient);
|
||||
var request = MapToCustomerBasketRequest(currentBasket);
|
||||
|
||||
await client.UpdateBasketAsync(request);
|
||||
}
|
||||
|
||||
private BasketData MapToBasketData(CustomerBasketResponse customerBasketRequest)
|
||||
{
|
||||
if (customerBasketRequest == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var map = new BasketData
|
||||
{
|
||||
BuyerId = customerBasketRequest.Buyerid
|
||||
};
|
||||
|
||||
customerBasketRequest.Items.ToList().ForEach(item => map.Items.Add(new BasketDataItem
|
||||
{
|
||||
Id = item.Id,
|
||||
OldUnitPrice = (decimal)item.Oldunitprice,
|
||||
PictureUrl = item.Pictureurl,
|
||||
ProductId = item.Productid,
|
||||
ProductName = item.Productname,
|
||||
Quantity = item.Quantity,
|
||||
UnitPrice = (decimal)item.Unitprice
|
||||
}));
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private CustomerBasketRequest MapToCustomerBasketRequest(BasketData basketData)
|
||||
{
|
||||
if (basketData == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var map = new CustomerBasketRequest
|
||||
{
|
||||
Buyerid = basketData.BuyerId
|
||||
};
|
||||
|
||||
basketData.Items.ToList().ForEach(item => map.Items.Add(new BasketItemResponse
|
||||
{
|
||||
Id = item.Id,
|
||||
Oldunitprice = (double)item.OldUnitPrice,
|
||||
Pictureurl = item.PictureUrl,
|
||||
Productid = item.ProductId,
|
||||
Productname = item.ProductName,
|
||||
Quantity = item.Quantity,
|
||||
Unitprice = (double)item.UnitPrice
|
||||
}));
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,33 +1,37 @@
|
||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
||||
using CatalogApi;
|
||||
using Grpc.Net.Client;
|
||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using static CatalogApi.Catalog;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
||||
{
|
||||
public class CatalogService : ICatalogService
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly ILogger<CatalogService> _logger;
|
||||
private readonly UrlsConfig _urls;
|
||||
|
||||
public CatalogService(HttpClient httpClient, ILogger<CatalogService> logger, IOptions<UrlsConfig> config)
|
||||
public CatalogService(HttpClient httpClient, IOptions<UrlsConfig> config)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_logger = logger;
|
||||
_urls = config.Value;
|
||||
}
|
||||
|
||||
public async Task<CatalogItem> GetCatalogItemAsync(int id)
|
||||
{
|
||||
var stringContent = await _httpClient.GetStringAsync(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id));
|
||||
var catalogItem = JsonConvert.DeserializeObject<CatalogItem>(stringContent);
|
||||
_httpClient.BaseAddress = new Uri(_urls.Catalog + UrlsConfig.CatalogOperations.GetItemById(id));
|
||||
|
||||
return catalogItem;
|
||||
var client = GrpcClient.Create<CatalogClient>(_httpClient);
|
||||
var request = new CatalogItemRequest { Id = id };
|
||||
var response = await client.GetItemByIdAsync(request);
|
||||
|
||||
return MapToCatalogItemResponse(response);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids)
|
||||
@ -37,5 +41,16 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
||||
|
||||
return catalogItems;
|
||||
}
|
||||
|
||||
private CatalogItem MapToCatalogItemResponse(CatalogItemResponse catalogItemResponse)
|
||||
{
|
||||
return new CatalogItem
|
||||
{
|
||||
Id = catalogItemResponse.Id,
|
||||
Name = catalogItemResponse.Name,
|
||||
PictureUri = catalogItemResponse.PictureUri,
|
||||
Price = (decimal)catalogItemResponse.Price
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
||||
{
|
||||
public interface IBasketService
|
||||
{
|
||||
Task<BasketData> GetByIdAsync(string id);
|
||||
Task<BasketData> GetById(string id);
|
||||
|
||||
Task UpdateAsync(BasketData currentBasket);
|
||||
|
||||
|
@ -5,7 +5,6 @@ using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
||||
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;
|
||||
@ -14,9 +13,9 @@ using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Polly;
|
||||
using Polly.Extensions.Http;
|
||||
using Swashbuckle.AspNetCore.Swagger;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
@ -63,19 +62,6 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
|
||||
app.UsePathBase(pathBase);
|
||||
}
|
||||
|
||||
app.UseHealthChecks("/hc", new HealthCheckOptions()
|
||||
{
|
||||
Predicate = _ => true,
|
||||
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
|
||||
});
|
||||
|
||||
app.UseHealthChecks("/liveness", new HealthCheckOptions
|
||||
{
|
||||
Predicate = r => r.Name.Contains("self")
|
||||
});
|
||||
|
||||
app.UseCors("CorsPolicy");
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
@ -86,15 +72,31 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseCors("CorsPolicy");
|
||||
app.UseHttpsRedirection();
|
||||
app.UseMvc();
|
||||
app.UseRouting();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapHealthChecks("/hc", new HealthCheckOptions()
|
||||
{
|
||||
Predicate = _ => true,
|
||||
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
|
||||
});
|
||||
endpoints.MapHealthChecks("/liveness", new HealthCheckOptions
|
||||
{
|
||||
Predicate = r => r.Name.Contains("self")
|
||||
});
|
||||
});
|
||||
|
||||
app.UseSwagger().UseSwaggerUI(c =>
|
||||
{
|
||||
c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1");
|
||||
|
||||
c.OAuthClientId("Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregatorwaggerui");
|
||||
c.OAuthClientId("mobileshoppingaggswaggerui");
|
||||
c.OAuthClientSecret(string.Empty);
|
||||
c.OAuthRealm(string.Empty);
|
||||
c.OAuthAppName("Purchase BFF Swagger UI");
|
||||
@ -109,30 +111,33 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
|
||||
services.AddOptions();
|
||||
services.Configure<UrlsConfig>(configuration.GetSection("urls"));
|
||||
|
||||
services.AddMvc()
|
||||
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
|
||||
services.AddControllers()
|
||||
.AddNewtonsoftJson();
|
||||
|
||||
services.AddSwaggerGen(options =>
|
||||
{
|
||||
options.DescribeAllEnumsAsStrings();
|
||||
options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
|
||||
options.SwaggerDoc("v1", new OpenApiInfo
|
||||
{
|
||||
Title = "Shopping Aggregator for Mobile Clients",
|
||||
Version = "v1",
|
||||
Description = "Shopping Aggregator for Mobile Clients",
|
||||
TermsOfService = "Terms Of Service"
|
||||
Description = "Shopping Aggregator for Mobile Clients"
|
||||
});
|
||||
|
||||
options.AddSecurityDefinition("oauth2", new OAuth2Scheme
|
||||
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
|
||||
{
|
||||
Type = "oauth2",
|
||||
Flow = "implicit",
|
||||
AuthorizationUrl = $"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/authorize",
|
||||
TokenUrl = $"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/token",
|
||||
Type = SecuritySchemeType.OAuth2,
|
||||
Flows = new OpenApiOAuthFlows()
|
||||
{
|
||||
Implicit = new OpenApiOAuthFlow()
|
||||
{
|
||||
AuthorizationUrl = new Uri($"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/authorize"),
|
||||
TokenUrl = new Uri($"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/token"),
|
||||
Scopes = new Dictionary<string, string>()
|
||||
{
|
||||
{ "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
options.OperationFilter<AuthorizeCheckOperationFilter>();
|
||||
@ -152,7 +157,8 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
|
||||
}
|
||||
public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");
|
||||
|
||||
var identityUrl = configuration.GetValue<string>("urls:identity");
|
||||
|
||||
services.AddAuthentication(options =>
|
||||
@ -166,15 +172,6 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
|
||||
options.Authority = identityUrl;
|
||||
options.RequireHttpsMetadata = false;
|
||||
options.Audience = "mobileshoppingagg";
|
||||
options.Events = new JwtBearerEvents()
|
||||
{
|
||||
OnAuthenticationFailed = async ctx =>
|
||||
{
|
||||
},
|
||||
OnTokenValidated = async ctx =>
|
||||
{
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
return services;
|
||||
|
@ -1,4 +1,9 @@
|
||||
{
|
||||
"Kestrel": {
|
||||
"EndpointDefaults": {
|
||||
"Protocols": "Http2"
|
||||
}
|
||||
},
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"Debug": {
|
||||
|
@ -4,5 +4,20 @@
|
||||
"catalog": "http://localhost:55101",
|
||||
"orders": "http://localhost:55102",
|
||||
"identity": "http://localhost:55105"
|
||||
},
|
||||
"IdentityUrlExternal": "http://localhost:5105",
|
||||
"IdentityUrl": "http://localhost:5105",
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"Debug": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug"
|
||||
}
|
||||
},
|
||||
"Console": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,9 @@
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Redis" Version="$(AspNetCore_HealthChecks_Redis)" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="$(AspNetCore_HealthChecks_UI_Client)" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="$(Autofac_Extensions_DependencyInjection)" />
|
||||
<PackageReference Include="Grpc.AspNetCore.Server" Version="$(Grpc_AspNetCore_Server)" />
|
||||
<PackageReference Include="Google.Protobuf" Version="$(Google_Protobuf)" />
|
||||
<PackageReference Include="Grpc.Tools" Version="$(Grpc_Tools)" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="$(Microsoft_ApplicationInsights_AspNetCore)" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="$(Microsoft_ApplicationInsights_DependencyCollector)" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="$(Microsoft_ApplicationInsights_Kubernetes)" />
|
||||
@ -39,6 +42,12 @@
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="$(Swashbuckle_AspNetCore)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="Proto\basket.proto" GrpcServices="Server" Generator="MSBuild:Compile" />
|
||||
<Content Include="@(Protobuf)" />
|
||||
<None Remove="@(Protobuf)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
|
||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" />
|
||||
|
100
src/Services/Basket/Basket.API/Grpc/BasketService.cs
Normal file
100
src/Services/Basket/Basket.API/Grpc/BasketService.cs
Normal file
@ -0,0 +1,100 @@
|
||||
using Grpc.Core;
|
||||
using Microsoft.eShopOnContainers.Services.Basket.API.Model;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace grpc
|
||||
{
|
||||
public class BasketService : Basket.BasketBase
|
||||
{
|
||||
private readonly IBasketRepository _repository;
|
||||
private readonly ILogger<BasketService> _logger;
|
||||
|
||||
public BasketService(IBasketRepository repository, ILogger<BasketService> logger)
|
||||
{
|
||||
_repository = repository;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override async Task<CustomerBasketResponse> GetBasketById(BasketRequest request, ServerCallContext context)
|
||||
{
|
||||
_logger.LogInformation($"Begin grpc call from method {context.Method} for basket id {request.Id}");
|
||||
|
||||
var data = await _repository.GetBasketAsync(request.Id);
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
context.Status = new Status(StatusCode.OK, $"Basket with id {request.Id} do exist");
|
||||
|
||||
return MapToCustomerBasketResponse(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Status = new Status(StatusCode.NotFound, $"Basket with id {request.Id} do not exist");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override async Task<CustomerBasketResponse> UpdateBasket(CustomerBasketRequest request, ServerCallContext context)
|
||||
{
|
||||
_logger.LogInformation($"Begin grpc call BasketService.UpdateBasketAsync for buyer id {request.Buyerid}");
|
||||
|
||||
var customerBasket = MapToCustomerBasket(request);
|
||||
|
||||
var response = await _repository.UpdateBasketAsync(customerBasket);
|
||||
|
||||
if (response != null)
|
||||
{
|
||||
return MapToCustomerBasketResponse(response);
|
||||
}
|
||||
|
||||
context.Status = new Status(StatusCode.NotFound, $"Basket with buyer id {request.Buyerid} do not exist");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private CustomerBasketResponse MapToCustomerBasketResponse(CustomerBasket customerBasket)
|
||||
{
|
||||
var response = new CustomerBasketResponse
|
||||
{
|
||||
Buyerid = customerBasket.BuyerId
|
||||
};
|
||||
|
||||
customerBasket.Items.ForEach(item => response.Items.Add(new BasketItemResponse
|
||||
{
|
||||
Id = item.Id,
|
||||
Oldunitprice = (double)item.OldUnitPrice,
|
||||
Pictureurl = item.PictureUrl,
|
||||
Productid = item.ProductId,
|
||||
Productname = item.ProductName,
|
||||
Quantity = item.Quantity,
|
||||
Unitprice = (double)item.UnitPrice
|
||||
}));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private CustomerBasket MapToCustomerBasket(CustomerBasketRequest customerBasketRequest)
|
||||
{
|
||||
var response = new CustomerBasket
|
||||
{
|
||||
BuyerId = customerBasketRequest.Buyerid
|
||||
};
|
||||
|
||||
customerBasketRequest.Items.ToList().ForEach(item => response.Items.Add(new BasketItem
|
||||
{
|
||||
Id = item.Id,
|
||||
OldUnitPrice = (decimal)item.Oldunitprice,
|
||||
PictureUrl = item.Pictureurl,
|
||||
ProductId = item.Productid,
|
||||
ProductName = item.Productname,
|
||||
Quantity = item.Quantity,
|
||||
UnitPrice = (decimal)item.Unitprice
|
||||
}));
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,11 +2,12 @@
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
{
|
||||
@ -45,8 +46,21 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
private static IWebHost BuildWebHost(IConfiguration configuration, string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.CaptureStartupErrors(false)
|
||||
.UseFailing(options =>
|
||||
options.ConfigPath = "/Failing")
|
||||
.ConfigureKestrel(options =>
|
||||
{
|
||||
var ports = GetDefinedPorts(configuration);
|
||||
|
||||
options.Listen(IPAddress.Any, ports.httpPort, listenOptions =>
|
||||
{
|
||||
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
|
||||
});
|
||||
|
||||
options.Listen(IPAddress.Any, ports.grpcPort, listenOptions =>
|
||||
{
|
||||
listenOptions.Protocols = HttpProtocols.Http2;
|
||||
});
|
||||
})
|
||||
.UseFailing(options => options.ConfigPath = "/Failing")
|
||||
.UseStartup<Startup>()
|
||||
.UseApplicationInsights()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
@ -88,5 +102,12 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
private static (int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config)
|
||||
{
|
||||
var grpcPort = config.GetValue("GRPC_PORT", 5001);
|
||||
var port = config.GetValue("PORT", 80);
|
||||
return (port, grpcPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
38
src/Services/Basket/Basket.API/Proto/basket.proto
Normal file
38
src/Services/Basket/Basket.API/Proto/basket.proto
Normal file
@ -0,0 +1,38 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option csharp_namespace = "grpc";
|
||||
|
||||
package BasketApi;
|
||||
|
||||
service Basket {
|
||||
rpc GetBasketById(BasketRequest) returns (CustomerBasketResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/GetBasketById"
|
||||
};
|
||||
}
|
||||
rpc UpdateBasket(CustomerBasketRequest) returns (CustomerBasketResponse) {}
|
||||
}
|
||||
|
||||
message BasketRequest {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message CustomerBasketRequest {
|
||||
string buyerid = 1;
|
||||
repeated BasketItemResponse items = 2;
|
||||
}
|
||||
|
||||
message CustomerBasketResponse {
|
||||
string buyerid = 1;
|
||||
repeated BasketItemResponse items = 2;
|
||||
}
|
||||
|
||||
message BasketItemResponse {
|
||||
string id = 1;
|
||||
string productid = 2;
|
||||
string productname = 3;
|
||||
double unitprice = 4;
|
||||
double oldunitprice = 5;
|
||||
int32 quantity = 6;
|
||||
string pictureurl = 7;
|
||||
}
|
@ -4,6 +4,7 @@ using Basket.API.Infrastructure.Filters;
|
||||
using Basket.API.Infrastructure.Middlewares;
|
||||
using Basket.API.IntegrationEvents.EventHandling;
|
||||
using Basket.API.IntegrationEvents.Events;
|
||||
using grpc;
|
||||
using HealthChecks.UI.Client;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
@ -32,6 +33,7 @@ using StackExchange.Redis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.IO;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
{
|
||||
@ -47,6 +49,11 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public virtual IServiceProvider ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddGrpc(options =>
|
||||
{
|
||||
options.EnableDetailedErrors = true;
|
||||
});
|
||||
|
||||
RegisterAppInsights(services);
|
||||
|
||||
services.AddControllers(options =>
|
||||
@ -88,7 +95,6 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
options.OperationFilter<AuthorizeCheckOperationFilter>();
|
||||
});
|
||||
|
||||
|
||||
ConfigureAuthService(services);
|
||||
|
||||
services.AddCustomHealthCheck(Configuration);
|
||||
@ -192,6 +198,14 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
app.UsePathBase(pathBase);
|
||||
}
|
||||
|
||||
app.UseSwagger()
|
||||
.UseSwaggerUI(setup =>
|
||||
{
|
||||
setup.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Basket.API V1");
|
||||
setup.OAuthClientId("basketswaggerui");
|
||||
setup.OAuthAppName("Basket Swagger UI");
|
||||
});
|
||||
|
||||
app.UseRouting();
|
||||
ConfigureAuth(app);
|
||||
|
||||
@ -202,6 +216,21 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
{
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapGet("/_proto/", async ctx =>
|
||||
{
|
||||
ctx.Response.ContentType = "text/plain";
|
||||
using var fs = new FileStream(Path.Combine(env.ContentRootPath, "Proto", "basket.proto"), FileMode.Open, FileAccess.Read);
|
||||
using var sr = new StreamReader(fs);
|
||||
while (!sr.EndOfStream)
|
||||
{
|
||||
var line = await sr.ReadLineAsync();
|
||||
if (line != "/* >>" || line != "<< */")
|
||||
{
|
||||
await ctx.Response.WriteAsync(line);
|
||||
}
|
||||
}
|
||||
});
|
||||
endpoints.MapGrpcService<BasketService>();
|
||||
endpoints.MapHealthChecks("/hc", new HealthCheckOptions()
|
||||
{
|
||||
Predicate = _ => true,
|
||||
@ -213,15 +242,6 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
});
|
||||
});
|
||||
|
||||
app.UseSwagger()
|
||||
.UseSwaggerUI(setup =>
|
||||
{
|
||||
setup.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Basket.API V1");
|
||||
setup.OAuthClientId("basketswaggerui");
|
||||
setup.OAuthAppName("Basket Swagger UI");
|
||||
});
|
||||
|
||||
|
||||
ConfigureEventBus(app);
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Kestrel": {
|
||||
"EndpointDefaults": {
|
||||
"Protocols": "Http2"
|
||||
}
|
||||
},
|
||||
"SubscriptionClientName": "Basket",
|
||||
"ApplicationInsights": {
|
||||
"InstrumentationKey": ""
|
||||
|
@ -19,6 +19,7 @@
|
||||
<Grpc_AspNetCore_Server>0.1.22-pre1</Grpc_AspNetCore_Server>
|
||||
<Google_Protobuf>3.9.0-rc1</Google_Protobuf>
|
||||
<Grpc_Tools>1.22.0</Grpc_Tools>
|
||||
<Grpc_AspNetCore_Server_ClientFactory>0.1.22-pre2</Grpc_AspNetCore_Server_ClientFactory>
|
||||
|
||||
<Microsoft_Extensions_Hosting>3.0.0-preview7.19362.4</Microsoft_Extensions_Hosting>
|
||||
<Microsoft_VisualStudio_Azure_Containers_Tools_Targets>1.7.9</Microsoft_VisualStudio_Azure_Containers_Tools_Targets>
|
||||
|
Loading…
x
Reference in New Issue
Block a user