Browse Source

added grpc factory and interceptor

pull/1547/head
Borja García Rodríguez 4 years ago
parent
commit
646f7121b4
6 changed files with 142 additions and 47 deletions
  1. +43
    -0
      src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/Http2SupportGrpcInterceptor.cs
  2. +12
    -24
      src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs
  3. +17
    -1
      src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs
  4. +43
    -0
      src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/Http2SupportGrpcInterceptor.cs
  5. +11
    -20
      src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs
  6. +16
    -2
      src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs

+ 43
- 0
src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/Http2SupportGrpcInterceptor.cs View File

@ -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<Http2SupportGrpcInterceptor> _logger;
public Http2SupportGrpcInterceptor(ILogger<Http2SupportGrpcInterceptor> logger)
{
_logger = logger;
}
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request,
ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> 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);
}
}
}
}

+ 12
- 24
src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs View File

@ -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.Config;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models; using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System.Linq; using System.Linq;
using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
{ {
public class BasketService : IBasketService public class BasketService : IBasketService
{ {
private readonly HttpClient _httpClient;
private readonly UrlsConfig _urls; private readonly UrlsConfig _urls;
private readonly Basket.BasketClient _basketClient;
private readonly ILogger<BasketService> _logger; private readonly ILogger<BasketService> _logger;
public BasketService(HttpClient httpClient, IOptions<UrlsConfig> config, ILogger<BasketService> logger)
public BasketService(Basket.BasketClient basketClient, IOptions<UrlsConfig> config, ILogger<BasketService> logger)
{ {
_httpClient = httpClient;
_urls = config.Value; _urls = config.Value;
_basketClient = basketClient;
_logger = logger; _logger = logger;
} }
public async Task<BasketData> GetById(string id) public async Task<BasketData> 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) 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) private BasketData MapToBasketData(CustomerBasketResponse customerBasketRequest)


+ 17
- 1
src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs View File

@ -1,4 +1,5 @@
using Devspaces.Support; using Devspaces.Support;
using GrpcBasket;
using HealthChecks.UI.Client; using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
@ -14,6 +15,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -46,7 +48,8 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
services.AddCustomMvc(Configuration) services.AddCustomMvc(Configuration)
.AddCustomAuthentication(Configuration) .AddCustomAuthentication(Configuration)
.AddDevspaces() .AddDevspaces()
.AddHttpServices();
.AddHttpServices()
.AddGrpcServices();
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // 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; return services;
} }
public static IServiceCollection AddGrpcServices(this IServiceCollection services)
{
services.AddSingleton<Http2SupportGrpcInterceptor>();
services.AddGrpcClient<Basket.BasketClient>((services, options) =>
{
var basketApi = services.GetService<IOptions<UrlsConfig>>().Value.Basket;
options.Address = new Uri(basketApi);
}).AddInterceptor<Http2SupportGrpcInterceptor>();
return services;
}
} }
} }

+ 43
- 0
src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/Http2SupportGrpcInterceptor.cs View File

@ -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<Http2SupportGrpcInterceptor> _logger;
public Http2SupportGrpcInterceptor(ILogger<Http2SupportGrpcInterceptor> logger)
{
_logger = logger;
}
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request,
ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> 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);
}
}
}
}

+ 11
- 20
src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs View File

@ -4,7 +4,6 @@ using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System.Linq; using System.Linq;
using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
@ -12,41 +11,33 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
public class BasketService : IBasketService public class BasketService : IBasketService
{ {
private readonly UrlsConfig _urls; private readonly UrlsConfig _urls;
public readonly HttpClient _httpClient;
private readonly Basket.BasketClient _basketClient;
private readonly ILogger<BasketService> _logger; private readonly ILogger<BasketService> _logger;
public BasketService(HttpClient httpClient, IOptions<UrlsConfig> config, ILogger<BasketService> logger)
public BasketService(Basket.BasketClient basketClient, IOptions<UrlsConfig> config, ILogger<BasketService> logger)
{ {
_urls = config.Value; _urls = config.Value;
_httpClient = httpClient;
_basketClient = basketClient;
_logger = logger; _logger = logger;
} }
public async Task<BasketData> GetById(string id) public async Task<BasketData> 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) 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) private BasketData MapToBasketData(CustomerBasketResponse customerBasketRequest)


+ 16
- 2
src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs View File

@ -1,4 +1,5 @@
using Devspaces.Support; using Devspaces.Support;
using GrpcBasket;
using HealthChecks.UI.Client; using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
@ -14,6 +15,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -46,7 +48,8 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator
services.AddCustomMvc(Configuration) services.AddCustomMvc(Configuration)
.AddCustomAuthentication(Configuration) .AddCustomAuthentication(Configuration)
.AddDevspaces() .AddDevspaces()
.AddApplicationServices();
.AddApplicationServices()
.AddGrpcServices();
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // 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.UseDeveloperExceptionPage();
} }
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.UseSwagger().UseSwaggerUI(c => app.UseSwagger().UseSwaggerUI(c =>
@ -199,6 +202,17 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator
return services; return services;
} }
public static IServiceCollection AddGrpcServices(this IServiceCollection services)
{
services.AddSingleton<Http2SupportGrpcInterceptor>();
services.AddGrpcClient<Basket.BasketClient>((services, options) =>
{
var basketApi = services.GetService<IOptions<UrlsConfig>>().Value.Basket;
options.Address = new Uri(basketApi);
}).AddInterceptor<Http2SupportGrpcInterceptor>();
return services;
}
} }
} }

Loading…
Cancel
Save