Skip to content

Commit

Permalink
HttpClient cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Jérôme Quiles committed Jul 18, 2017
1 parent 6c27c2a commit 0d58b61
Show file tree
Hide file tree
Showing 15 changed files with 93 additions and 130 deletions.
3 changes: 1 addition & 2 deletions Skeleton.Tests.Web/HttpClientAsyncCachedEntityReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ namespace Skeleton.Tests.Web
public class HttpClientAsyncCachedEntityReaderTests
{
private readonly AsyncCrudHttpClient<CustomerDto> Client =
new AsyncCrudHttpClient<CustomerDto>(AppConfiguration.AsyncCachedCustomersUriBuilder,
new AutomaticDecompressionHandler());
new AsyncCrudHttpClient<CustomerDto>(AppConfiguration.AsyncCachedCustomersUriBuilder);

[Test]
public async Task AsyncCachedEntityReader_GetAllAsync()
Expand Down
3 changes: 1 addition & 2 deletions Skeleton.Tests.Web/HttpClientAsyncEntityReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ namespace Skeleton.Tests.Web
public class HttpClientAsyncEntityReaderTests
{
private readonly AsyncCrudHttpClient<CustomerDto> Client =
new AsyncCrudHttpClient<CustomerDto>(AppConfiguration.AsyncCustomersUriBuilder,
new AutomaticDecompressionHandler());
new AsyncCrudHttpClient<CustomerDto>(AppConfiguration.AsyncCustomersUriBuilder);

[Test]
public async Task AsyncEntityReader_GetAllAsync()
Expand Down
3 changes: 1 addition & 2 deletions Skeleton.Tests.Web/HttpClientAsyncEntityWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ namespace Skeleton.Tests.Web
public class HttpClientAsyncEntityWriterTests
{
private readonly AsyncCrudHttpClient<CustomerDto> Client =
new AsyncCrudHttpClient<CustomerDto>(AppConfiguration.AsyncCustomersUriBuilder,
new AutomaticDecompressionHandler());
new AsyncCrudHttpClient<CustomerDto>(AppConfiguration.AsyncCustomersUriBuilder);

[Test]
public async Task AsyncEntityWriter_UpdateAsync()
Expand Down
3 changes: 1 addition & 2 deletions Skeleton.Tests.Web/HttpClientCachedEntityReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ namespace Skeleton.Tests.Web
public class HttpClientCachedEntityReaderTests
{
private readonly CrudHttpClient<CustomerDto> Client =
new CrudHttpClient<CustomerDto>(AppConfiguration.CachedCustomersUriBuilder,
new AutomaticDecompressionHandler());
new CrudHttpClient<CustomerDto>(AppConfiguration.CachedCustomersUriBuilder);

[Test]
public void CachedEntityReader_GetAll()
Expand Down
3 changes: 1 addition & 2 deletions Skeleton.Tests.Web/HttpClientEntityReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ public class HttpClientEntityReaderTests
private const int numberOfPages = 5;

private readonly CrudHttpClient<CustomerDto> Client =
new CrudHttpClient<CustomerDto>(AppConfiguration.CustomersUriBuilder,
new AutomaticDecompressionHandler());
new CrudHttpClient<CustomerDto>(AppConfiguration.CustomersUriBuilder);

[Test]
public void EntityReader_GetAll()
Expand Down
3 changes: 1 addition & 2 deletions Skeleton.Tests.Web/HttpClientEntityWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ namespace Skeleton.Tests.Web
public class HttpClientEntityWriterTests
{
private readonly CrudHttpClient<CustomerDto> Client =
new CrudHttpClient<CustomerDto>(AppConfiguration.CustomersUriBuilder,
new AutomaticDecompressionHandler());
new CrudHttpClient<CustomerDto>(AppConfiguration.CustomersUriBuilder);

[Test]
public void EntityWriter_Update()
Expand Down
3 changes: 1 addition & 2 deletions Skeleton.Tests.Web/HttpClientHealthCheckTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ public class HttpClientHealthCheckTests
{
private readonly JsonHttpClient Client =
new JsonHttpClient(
new RestUriBuilder(AppConfiguration.Host, AppConfiguration.Port, "api/HealthCheck"),
new AutomaticDecompressionHandler());
new RestUriBuilder(AppConfiguration.Host, AppConfiguration.Port, "api/HealthCheck"));

[Test]
public void HeartBeat()
Expand Down
3 changes: 1 addition & 2 deletions Skeleton.Tests.Web/HttpClientLoggerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ public class HttpClientLoggerTests
{
private readonly JsonHttpClient Client =
new JsonHttpClient(
new RestUriBuilder(AppConfiguration.Host,AppConfiguration.Port, "api/log"),
new AutomaticDecompressionHandler());
new RestUriBuilder(AppConfiguration.Host,AppConfiguration.Port, "api/log"));

[Test]
public void Logger_LogInfo()
Expand Down
5 changes: 5 additions & 0 deletions Skeleton.Web.Client/AsyncJsonCrudHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ namespace Skeleton.Web.Client
public class AsyncCrudHttpClient<TDto> :
JsonHttpClient where TDto : class
{
public AsyncCrudHttpClient(IRestUriBuilder uriBuilder)
: base(uriBuilder)
{
}

public AsyncCrudHttpClient(IRestUriBuilder uriBuilder, HttpClientHandler handler)
: base(uriBuilder, handler)
{
Expand Down
8 changes: 6 additions & 2 deletions Skeleton.Web.Client/JsonCrudHttpClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Net.Http;

Expand All @@ -8,6 +7,11 @@ namespace Skeleton.Web.Client
public class CrudHttpClient<TDto> :
JsonHttpClient where TDto : class
{
public CrudHttpClient(IRestUriBuilder uriBuilder)
: base(uriBuilder)
{
}

public CrudHttpClient(IRestUriBuilder uriBuilder, HttpClientHandler handler)
: base(uriBuilder, handler)
{
Expand Down
169 changes: 68 additions & 101 deletions Skeleton.Web.Client/JsonHttpClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net.Http;
using System.Net.Http.Headers;
Expand All @@ -11,13 +10,18 @@ namespace Skeleton.Web.Client
public class JsonHttpClient : IDisposable
{
private static int Version = Assembly.GetAssembly(typeof(JsonHttpClient)).GetName().Version.Major;
private static Lazy<HttpClient> HttpClient;
private static Lazy<HttpClient> InnerClient;

private readonly ExponentialRetryPolicy _retryPolicy = new ExponentialRetryPolicy();
private readonly IRestUriBuilder _uriBuilder;
private readonly HttpClientHandler _handler;
private bool _disposed;


public JsonHttpClient(IRestUriBuilder uriBuilder)
: this(uriBuilder, new AutomaticDecompressionHandler())
{
}

public JsonHttpClient(IRestUriBuilder uriBuilder, HttpClientHandler handler)
{
if (uriBuilder == null)
Expand All @@ -27,50 +31,30 @@ public JsonHttpClient(IRestUriBuilder uriBuilder, HttpClientHandler handler)
throw new ArgumentNullException(nameof(handler));

_uriBuilder = uriBuilder;
_handler = handler as HttpClientHandler;
_handler = handler;

HttpClient = new Lazy<HttpClient>(
InnerClient = new Lazy<HttpClient>(
() => new HttpClient(_handler));
}

public IRestUriBuilder UriBuilder => _uriBuilder;

protected HttpClient Client => HttpClient.Value;

public HttpResponseMessage Get(Uri requestUri)
{
return _retryPolicy.Execute(() =>
{
var response = Client
.GetAsync(requestUri)
.Result;
response.HandleException();
public AuthenticationHeaderValue Authentication { get; set; }

return response;
});
}
public HttpClient Client => InnerClient.Value;

public async Task<HttpResponseMessage> GetAsync(Uri requestUri)
public HttpResponseMessage Send(HttpRequestMessage request)
{
return await _retryPolicy.ExecuteAsync(async () =>
{
var response = await Client
.GetAsync(requestUri)
.ConfigureAwait(false);
if (request == null)
throw new ArgumentNullException(nameof(request));

response.HandleException();
return response;
});
}
CheckDisposed();
SetAuthentication(request);

public HttpResponseMessage Delete(Uri requestUri)
{
return _retryPolicy.Execute(() =>
{
var response = Client
.DeleteAsync(requestUri)
.SendAsync(request)
.Result;
response.HandleException();
Expand All @@ -79,12 +63,18 @@ public HttpResponseMessage Delete(Uri requestUri)
});
}

public async Task<HttpResponseMessage> DeleteAsync(Uri requestUri)
public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request)
{
return await _retryPolicy.ExecuteAsync(async () =>
if (request == null)
throw new ArgumentNullException(nameof(request));

CheckDisposed();
SetAuthentication(request);

return await _retryPolicy.Execute(async () =>
{
var response = await Client
.DeleteAsync(requestUri)
.SendAsync(request)
.ConfigureAwait(false);
response.HandleException();
Expand All @@ -93,93 +83,56 @@ public async Task<HttpResponseMessage> DeleteAsync(Uri requestUri)
});
}

public HttpResponseMessage Put<TDto>(Uri requestUri, TDto dto) where TDto : class
public HttpResponseMessage Get(Uri requestUri)
{
return _retryPolicy.Execute(() =>
{
var content = new JsonObjectContent(dto);
var response = Client
.PutAsync(requestUri, content)
.Result;
response.HandleException();
return response;
});
return Send(new HttpRequestMessage(HttpMethod.Get, requestUri));
}

public async Task<HttpResponseMessage> PutAsync<TDto>(Uri requestUri, TDto dto) where TDto : class
public async Task<HttpResponseMessage> GetAsync(Uri requestUri)
{
return await _retryPolicy.ExecuteAsync(async () =>
{
var content = new JsonObjectContent(dto);
var response = await Client
.PutAsync(requestUri, content)
.ConfigureAwait(false);
response.HandleException();
return await SendAsync(new HttpRequestMessage(HttpMethod.Get, requestUri));
}

return response;
});
public HttpResponseMessage Delete(Uri requestUri)
{
return Send(new HttpRequestMessage(HttpMethod.Delete, requestUri));
}

public HttpResponseMessage Post<TDto>(Uri requestUri, TDto dto) where TDto : class
public async Task<HttpResponseMessage> DeleteAsync(Uri requestUri)
{
return _retryPolicy.Execute(() =>
{
var content = new JsonObjectContent(dto);
var response = Client
.PostAsync(requestUri, content)
.Result;
return await SendAsync(new HttpRequestMessage(HttpMethod.Delete, requestUri));
}

response.HandleException();
public HttpResponseMessage Put<T>(Uri requestUri, T value)
{
var content = new JsonObjectContent(value);
var request = new HttpRequestMessage(HttpMethod.Put, requestUri) { Content = content };

return response;
});
return Send(request);
}

public HttpResponseMessage Post<TDto>(Uri requestUri, IEnumerable<TDto> dtos) where TDto : class
public async Task<HttpResponseMessage> PutAsync<T>(Uri requestUri, T value)
{
return _retryPolicy.Execute(() =>
{
var content = new JsonObjectContent(dtos);
var response = Client
.PostAsync(requestUri, content)
.Result;
response.HandleException();
var content = new JsonObjectContent(value);
var request = new HttpRequestMessage(HttpMethod.Put, requestUri) { Content = content };

return response;
});
return await SendAsync(request);
}

public async Task<HttpResponseMessage> PostAsync<TDto>(Uri requestUri, TDto dto) where TDto : class
public HttpResponseMessage Post<T>(Uri requestUri, T value)
{
return await _retryPolicy.ExecuteAsync(async () =>
{
var content = new JsonObjectContent(dto);
var response = await Client
.PostAsync(requestUri, content)
.ConfigureAwait(false);
response.HandleException();
var content = new JsonObjectContent(value);
var request = new HttpRequestMessage(HttpMethod.Post, requestUri) { Content = content };

return response;
});
return Send(request);
}

public async Task<HttpResponseMessage> PostAsync<TDto>(Uri requestUri, IEnumerable<TDto> dtos) where TDto : class
public async Task<HttpResponseMessage> PostAsync<T>(Uri requestUri, T value)
{
return await _retryPolicy.ExecuteAsync(async () =>
{
var content = new JsonObjectContent(dtos);
var response = await Client
.PostAsync(requestUri, content)
.ConfigureAwait(false);
response.HandleException();
var content = new JsonObjectContent(value);
var request = new HttpRequestMessage(HttpMethod.Post, requestUri) { Content = content };

return response;
});
return await SendAsync(request);
}

public void Dispose()
Expand Down Expand Up @@ -208,6 +161,20 @@ private static ProductInfoHeaderValue GetUserAgent()
string.Format(CultureInfo.InvariantCulture, Constants.ProductHeader, Version)));
}

private void SetAuthentication(HttpRequestMessage request)
{
if (Authentication != null)
request.Headers.Authorization = Authentication;
}

private void CheckDisposed()
{
if (_disposed)
{
throw new ObjectDisposedException(GetType().FullName);
}
}

protected virtual void Dispose(bool disposing)
{
if (_disposed || !disposing)
Expand Down
10 changes: 5 additions & 5 deletions Skeleton.Web.Client/JsonObjectContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ namespace Skeleton.Web.Client
{
public sealed class JsonObjectContent : StringContent
{
public JsonObjectContent(object dto)
: base(Serialize(dto), Encoding.UTF8, Constants.JsonMediaType)
public JsonObjectContent(object value)
: base(Serialize(value), Encoding.UTF8, Constants.JsonMediaType)
{
}

private static string Serialize(object dto)
private static string Serialize(object value)
{
return JsonConvert.SerializeObject(dto);
return JsonConvert.SerializeObject(value);
}
}
}
}
Loading

0 comments on commit 0d58b61

Please sign in to comment.