Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring on use cases #341

Merged
merged 4 commits into from
Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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