Skip to content

Commit 646f712

Browse files
author
Borja García Rodríguez
committed
added grpc factory and interceptor
1 parent 51251a3 commit 646f712

6 files changed

Lines changed: 142 additions & 47 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using Grpc.Core;
2+
using Grpc.Core.Interceptors;
3+
using Microsoft.Extensions.Logging;
4+
using System;
5+
6+
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure
7+
{
8+
public class Http2SupportGrpcInterceptor : Interceptor
9+
{
10+
private readonly ILogger<Http2SupportGrpcInterceptor> _logger;
11+
12+
public Http2SupportGrpcInterceptor(ILogger<Http2SupportGrpcInterceptor> logger)
13+
{
14+
_logger = logger;
15+
}
16+
17+
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
18+
TRequest request,
19+
ClientInterceptorContext<TRequest, TResponse> context,
20+
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
21+
{
22+
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
23+
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", true);
24+
25+
_logger.LogInformation("Calling via grpc client base address serviceName ={@ServiceName}, BaseAddress={@Host} ", context.Method.ServiceName, context.Host);
26+
27+
try
28+
{
29+
return continuation(request, context);
30+
}
31+
catch (RpcException e)
32+
{
33+
_logger.LogError("Error calling via grpc: {Status} - {Message}", e.Status, e.Message);
34+
return default;
35+
}
36+
finally
37+
{
38+
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", false);
39+
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", false);
40+
}
41+
}
42+
}
43+
}

src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/BasketService.cs

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,42 @@
1-
using Grpc.Net.Client;
2-
using GrpcBasket;
1+
using GrpcBasket;
32
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
43
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
54
using Microsoft.Extensions.Logging;
65
using Microsoft.Extensions.Options;
76
using System.Linq;
8-
using System.Net.Http;
97
using System.Threading.Tasks;
108

119
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
1210
{
1311
public class BasketService : IBasketService
1412
{
15-
private readonly HttpClient _httpClient;
1613
private readonly UrlsConfig _urls;
14+
private readonly Basket.BasketClient _basketClient;
1715
private readonly ILogger<BasketService> _logger;
1816

19-
public BasketService(HttpClient httpClient, IOptions<UrlsConfig> config, ILogger<BasketService> logger)
17+
public BasketService(Basket.BasketClient basketClient, IOptions<UrlsConfig> config, ILogger<BasketService> logger)
2018
{
21-
_httpClient = httpClient;
2219
_urls = config.Value;
20+
_basketClient = basketClient;
2321
_logger = logger;
2422
}
2523

2624
public async Task<BasketData> GetById(string id)
2725
{
28-
return await GrpcCallerService.CallService(_urls.GrpcBasket, async channel =>
29-
{
30-
31-
var client = new Basket.BasketClient(channel);
32-
_logger.LogDebug("grpc client created, request = {@id}", id);
33-
var response = await client.GetBasketByIdAsync(new BasketRequest { Id = id });
34-
_logger.LogDebug("grpc response {@response}", response);
26+
_logger.LogDebug("grpc client created, request = {@id}", id);
27+
var response = await _basketClient.GetBasketByIdAsync(new BasketRequest { Id = id });
28+
_logger.LogDebug("grpc response {@response}", response);
3529

36-
return MapToBasketData(response);
37-
});
30+
return MapToBasketData(response);
3831
}
3932

4033
public async Task UpdateAsync(BasketData currentBasket)
4134
{
42-
await GrpcCallerService.CallService(_urls.GrpcBasket, async httpClient =>
43-
{
44-
var channel = GrpcChannel.ForAddress(_urls.GrpcBasket);
45-
var client = new Basket.BasketClient(channel);
46-
_logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket);
47-
var request = MapToCustomerBasketRequest(currentBasket);
48-
_logger.LogDebug("Grpc update basket request {@request}", request);
35+
_logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket);
36+
var request = MapToCustomerBasketRequest(currentBasket);
37+
_logger.LogDebug("Grpc update basket request {@request}", request);
4938

50-
return await client.UpdateBasketAsync(request);
51-
});
39+
await _basketClient.UpdateBasketAsync(request);
5240
}
5341

5442
private BasketData MapToBasketData(CustomerBasketResponse customerBasketRequest)

src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Devspaces.Support;
2+
using GrpcBasket;
23
using HealthChecks.UI.Client;
34
using Microsoft.AspNetCore.Authentication.JwtBearer;
45
using Microsoft.AspNetCore.Builder;
@@ -14,6 +15,7 @@
1415
using Microsoft.Extensions.Diagnostics.HealthChecks;
1516
using Microsoft.Extensions.Hosting;
1617
using Microsoft.Extensions.Logging;
18+
using Microsoft.Extensions.Options;
1719
using Microsoft.OpenApi.Models;
1820
using System;
1921
using System.Collections.Generic;
@@ -46,7 +48,8 @@ public void ConfigureServices(IServiceCollection services)
4648
services.AddCustomMvc(Configuration)
4749
.AddCustomAuthentication(Configuration)
4850
.AddDevspaces()
49-
.AddHttpServices();
51+
.AddHttpServices()
52+
.AddGrpcServices();
5053
}
5154

5255
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -194,5 +197,18 @@ public static IServiceCollection AddHttpServices(this IServiceCollection service
194197
return services;
195198
}
196199

200+
public static IServiceCollection AddGrpcServices(this IServiceCollection services)
201+
{
202+
services.AddSingleton<Http2SupportGrpcInterceptor>();
203+
204+
services.AddGrpcClient<Basket.BasketClient>((services, options) =>
205+
{
206+
var basketApi = services.GetService<IOptions<UrlsConfig>>().Value.Basket;
207+
options.Address = new Uri(basketApi);
208+
}).AddInterceptor<Http2SupportGrpcInterceptor>();
209+
210+
return services;
211+
}
212+
197213
}
198214
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using Grpc.Core;
2+
using Grpc.Core.Interceptors;
3+
using Microsoft.Extensions.Logging;
4+
using System;
5+
6+
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure
7+
{
8+
public class Http2SupportGrpcInterceptor : Interceptor
9+
{
10+
private readonly ILogger<Http2SupportGrpcInterceptor> _logger;
11+
12+
public Http2SupportGrpcInterceptor(ILogger<Http2SupportGrpcInterceptor> logger)
13+
{
14+
_logger = logger;
15+
}
16+
17+
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
18+
TRequest request,
19+
ClientInterceptorContext<TRequest, TResponse> context,
20+
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
21+
{
22+
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
23+
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", true);
24+
25+
_logger.LogInformation("Calling via grpc client base address serviceName ={@ServiceName}, BaseAddress={@Host} ", context.Method.ServiceName, context.Host);
26+
27+
try
28+
{
29+
return continuation(request, context);
30+
}
31+
catch (RpcException e)
32+
{
33+
_logger.LogError("Error calling via grpc: {Status} - {Message}", e.Status, e.Message);
34+
return default;
35+
}
36+
finally
37+
{
38+
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", false);
39+
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", false);
40+
}
41+
}
42+
}
43+
}

src/ApiGateways/Web.Bff.Shopping/aggregator/Services/BasketService.cs

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,40 @@
44
using Microsoft.Extensions.Logging;
55
using Microsoft.Extensions.Options;
66
using System.Linq;
7-
using System.Net.Http;
87
using System.Threading.Tasks;
98

109
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
1110
{
1211
public class BasketService : IBasketService
1312
{
1413
private readonly UrlsConfig _urls;
15-
public readonly HttpClient _httpClient;
14+
private readonly Basket.BasketClient _basketClient;
1615
private readonly ILogger<BasketService> _logger;
1716

18-
public BasketService(HttpClient httpClient, IOptions<UrlsConfig> config, ILogger<BasketService> logger)
17+
public BasketService(Basket.BasketClient basketClient, IOptions<UrlsConfig> config, ILogger<BasketService> logger)
1918
{
2019
_urls = config.Value;
21-
_httpClient = httpClient;
20+
_basketClient = basketClient;
2221
_logger = logger;
2322
}
2423

2524

2625
public async Task<BasketData> GetById(string id)
2726
{
28-
return await GrpcCallerService.CallService(_urls.GrpcBasket, async channel =>
29-
{
30-
var client = new Basket.BasketClient(channel);
31-
_logger.LogDebug("grpc client created, request = {@id}", id);
32-
var response = await client.GetBasketByIdAsync(new BasketRequest { Id = id });
33-
_logger.LogDebug("grpc response {@response}", response);
27+
_logger.LogDebug("grpc client created, request = {@id}", id);
28+
var response = await _basketClient.GetBasketByIdAsync(new BasketRequest { Id = id });
29+
_logger.LogDebug("grpc response {@response}", response);
3430

35-
return MapToBasketData(response);
36-
});
31+
return MapToBasketData(response);
3732
}
3833

3934
public async Task UpdateAsync(BasketData currentBasket)
4035
{
41-
await GrpcCallerService.CallService(_urls.GrpcBasket, async channel =>
42-
{
43-
var client = new Basket.BasketClient(channel);
44-
_logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket);
45-
var request = MapToCustomerBasketRequest(currentBasket);
46-
_logger.LogDebug("Grpc update basket request {@request}", request);
36+
_logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket);
37+
var request = MapToCustomerBasketRequest(currentBasket);
38+
_logger.LogDebug("Grpc update basket request {@request}", request);
4739

48-
return await client.UpdateBasketAsync(request);
49-
});
40+
await _basketClient.UpdateBasketAsync(request);
5041
}
5142

5243
private BasketData MapToBasketData(CustomerBasketResponse customerBasketRequest)

src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Devspaces.Support;
2+
using GrpcBasket;
23
using HealthChecks.UI.Client;
34
using Microsoft.AspNetCore.Authentication.JwtBearer;
45
using Microsoft.AspNetCore.Builder;
@@ -14,6 +15,7 @@
1415
using Microsoft.Extensions.Diagnostics.HealthChecks;
1516
using Microsoft.Extensions.Hosting;
1617
using Microsoft.Extensions.Logging;
18+
using Microsoft.Extensions.Options;
1719
using Microsoft.OpenApi.Models;
1820
using System;
1921
using System.Collections.Generic;
@@ -46,7 +48,8 @@ public void ConfigureServices(IServiceCollection services)
4648
services.AddCustomMvc(Configuration)
4749
.AddCustomAuthentication(Configuration)
4850
.AddDevspaces()
49-
.AddApplicationServices();
51+
.AddApplicationServices()
52+
.AddGrpcServices();
5053
}
5154

5255
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -63,7 +66,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF
6366
{
6467
app.UseDeveloperExceptionPage();
6568
}
66-
69+
6770
app.UseHttpsRedirection();
6871

6972
app.UseSwagger().UseSwaggerUI(c =>
@@ -199,6 +202,17 @@ public static IServiceCollection AddApplicationServices(this IServiceCollection
199202
return services;
200203
}
201204

205+
public static IServiceCollection AddGrpcServices(this IServiceCollection services)
206+
{
207+
services.AddSingleton<Http2SupportGrpcInterceptor>();
208+
209+
services.AddGrpcClient<Basket.BasketClient>((services, options) =>
210+
{
211+
var basketApi = services.GetService<IOptions<UrlsConfig>>().Value.Basket;
212+
options.Address = new Uri(basketApi);
213+
}).AddInterceptor<Http2SupportGrpcInterceptor>();
202214

215+
return services;
216+
}
203217
}
204218
}

0 commit comments

Comments
 (0)