Skip to content

Commit

Permalink
Refactoring on use cases (#341)
Browse files Browse the repository at this point in the history
* Refactor client & request instantiation

* Remove unnecessary parameters and fields

* Remove specific use cases, use vonage client for generic purpose
  • Loading branch information
Tr00d authored Jan 27, 2023
1 parent d56e0ee commit d950232
Show file tree
Hide file tree
Showing 58 changed files with 109 additions and 746 deletions.
28 changes: 1 addition & 27 deletions Vonage.Common.Test/Client/VonageRequestBuilderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ namespace Vonage.Common.Test.Client;
public class VonageRequestBuilderTest
{
private readonly HttpMethod method;
private readonly string token;
private readonly string stringContent;
private readonly Uri endpointUri;

Expand All @@ -16,24 +15,10 @@ public VonageRequestBuilderTest()
var fixture = new Fixture();
this.method = fixture.Create<HttpMethod>();
this.endpointUri = fixture.Create<Uri>();
this.token = fixture.Create<string>();
fixture.Create<string>();
this.stringContent = fixture.Create<string>();
}

[Theory]
[InlineData("")]
[InlineData(" ")]
[InlineData(null)]
public void Build_ShouldNotUpdateAuthorizationHeader_GivenTokenIsNullOrWhitespace(string invalidToken) =>
VonageRequestBuilder
.Initialize(this.method, this.endpointUri.AbsoluteUri)
.WithAuthorizationToken(invalidToken)
.Build()
.Headers
.Authorization
.Should()
.BeNull();

[Fact]
public void Build_ShouldReturnRequestNotUpdateContent_GivenContentIsNull() =>
VonageRequestBuilder
Expand All @@ -44,17 +29,6 @@ public void Build_ShouldReturnRequestNotUpdateContent_GivenContentIsNull() =>
.Should()
.BeNull();

[Fact]
public void Build_ShouldReturnRequestWithAuthorizationHeader_GivenTokenIsProvided()
{
var request = VonageRequestBuilder
.Initialize(this.method, this.endpointUri.AbsoluteUri)
.WithAuthorizationToken(this.token)
.Build();
request.Headers.Authorization.Scheme.Should().Be("Bearer");
request.Headers.Authorization.Parameter.Should().Be(this.token);
}

[Fact]
public async Task Build_ShouldReturnRequestWithContent_GivenContentIsProvided()
{
Expand Down
18 changes: 18 additions & 0 deletions Vonage.Common/Client/HttpRequestMessageExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Net.Http.Headers;

namespace Vonage.Common.Client;

internal static class HttpRequestMessageExtensions
{
internal static HttpRequestMessage WithAuthorization(this HttpRequestMessage message, string token)
{
message.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
return message;
}

internal static HttpRequestMessage WithUserAgent(this HttpRequestMessage message, string userAgent)
{
message.Headers.UserAgent.ParseAdd(userAgent);
return message;
}
}
3 changes: 1 addition & 2 deletions Vonage.Common/Client/IVonageRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ public interface IVonageRequest
/// <summary>
/// Converts the request to a HttpRequest.
/// </summary>
/// <param name="token">The token.</param>
/// <returns>The Http request.</returns>
HttpRequestMessage BuildRequestMessage(string token);
HttpRequestMessage BuildRequestMessage();

/// <summary>
/// Retrieves the endpoint's path.
Expand Down
28 changes: 15 additions & 13 deletions Vonage.Common/Client/VonageHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Vonage.Common.Client;
/// </summary>
public class VonageHttpClient
{
private readonly Func<string> tokenGeneration;
private readonly HttpClient client;
private readonly IJsonSerializer jsonSerializer;

Expand All @@ -17,36 +18,40 @@ public class VonageHttpClient
/// </summary>
/// <param name="httpClient">The http client.</param>
/// <param name="serializer">The serializer.</param>
public VonageHttpClient(HttpClient httpClient, IJsonSerializer serializer)
/// <param name="tokenGeneration">The token generation operation.</param>
public VonageHttpClient(HttpClient httpClient, IJsonSerializer serializer, Func<string> tokenGeneration)
{
this.client = httpClient;
this.jsonSerializer = serializer;
this.tokenGeneration = tokenGeneration;
}

/// <summary>
/// Sends a HttpRequest.
/// </summary>
/// <param name="request">The request to send.</param>
/// <param name="token">The token to use for authentication.</param>
/// <returns>Success if the operation succeeds, Failure it if fails.</returns>
public async Task<Result<Unit>> SendAsync<T>(Result<T> request, string token) where T : IVonageRequest =>
public async Task<Result<Unit>> SendAsync<T>(Result<T> request) where T : IVonageRequest =>
await request
.MapAsync(value => this.SendRequestAsync(value, token))
.BindAsync(value =>
MatchResponse(value, this.ParseFailure<Unit>, CreateSuccessResult));
.Map(this.BuildHttpRequestMessage)
.MapAsync(value => this.client.SendAsync(value))
.BindAsync(value => MatchResponse(value, this.ParseFailure<Unit>, CreateSuccessResult));

/// <summary>
/// Sends a HttpRequest and parses the response.
/// </summary>
/// <param name="request">The request to send.</param>
/// <param name="token">The token to use for authentication.</param>
/// <returns>Success if the operation succeeds, Failure it if fails.</returns>
public async Task<Result<TResponse>> SendWithResponseAsync<TResponse, TRequest>(Result<TRequest> request,
string token) where TRequest : IVonageRequest =>
public async Task<Result<TResponse>> SendWithResponseAsync<TRequest, TResponse>(Result<TRequest> request)
where TRequest : IVonageRequest =>
await request
.MapAsync(value => this.SendRequestAsync(value, token))
.Map(this.BuildHttpRequestMessage)
.MapAsync(value => this.client.SendAsync(value))
.BindAsync(value => MatchResponse(value, this.ParseFailure<TResponse>, this.ParseSuccess<TResponse>));

private HttpRequestMessage BuildHttpRequestMessage<T>(T value) where T : IVonageRequest =>
value.BuildRequestMessage().WithAuthorization(this.tokenGeneration());

private Result<T> CreateFailureResult<T>(HttpStatusCode code, string responseContent) =>
this.jsonSerializer
.DeserializeObject<ErrorResponse>(responseContent)
Expand Down Expand Up @@ -80,7 +85,4 @@ private async Task<Result<T>> ParseSuccess<T>(HttpResponseMessage response)
.DeserializeObject<T>(responseContent)
.Match(Result<T>.FromSuccess, Result<T>.FromFailure);
}

private Task<HttpResponseMessage> SendRequestAsync(IVonageRequest request, string token) =>
this.client.SendAsync(request.BuildRequestMessage(token));
}
15 changes: 1 addition & 14 deletions Vonage.Common/Client/VonageRequestBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Net.Http.Headers;
using Vonage.Common.Monads;
using Vonage.Common.Monads;

namespace Vonage.Common.Client;

Expand All @@ -9,7 +8,6 @@ namespace Vonage.Common.Client;
public class VonageRequestBuilder
{
private readonly HttpRequestMessage request;
private Maybe<AuthenticationHeaderValue> authenticationHeader = Maybe<AuthenticationHeaderValue>.None;
private Maybe<HttpContent> requestContent = Maybe<HttpContent>.None;

private VonageRequestBuilder(HttpMethod httpMethod, string endpointUri)
Expand All @@ -19,23 +17,12 @@ private VonageRequestBuilder(HttpMethod httpMethod, string endpointUri)

public HttpRequestMessage Build()
{
this.authenticationHeader.IfSome(header => this.request.Headers.Authorization = header);
this.requestContent.IfSome(content => this.request.Content = content);
return this.request;
}

public static VonageRequestBuilder Initialize(HttpMethod method, string endpointUri) => new(method, endpointUri);

public VonageRequestBuilder WithAuthorizationToken(string token)
{
if (!string.IsNullOrWhiteSpace(token))
{
this.authenticationHeader = new AuthenticationHeaderValue("Bearer", token);
}

return this;
}

public VonageRequestBuilder WithContent(HttpContent content)
{
if (content != null)
Expand Down
3 changes: 1 addition & 2 deletions Vonage.Server/Video/Archives/AddStream/AddStreamRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,9 @@ private AddStreamRequest(string applicationId, string archiveId, string streamId
public string StreamId { get; }

/// <inheritdoc />
public HttpRequestMessage BuildRequestMessage(string token) =>
public HttpRequestMessage BuildRequestMessage() =>
VonageRequestBuilder
.Initialize(new HttpMethod("PATCH"), this.GetEndpointPath())
.WithAuthorizationToken(token)
.WithContent(this.GetRequestContent())
.Build();

Expand Down
21 changes: 0 additions & 21 deletions Vonage.Server/Video/Archives/AddStream/AddStreamUseCase.cs

This file was deleted.

46 changes: 11 additions & 35 deletions Vonage.Server/Video/Archives/ArchiveClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,15 @@ namespace Vonage.Server.Video.Archives;
/// </summary>
public class ArchiveClient
{
private readonly AddStreamUseCase addStreamUseCase;
private readonly ChangeLayoutUseCase changeLayoutUseCase;
private readonly CreateArchiveUseCase createArchiveUseCase;
private readonly DeleteArchiveUseCase deleteArchiveUseCase;
private readonly GetArchivesUseCase getArchivesUseCase;
private readonly GetArchiveUseCase getArchiveUseCase;
private readonly RemoveStreamUseCase removeStreamUseCase;
private readonly StopArchiveUseCase stopArchiveUseCase;
private readonly VonageHttpClient vonageClient;

/// <summary>
/// Creates a new client.
/// </summary>
/// <param name="httpClient">Http Client to used for further connections.</param>
/// <param name="tokenGeneration">Function used for generating a token.</param>
public ArchiveClient(HttpClient httpClient, Func<string> tokenGeneration)
{
this.getArchivesUseCase =
new GetArchivesUseCase(new VonageHttpClient(httpClient, JsonSerializerBuilder.Build()), tokenGeneration);
this.getArchiveUseCase = new GetArchiveUseCase(new VonageHttpClient(httpClient, JsonSerializerBuilder.Build()),
tokenGeneration);
this.createArchiveUseCase =
new CreateArchiveUseCase(new VonageHttpClient(httpClient, JsonSerializerBuilder.Build()), tokenGeneration);
this.deleteArchiveUseCase =
new DeleteArchiveUseCase(new VonageHttpClient(httpClient, JsonSerializerBuilder.Build()), tokenGeneration);
this.stopArchiveUseCase =
new StopArchiveUseCase(new VonageHttpClient(httpClient, JsonSerializerBuilder.Build()), tokenGeneration);
this.changeLayoutUseCase =
new ChangeLayoutUseCase(new VonageHttpClient(httpClient, JsonSerializerBuilder.Build()), tokenGeneration);
this.addStreamUseCase = new AddStreamUseCase(new VonageHttpClient(httpClient, JsonSerializerBuilder.Build()),
tokenGeneration);
this.removeStreamUseCase =
new RemoveStreamUseCase(new VonageHttpClient(httpClient, JsonSerializerBuilder.Build()), tokenGeneration);
}
public ArchiveClient(HttpClient httpClient, Func<string> tokenGeneration) => this.vonageClient =
new VonageHttpClient(httpClient, JsonSerializerBuilder.Build(), tokenGeneration);

/// <summary>
/// Adds the stream included in a composed archive that was started with the streamMode set to "manual".
Expand All @@ -64,7 +40,7 @@ public ArchiveClient(HttpClient httpClient, Func<string> tokenGeneration)
/// failed.
/// </returns>
public Task<Result<Unit>> AddStreamAsync(Result<AddStreamRequest> request) =>
this.addStreamUseCase.AddStreamAsync(request);
this.vonageClient.SendAsync(request);

/// <summary>
/// Changes the layout type of a composed archive while it is being recorded.
Expand All @@ -75,7 +51,7 @@ public Task<Result<Unit>> AddStreamAsync(Result<AddStreamRequest> request) =>
/// failed.
/// </returns>
public Task<Result<Unit>> ChangeLayoutAsync(Result<ChangeLayoutRequest> request) =>
this.changeLayoutUseCase.ChangeLayoutAsync(request);
this.vonageClient.SendAsync(request);

/// <summary>
/// Creates a new archive.
Expand All @@ -86,7 +62,7 @@ public Task<Result<Unit>> ChangeLayoutAsync(Result<ChangeLayoutRequest> request)
/// failed.
/// </returns>
public Task<Result<Archive>> CreateArchiveAsync(Result<CreateArchiveRequest> request) =>
this.createArchiveUseCase.CreateArchiveAsync(request);
this.vonageClient.SendWithResponseAsync<CreateArchiveRequest, Archive>(request);

/// <summary>
/// Deletes the specified archive.
Expand All @@ -97,7 +73,7 @@ public Task<Result<Archive>> CreateArchiveAsync(Result<CreateArchiveRequest> req
/// failed.
/// </returns>
public Task<Result<Unit>> DeleteArchiveAsync(Result<DeleteArchiveRequest> request) =>
this.deleteArchiveUseCase.DeleteArchiveAsync(request);
this.vonageClient.SendAsync(request);

/// <summary>
/// Return the archive information of a specific archive.
Expand All @@ -108,15 +84,15 @@ public Task<Result<Unit>> DeleteArchiveAsync(Result<DeleteArchiveRequest> reques
/// failed.
/// </returns>
public Task<Result<Archive>> GetArchiveAsync(Result<GetArchiveRequest> request) =>
this.getArchiveUseCase.GetArchiveAsync(request);
this.vonageClient.SendWithResponseAsync<GetArchiveRequest, Archive>(request);

/// <summary>
/// Retrieves all archives from an application.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>A success state with archives if the operation succeeded. A failure state with the error message if it failed.</returns>
public Task<Result<GetArchivesResponse>> GetArchivesAsync(Result<GetArchivesRequest> request) =>
this.getArchivesUseCase.GetArchivesAsync(request);
this.vonageClient.SendWithResponseAsync<GetArchivesRequest, GetArchivesResponse>(request);

/// <summary>
/// Removes the stream included in a composed archive that was started with the streamMode set to "manual".
Expand All @@ -127,7 +103,7 @@ public Task<Result<GetArchivesResponse>> GetArchivesAsync(Result<GetArchivesRequ
/// failed.
/// </returns>
public Task<Result<Unit>> RemoveStreamAsync(Result<RemoveStreamRequest> request) =>
this.removeStreamUseCase.RemoveStreamAsync(request);
this.vonageClient.SendAsync(request);

/// <summary>
/// Stops an archive.
Expand All @@ -138,5 +114,5 @@ public Task<Result<Unit>> RemoveStreamAsync(Result<RemoveStreamRequest> request)
/// failed.
/// </returns>
public Task<Result<Archive>> StopArchiveAsync(Result<StopArchiveRequest> request) =>
this.stopArchiveUseCase.StopArchiveAsync(request);
this.vonageClient.SendWithResponseAsync<StopArchiveRequest, Archive>(request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ private ChangeLayoutRequest(string applicationId, string archiveId, ArchiveLayou
public ArchiveLayout Layout { get; }

/// <inheritdoc />
public HttpRequestMessage BuildRequestMessage(string token) =>
public HttpRequestMessage BuildRequestMessage() =>
VonageRequestBuilder
.Initialize(HttpMethod.Put, this.GetEndpointPath())
.WithAuthorizationToken(token)
.WithContent(this.GetRequestContent())
.Build();

Expand Down
21 changes: 0 additions & 21 deletions Vonage.Server/Video/Archives/ChangeLayout/ChangeLayoutUseCase.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,9 @@ private CreateArchiveRequest(ArchiveLayout layout, string applicationId, string
public StreamMode StreamMode { get; }

/// <inheritdoc />
public HttpRequestMessage BuildRequestMessage(string token) =>
public HttpRequestMessage BuildRequestMessage() =>
VonageRequestBuilder
.Initialize(HttpMethod.Post, this.GetEndpointPath())
.WithAuthorizationToken(token)
.WithContent(this.GetRequestContent())
.Build();

Expand Down
Loading

0 comments on commit d950232

Please sign in to comment.