added grpc factory and interceptor
This commit is contained in:
parent
51251a3f75
commit
646f7121b4
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
_logger.LogDebug("grpc client created, request = {@id}", id);
|
||||||
var response = await client.GetBasketByIdAsync(new BasketRequest { Id = id });
|
var response = await _basketClient.GetBasketByIdAsync(new BasketRequest { Id = id });
|
||||||
_logger.LogDebug("grpc response {@response}", response);
|
_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);
|
_logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket);
|
||||||
var request = MapToCustomerBasketRequest(currentBasket);
|
var request = MapToCustomerBasketRequest(currentBasket);
|
||||||
_logger.LogDebug("Grpc update basket request {@request}", request);
|
_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)
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
_logger.LogDebug("grpc client created, request = {@id}", id);
|
||||||
var response = await client.GetBasketByIdAsync(new BasketRequest { Id = id });
|
var response = await _basketClient.GetBasketByIdAsync(new BasketRequest { Id = id });
|
||||||
_logger.LogDebug("grpc response {@response}", response);
|
_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);
|
_logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket);
|
||||||
var request = MapToCustomerBasketRequest(currentBasket);
|
var request = MapToCustomerBasketRequest(currentBasket);
|
||||||
_logger.LogDebug("Grpc update basket request {@request}", request);
|
_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)
|
||||||
|
@ -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.
|
||||||
@ -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…
x
Reference in New Issue
Block a user