From 646f7121b42df1835adc043d38b0db9a07345e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Borja=20Garc=C3=ADa=20Rodr=C3=ADguez?= Date: Mon, 14 Dec 2020 16:47:42 +0100 Subject: [PATCH] added grpc factory and interceptor --- .../Http2SupportGrpcInterceptor.cs | 43 +++++++++++++++++++ .../aggregator/Services/BasketService.cs | 36 ++++++---------- .../Mobile.Bff.Shopping/aggregator/Startup.cs | 18 +++++++- .../Http2SupportGrpcInterceptor.cs | 43 +++++++++++++++++++ .../aggregator/Services/BasketService.cs | 31 +++++-------- .../Web.Bff.Shopping/aggregator/Startup.cs | 18 +++++++- 6 files changed, 142 insertions(+), 47 deletions(-) create mode 100644 src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/Http2SupportGrpcInterceptor.cs create mode 100644 src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/Http2SupportGrpcInterceptor.cs diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/Http2SupportGrpcInterceptor.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/Http2SupportGrpcInterceptor.cs new file mode 100644 index 000000000..b38178fc3 --- /dev/null +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/Http2SupportGrpcInterceptor.cs @@ -0,0 +1,43 @@ +using Grpc.Core; +using Grpc.Core.Interceptors; +using Microsoft.Extensions.Logging; +using System; + +namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure +{ + public class Http2SupportGrpcInterceptor : Interceptor + { + private readonly ILogger _logger; + + public Http2SupportGrpcInterceptor(ILogger logger) + { + _logger = logger; + } + + public override AsyncUnaryCall AsyncUnaryCall( + TRequest request, + ClientInterceptorContext context, + AsyncUnaryCallContinuation continuation) + { + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", true); + + _logger.LogInformation("Calling via grpc client base address serviceName ={@ServiceName}, BaseAddress={@Host} ", context.Method.ServiceName, context.Host); + + try + { + return continuation(request, context); + } + catch (RpcException e) + { + _logger.LogError("Error calling via grpc: {Status} - {Message}", e.Status, e.Message); + return default; + } + finally + { + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", false); + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", false); + } + } + } +} diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs index 8bd4c8948..5e97eed50 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs @@ -1,54 +1,42 @@ -using Grpc.Net.Client; -using GrpcBasket; +using GrpcBasket; using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config; using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Linq; -using System.Net.Http; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services { public class BasketService : IBasketService { - private readonly HttpClient _httpClient; private readonly UrlsConfig _urls; + private readonly Basket.BasketClient _basketClient; private readonly ILogger _logger; - public BasketService(HttpClient httpClient, IOptions config, ILogger logger) + public BasketService(Basket.BasketClient basketClient, IOptions config, ILogger logger) { - _httpClient = httpClient; _urls = config.Value; + _basketClient = basketClient; _logger = logger; } public async Task GetById(string id) { - return await GrpcCallerService.CallService(_urls.GrpcBasket, async channel => - { - - var client = new Basket.BasketClient(channel); - _logger.LogDebug("grpc client created, request = {@id}", id); - var response = await client.GetBasketByIdAsync(new BasketRequest { Id = id }); - _logger.LogDebug("grpc response {@response}", response); + _logger.LogDebug("grpc client created, request = {@id}", id); + var response = await _basketClient.GetBasketByIdAsync(new BasketRequest { Id = id }); + _logger.LogDebug("grpc response {@response}", response); - return MapToBasketData(response); - }); + return MapToBasketData(response); } public async Task UpdateAsync(BasketData currentBasket) { - await GrpcCallerService.CallService(_urls.GrpcBasket, async httpClient => - { - var channel = GrpcChannel.ForAddress(_urls.GrpcBasket); - var client = new Basket.BasketClient(channel); - _logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket); - var request = MapToCustomerBasketRequest(currentBasket); - _logger.LogDebug("Grpc update basket request {@request}", request); + _logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket); + var request = MapToCustomerBasketRequest(currentBasket); + _logger.LogDebug("Grpc update basket request {@request}", request); - return await client.UpdateBasketAsync(request); - }); + await _basketClient.UpdateBasketAsync(request); } private BasketData MapToBasketData(CustomerBasketResponse customerBasketRequest) diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs index 6523cafe9..8eb0a5788 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs @@ -1,4 +1,5 @@ using Devspaces.Support; +using GrpcBasket; using HealthChecks.UI.Client; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; @@ -14,6 +15,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Microsoft.OpenApi.Models; using System; using System.Collections.Generic; @@ -46,7 +48,8 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator services.AddCustomMvc(Configuration) .AddCustomAuthentication(Configuration) .AddDevspaces() - .AddHttpServices(); + .AddHttpServices() + .AddGrpcServices(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -194,5 +197,18 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator return services; } + public static IServiceCollection AddGrpcServices(this IServiceCollection services) + { + services.AddSingleton(); + + services.AddGrpcClient((services, options) => + { + var basketApi = services.GetService>().Value.Basket; + options.Address = new Uri(basketApi); + }).AddInterceptor(); + + return services; + } + } } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/Http2SupportGrpcInterceptor.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/Http2SupportGrpcInterceptor.cs new file mode 100644 index 000000000..522a0ad65 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/Http2SupportGrpcInterceptor.cs @@ -0,0 +1,43 @@ +using Grpc.Core; +using Grpc.Core.Interceptors; +using Microsoft.Extensions.Logging; +using System; + +namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure +{ + public class Http2SupportGrpcInterceptor : Interceptor + { + private readonly ILogger _logger; + + public Http2SupportGrpcInterceptor(ILogger logger) + { + _logger = logger; + } + + public override AsyncUnaryCall AsyncUnaryCall( + TRequest request, + ClientInterceptorContext context, + AsyncUnaryCallContinuation continuation) + { + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", true); + + _logger.LogInformation("Calling via grpc client base address serviceName ={@ServiceName}, BaseAddress={@Host} ", context.Method.ServiceName, context.Host); + + try + { + return continuation(request, context); + } + catch (RpcException e) + { + _logger.LogError("Error calling via grpc: {Status} - {Message}", e.Status, e.Message); + return default; + } + finally + { + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", false); + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", false); + } + } + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs index 7e85132cd..858251b25 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs @@ -4,7 +4,6 @@ using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Linq; -using System.Net.Http; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services @@ -12,41 +11,33 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services public class BasketService : IBasketService { private readonly UrlsConfig _urls; - public readonly HttpClient _httpClient; + private readonly Basket.BasketClient _basketClient; private readonly ILogger _logger; - public BasketService(HttpClient httpClient, IOptions config, ILogger logger) + public BasketService(Basket.BasketClient basketClient, IOptions config, ILogger logger) { _urls = config.Value; - _httpClient = httpClient; + _basketClient = basketClient; _logger = logger; } public async Task GetById(string id) { - return await GrpcCallerService.CallService(_urls.GrpcBasket, async channel => - { - var client = new Basket.BasketClient(channel); - _logger.LogDebug("grpc client created, request = {@id}", id); - var response = await client.GetBasketByIdAsync(new BasketRequest { Id = id }); - _logger.LogDebug("grpc response {@response}", response); + _logger.LogDebug("grpc client created, request = {@id}", id); + var response = await _basketClient.GetBasketByIdAsync(new BasketRequest { Id = id }); + _logger.LogDebug("grpc response {@response}", response); - return MapToBasketData(response); - }); + return MapToBasketData(response); } public async Task UpdateAsync(BasketData currentBasket) { - await GrpcCallerService.CallService(_urls.GrpcBasket, async channel => - { - var client = new Basket.BasketClient(channel); - _logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket); - var request = MapToCustomerBasketRequest(currentBasket); - _logger.LogDebug("Grpc update basket request {@request}", request); + _logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket); + var request = MapToCustomerBasketRequest(currentBasket); + _logger.LogDebug("Grpc update basket request {@request}", request); - return await client.UpdateBasketAsync(request); - }); + await _basketClient.UpdateBasketAsync(request); } private BasketData MapToBasketData(CustomerBasketResponse customerBasketRequest) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs index 1ea6c0f4f..48b153370 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs @@ -1,4 +1,5 @@ using Devspaces.Support; +using GrpcBasket; using HealthChecks.UI.Client; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; @@ -14,6 +15,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Microsoft.OpenApi.Models; using System; using System.Collections.Generic; @@ -46,7 +48,8 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator services.AddCustomMvc(Configuration) .AddCustomAuthentication(Configuration) .AddDevspaces() - .AddApplicationServices(); + .AddApplicationServices() + .AddGrpcServices(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -63,7 +66,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator { app.UseDeveloperExceptionPage(); } - + app.UseHttpsRedirection(); app.UseSwagger().UseSwaggerUI(c => @@ -199,6 +202,17 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator return services; } + public static IServiceCollection AddGrpcServices(this IServiceCollection services) + { + services.AddSingleton(); + services.AddGrpcClient((services, options) => + { + var basketApi = services.GetService>().Value.Basket; + options.Address = new Uri(basketApi); + }).AddInterceptor(); + + return services; + } } }