use HttpClientFactory and Polly

pull/1170/head
Mon 6 years ago
parent 5479701d89
commit 5499c87db0

@ -1,4 +1,4 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15 # Visual Studio 15
VisualStudioVersion = 15.0.28307.168 VisualStudioVersion = 15.0.28307.168
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1

@ -8,15 +8,20 @@ namespace Volo.Abp.AspNetCore.TestBase.DynamicProxying
public class AspNetCoreTestDynamicProxyHttpClientFactory : IDynamicProxyHttpClientFactory, ITransientDependency public class AspNetCoreTestDynamicProxyHttpClientFactory : IDynamicProxyHttpClientFactory, ITransientDependency
{ {
private readonly ITestServerAccessor _testServerAccessor; private readonly ITestServerAccessor _testServerAccessor;
private readonly IHttpClientFactory _httpClientFactory;
public AspNetCoreTestDynamicProxyHttpClientFactory(ITestServerAccessor testServerAccessor) public AspNetCoreTestDynamicProxyHttpClientFactory(ITestServerAccessor testServerAccessor, IHttpClientFactory httpClientFactory) {
{
_testServerAccessor = testServerAccessor; _testServerAccessor = testServerAccessor;
_httpClientFactory = httpClientFactory;
} }
public HttpClient Create() public HttpClient Create()
{ {
return _testServerAccessor.Server.CreateClient(); return _testServerAccessor.Server.CreateClient();
} }
public HttpClient Create(string name) {
return Create();
}
} }
} }

@ -28,7 +28,7 @@ namespace Volo.Abp.Http.Client.IdentityModel
var accessToken = await GetAccessTokenFromHttpContextOrNullAsync(); var accessToken = await GetAccessTokenFromHttpContextOrNullAsync();
if (accessToken != null) if (accessToken != null)
{ {
context.Client.SetBearerToken(accessToken); context.Request.SetBearerToken(accessToken);
return; return;
} }
} }

@ -3,6 +3,7 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using Castle.DynamicProxy; using Castle.DynamicProxy;
using JetBrains.Annotations; using JetBrains.Annotations;
using Polly;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Castle.DynamicProxy; using Volo.Abp.Castle.DynamicProxy;
using Volo.Abp.Http.Client; using Volo.Abp.Http.Client;
@ -105,6 +106,12 @@ namespace Microsoft.Extensions.DependencyInjection
{ {
options.HttpClientProxies[type] = new DynamicHttpClientProxyConfig(type, remoteServiceConfigurationName); options.HttpClientProxies[type] = new DynamicHttpClientProxyConfig(type, remoteServiceConfigurationName);
}); });
//use IHttpClientFactory and polly
services.AddHttpClient(remoteServiceConfigurationName)
.AddTransientHttpErrorPolicy(builder =>
// retry 3 times
builder.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i))));
var interceptorType = typeof(DynamicHttpProxyInterceptor<>).MakeGenericType(type); var interceptorType = typeof(DynamicHttpProxyInterceptor<>).MakeGenericType(type);
services.AddTransient(interceptorType); services.AddTransient(interceptorType);

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" /> <Import Project="..\..\..\common.props" />
@ -15,6 +15,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Abstractions" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="2.2.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

@ -1,13 +1,25 @@
using System.Net.Http; using System.Net.Http;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Http.Client.DynamicProxying namespace Volo.Abp.Http.Client.DynamicProxying
{ {
public class DefaultDynamicProxyHttpClientFactory : IDynamicProxyHttpClientFactory, ITransientDependency public class DefaultDynamicProxyHttpClientFactory : IDynamicProxyHttpClientFactory, ITransientDependency
{ {
public HttpClient Create() private readonly IHttpClientFactory _httpClientFactory;
public DefaultDynamicProxyHttpClientFactory(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public HttpClient Create()
{
return _httpClientFactory.CreateClient();
}
public HttpClient Create(string name)
{ {
return new HttpClient(); return _httpClientFactory.CreateClient(name);
} }
} }
} }

@ -128,41 +128,41 @@ namespace Volo.Abp.Http.Client.DynamicProxying
private async Task<string> MakeRequestAsync(IAbpMethodInvocation invocation) private async Task<string> MakeRequestAsync(IAbpMethodInvocation invocation)
{ {
using (var client = HttpClientFactory.Create()) var clientConfig = ClientOptions.HttpClientProxies.GetOrDefault(typeof(TService)) ?? throw new AbpException($"Could not get DynamicHttpClientProxyConfig for {typeof(TService).FullName}.");
{ var remoteServiceConfig = RemoteServiceOptions.RemoteServices.GetConfigurationOrDefault(clientConfig.RemoteServiceName);
var clientConfig = ClientOptions.HttpClientProxies.GetOrDefault(typeof(TService)) ?? throw new AbpException($"Could not get DynamicHttpClientProxyConfig for {typeof(TService).FullName}.");
var remoteServiceConfig = RemoteServiceOptions.RemoteServices.GetConfigurationOrDefault(clientConfig.RemoteServiceName);
var action = await ApiDescriptionFinder.FindActionAsync(remoteServiceConfig.BaseUrl, typeof(TService), invocation.Method); var client = HttpClientFactory.Create(clientConfig.RemoteServiceName);
var apiVersion = GetApiVersionInfo(action);
var url = remoteServiceConfig.BaseUrl + UrlBuilder.GenerateUrlWithParameters(action, invocation.ArgumentsDictionary, apiVersion);
var requestMessage = new HttpRequestMessage(action.GetHttpMethod(), url) var action = await ApiDescriptionFinder.FindActionAsync(remoteServiceConfig.BaseUrl, typeof(TService), invocation.Method);
{ var apiVersion = GetApiVersionInfo(action);
Content = RequestPayloadBuilder.BuildContent(action, invocation.ArgumentsDictionary, JsonSerializer, apiVersion) var url = remoteServiceConfig.BaseUrl + UrlBuilder.GenerateUrlWithParameters(action, invocation.ArgumentsDictionary, apiVersion);
};
AddHeaders(invocation, action, requestMessage, apiVersion);
await ClientAuthenticator.Authenticate(
new RemoteServiceHttpClientAuthenticateContext(
client,
requestMessage,
remoteServiceConfig,
clientConfig.RemoteServiceName
)
);
var response = await client.SendAsync(requestMessage, GetCancellationToken()); var requestMessage = new HttpRequestMessage(action.GetHttpMethod(), url)
{
Content = RequestPayloadBuilder.BuildContent(action, invocation.ArgumentsDictionary, JsonSerializer, apiVersion)
};
if (!response.IsSuccessStatusCode) AddHeaders(invocation, action, requestMessage, apiVersion);
{
await ThrowExceptionForResponseAsync(response);
}
return await response.Content.ReadAsStringAsync(); await ClientAuthenticator.Authenticate(
new RemoteServiceHttpClientAuthenticateContext(
client,
requestMessage,
remoteServiceConfig,
clientConfig.RemoteServiceName
)
);
var response = await client.SendAsync(requestMessage, GetCancellationToken());
if (!response.IsSuccessStatusCode)
{
await ThrowExceptionForResponseAsync(response);
} }
}
return await response.Content.ReadAsStringAsync();
}
private ApiVersionInfo GetApiVersionInfo(ActionApiDescriptionModel action) private ApiVersionInfo GetApiVersionInfo(ActionApiDescriptionModel action)
{ {

@ -5,5 +5,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying
public interface IDynamicProxyHttpClientFactory public interface IDynamicProxyHttpClientFactory
{ {
HttpClient Create(); HttpClient Create();
HttpClient Create(string name);
} }
} }
Loading…
Cancel
Save