33using Polly ;
44using Polly . Wrap ;
55using System ;
6+ using System . Collections . Generic ;
7+ using System . Linq ;
68using System . Net ;
79using System . Net . Http ;
810using System . Net . Http . Headers ;
@@ -18,29 +20,45 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http
1820 public class ResilientHttpClient : IHttpClient
1921 {
2022 private HttpClient _client ;
21- private PolicyWrap _policyWrapper ;
23+ private readonly Dictionary < string , PolicyWrap > _policiesPerOrigin ;
2224 private ILogger < ResilientHttpClient > _logger ;
25+ private readonly Func < string , IEnumerable < Policy > > _policyCreator ;
2326 //public HttpClient Inst => _client;
2427
25- public ResilientHttpClient ( Policy [ ] policies , ILogger < ResilientHttpClient > logger )
28+ public ResilientHttpClient ( Func < string , IEnumerable < Policy > > policyCreator , ILogger < ResilientHttpClient > logger )
2629 {
2730 _client = new HttpClient ( ) ;
2831 _logger = logger ;
29-
30- // Add Policies to be applied
31- _policyWrapper = Policy . WrapAsync ( policies ) ;
32+ _policiesPerOrigin = new Dictionary < string , PolicyWrap > ( ) ;
33+ _policyCreator = policyCreator ;
3234 }
3335
34- private Task < T > HttpInvoker < T > ( Func < Task < T > > action )
36+ private Task < T > HttpInvoker < T > ( string origin , Func < Task < T > > action )
3537 {
38+ var normalizedOrigin = NormalizeOrigin ( origin ) ;
39+
40+ if ( ! _policiesPerOrigin . ContainsKey ( normalizedOrigin ) )
41+ {
42+ var newWrapper = Policy . WrapAsync ( _policyCreator ( normalizedOrigin ) . ToArray ( ) ) ;
43+ _policiesPerOrigin . Add ( normalizedOrigin , newWrapper ) ;
44+ }
45+
46+ var policyWrapper = _policiesPerOrigin [ normalizedOrigin ] ;
47+
3648 // Executes the action applying all
3749 // the policies defined in the wrapper
38- return _policyWrapper . ExecuteAsync ( ( ) => action ( ) ) ;
50+ return policyWrapper . ExecuteAsync ( ( ) => action ( ) ) ;
51+ }
52+
53+ private static string NormalizeOrigin ( string origin )
54+ {
55+ return origin ? . Trim ( ) ? . ToLower ( ) ;
3956 }
4057
4158 public Task < string > GetStringAsync ( string uri , string authorizationToken = null , string authorizationMethod = "Bearer" )
4259 {
43- return HttpInvoker ( async ( ) =>
60+ var origin = GetOriginFromUri ( uri ) ;
61+ return HttpInvoker ( origin , async ( ) =>
4462 {
4563 var requestMessage = new HttpRequestMessage ( HttpMethod . Get , uri ) ;
4664
@@ -55,17 +73,24 @@ public Task<string> GetStringAsync(string uri, string authorizationToken = null,
5573 } ) ;
5674 }
5775
58- private Task < HttpResponseMessage > DoPostPutAsync < T > ( HttpMethod method , string uri , T item , string authorizationToken = null , string requestId = null , string authorizationMethod = "Bearer" )
76+ private static string GetOriginFromUri ( string uri )
5977 {
78+ var url = new Uri ( uri ) ;
79+ var origin = $ "{ url . Scheme } ://{ url . DnsSafeHost } :{ url . Port } ";
80+ return origin ;
81+ }
6082
83+ private Task < HttpResponseMessage > DoPostPutAsync < T > ( HttpMethod method , string uri , T item , string authorizationToken = null , string requestId = null , string authorizationMethod = "Bearer" )
84+ {
6185 if ( method != HttpMethod . Post && method != HttpMethod . Put )
6286 {
6387 throw new ArgumentException ( "Value must be either post or put." , nameof ( method ) ) ;
6488 }
6589
6690 // a new StringContent must be created for each retry
6791 // as it is disposed after each call
68- return HttpInvoker ( async ( ) =>
92+ var origin = GetOriginFromUri ( uri ) ;
93+ return HttpInvoker ( origin , async ( ) =>
6994 {
7095 var requestMessage = new HttpRequestMessage ( method , uri ) ;
7196
@@ -105,7 +130,8 @@ public Task<HttpResponseMessage> PutAsync<T>(string uri, T item, string authoriz
105130 }
106131 public Task < HttpResponseMessage > DeleteAsync ( string uri , string authorizationToken = null , string requestId = null , string authorizationMethod = "Bearer" )
107132 {
108- return HttpInvoker ( async ( ) =>
133+ var origin = GetOriginFromUri ( uri ) ;
134+ return HttpInvoker ( origin , async ( ) =>
109135 {
110136 var requestMessage = new HttpRequestMessage ( HttpMethod . Delete , uri ) ;
111137
0 commit comments