diff --git a/src/KafkaFlow.Retry.API/AppBuilderExtensions.cs b/src/KafkaFlow.Retry.API/AppBuilderExtensions.cs index c2f17ab4..3c186e78 100644 --- a/src/KafkaFlow.Retry.API/AppBuilderExtensions.cs +++ b/src/KafkaFlow.Retry.API/AppBuilderExtensions.cs @@ -9,23 +9,31 @@ public static class AppBuilderExtensions { + public static IApplicationBuilder UseKafkaFlowRetryEndpoints( - this IApplicationBuilder appBuilder - ) + this IApplicationBuilder appBuilder, + string endpointPrefix) { var retryDurableQueueRepositoryProvider = appBuilder .ApplicationServices .GetService(typeof(IRetryDurableQueueRepositoryProvider)) as IRetryDurableQueueRepositoryProvider; - appBuilder.UseRetryEndpoints(retryDurableQueueRepositoryProvider); + appBuilder.UseRetryEndpoints(retryDurableQueueRepositoryProvider, endpointPrefix); return appBuilder; } + public static IApplicationBuilder UseKafkaFlowRetryEndpoints( + this IApplicationBuilder appBuilder) + { + return appBuilder.UseKafkaFlowRetryEndpoints(string.Empty); + } + public static IApplicationBuilder UseRetryEndpoints( this IApplicationBuilder appBuilder, - IRetryDurableQueueRepositoryProvider retryDurableQueueRepositoryProvider + IRetryDurableQueueRepositoryProvider retryDurableQueueRepositoryProvider, + string endpointPrefix ) { appBuilder.UseMiddleware( @@ -33,21 +41,33 @@ IRetryDurableQueueRepositoryProvider retryDurableQueueRepositoryProvider retryDurableQueueRepositoryProvider, new GetItemsRequestDtoReader(), new GetItemsInputAdapter(), - new GetItemsResponseDtoAdapter())); + new GetItemsResponseDtoAdapter(), + endpointPrefix)); appBuilder.UseMiddleware( new PatchItemsHandler( retryDurableQueueRepositoryProvider, new UpdateItemsInputAdapter(), - new UpdateItemsResponseDtoAdapter())); + new UpdateItemsResponseDtoAdapter(), + endpointPrefix)); appBuilder.UseMiddleware( new PatchQueuesHandler( retryDurableQueueRepositoryProvider, new UpdateQueuesInputAdapter(), - new UpdateQueuesResponseDtoAdapter())); + new UpdateQueuesResponseDtoAdapter(), + endpointPrefix)); return appBuilder; } + + public static IApplicationBuilder UseRetryEndpoints( + this IApplicationBuilder appBuilder, + IRetryDurableQueueRepositoryProvider retryDurableQueueRepositoryProvider + ) + { + return appBuilder.UseRetryEndpoints(retryDurableQueueRepositoryProvider, string.Empty); + } + } } \ No newline at end of file diff --git a/src/KafkaFlow.Retry.API/Handlers/GetItemsHandler.cs b/src/KafkaFlow.Retry.API/Handlers/GetItemsHandler.cs index 6a478d10..cd0e854b 100644 --- a/src/KafkaFlow.Retry.API/Handlers/GetItemsHandler.cs +++ b/src/KafkaFlow.Retry.API/Handlers/GetItemsHandler.cs @@ -18,7 +18,8 @@ public GetItemsHandler( IRetryDurableQueueRepositoryProvider retryDurableQueueRepositoryProvider, IGetItemsRequestDtoReader getItemsRequestDtoReader, IGetItemsInputAdapter getItemsInputAdapter, - IGetItemsResponseDtoAdapter getItemsResponseDtoAdapter) + IGetItemsResponseDtoAdapter getItemsResponseDtoAdapter, + string endpointPrefix) : base(endpointPrefix, "items") { Guard.Argument(retryDurableQueueRepositoryProvider, nameof(retryDurableQueueRepositoryProvider)).NotNull(); Guard.Argument(getItemsRequestDtoReader, nameof(getItemsRequestDtoReader)).NotNull(); @@ -31,8 +32,6 @@ public GetItemsHandler( this.getItemsResponseDtoAdapter = getItemsResponseDtoAdapter; } - protected override string ResourcePath => base.ResourcePath.ExtendResourcePath("items"); - protected override HttpMethod HttpMethod => HttpMethod.GET; protected override async Task HandleRequestAsync(HttpRequest request, HttpResponse response) diff --git a/src/KafkaFlow.Retry.API/Handlers/PatchItemsHandler.cs b/src/KafkaFlow.Retry.API/Handlers/PatchItemsHandler.cs index 883ec8e7..008fc5c8 100644 --- a/src/KafkaFlow.Retry.API/Handlers/PatchItemsHandler.cs +++ b/src/KafkaFlow.Retry.API/Handlers/PatchItemsHandler.cs @@ -18,15 +18,14 @@ internal class PatchItemsHandler : RetryRequestHandlerBase public PatchItemsHandler( IRetryDurableQueueRepositoryProvider retryDurableQueueRepositoryProvider, IUpdateItemsInputAdapter updateItemsInputAdapter, - IUpdateItemsResponseDtoAdapter updateItemsResponseDtoAdapter) + IUpdateItemsResponseDtoAdapter updateItemsResponseDtoAdapter, + string endpointPrefix) : base(endpointPrefix, "items") { this.retryDurableQueueRepositoryProvider = retryDurableQueueRepositoryProvider; this.updateItemsInputAdapter = updateItemsInputAdapter; this.updateItemsResponseDtoAdapter = updateItemsResponseDtoAdapter; } - protected override string ResourcePath => base.ResourcePath.ExtendResourcePath("items"); - protected override HttpMethod HttpMethod => HttpMethod.PATCH; protected override async Task HandleRequestAsync(HttpRequest request, HttpResponse response) diff --git a/src/KafkaFlow.Retry.API/Handlers/PatchQueuesHandler.cs b/src/KafkaFlow.Retry.API/Handlers/PatchQueuesHandler.cs index 288e3407..2c9c6297 100644 --- a/src/KafkaFlow.Retry.API/Handlers/PatchQueuesHandler.cs +++ b/src/KafkaFlow.Retry.API/Handlers/PatchQueuesHandler.cs @@ -18,14 +18,14 @@ internal class PatchQueuesHandler : RetryRequestHandlerBase public PatchQueuesHandler( IRetryDurableQueueRepositoryProvider retryDurableQueueRepositoryProvider, IUpdateQueuesInputAdapter updateQueuesInputAdapter, - IUpdateQueuesResponseDtoAdapter updateQueuesResponseDtoAdapter) + IUpdateQueuesResponseDtoAdapter updateQueuesResponseDtoAdapter, + string endpointPrefix) : base(endpointPrefix, "queues") { this.retryDurableQueueRepositoryProvider = retryDurableQueueRepositoryProvider; this.updateQueuesInputAdapter = updateQueuesInputAdapter; this.updateQueuesResponseDtoAdapter = updateQueuesResponseDtoAdapter; } - protected override string ResourcePath => base.ResourcePath.ExtendResourcePath("queues"); protected override HttpMethod HttpMethod => HttpMethod.PATCH; diff --git a/src/KafkaFlow.Retry.API/RetryRequestHandlerBase.cs b/src/KafkaFlow.Retry.API/RetryRequestHandlerBase.cs index d1b7dc19..e2e64431 100644 --- a/src/KafkaFlow.Retry.API/RetryRequestHandlerBase.cs +++ b/src/KafkaFlow.Retry.API/RetryRequestHandlerBase.cs @@ -3,11 +3,17 @@ using System.IO; using System.Text; using System.Threading.Tasks; + using Dawn; using Microsoft.AspNetCore.Http; using Newtonsoft.Json; internal abstract class RetryRequestHandlerBase : IHttpRequestHandler { + + private readonly string path; + private const string RetryResource = "retry"; + + protected JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings() { DateTimeZoneHandling = DateTimeZoneHandling.Utc, @@ -16,7 +22,21 @@ internal abstract class RetryRequestHandlerBase : IHttpRequestHandler protected abstract HttpMethod HttpMethod { get; } - protected virtual string ResourcePath => "/retry"; + protected RetryRequestHandlerBase(string endpointPrefix, string resource) + { + Guard.Argument(resource, nameof(resource)).NotNull().NotEmpty(); + + if (!string.IsNullOrEmpty(endpointPrefix)) + { + this.path = this.path + .ExtendResourcePath(endpointPrefix); + } + + this.path = this.path + .ExtendResourcePath(RetryResource) + .ExtendResourcePath(resource); + } + public virtual async Task HandleAsync(HttpRequest request, HttpResponse response) { @@ -34,7 +54,7 @@ protected bool CanHandle(HttpRequest httpRequest) { var resource = httpRequest.Path.ToUriComponent(); - if (!resource.Equals(this.ResourcePath)) + if (!resource.Equals(this.path)) { return false; } diff --git a/src/KafkaFlow.Retry.UnitTests/API/Handlers/GetItemsHandlerTests.cs b/src/KafkaFlow.Retry.UnitTests/API/Handlers/GetItemsHandlerTests.cs index 3d7ebee4..4b5d3bbe 100644 --- a/src/KafkaFlow.Retry.UnitTests/API/Handlers/GetItemsHandlerTests.cs +++ b/src/KafkaFlow.Retry.UnitTests/API/Handlers/GetItemsHandlerTests.cs @@ -27,11 +27,11 @@ public class GetItemsHandlerTests private readonly Mock mockGetItemsInputAdapter = new Mock(); private readonly Mock mockGetItemsRequestDtoReader = new Mock(); private readonly Mock mockGetItemsResponseDtoReader = new Mock(); - private readonly string resourcePath = "/retry/items"; + private readonly string resourcePath = "/testendpoint/retry/items"; private readonly Mock retryDurableQueueRepositoryProvider = new Mock(); [Fact] - public async Task GetItemsHandler_HandleAsync_Success() + public async Task GetItemsHandler_HandleAsync_WithEndpointPrefix_Success() { // Arrange var httpContext = this.CreateHttpContext(); @@ -61,7 +61,8 @@ public async Task GetItemsHandler_HandleAsync_Success() retryDurableQueueRepositoryProvider.Object, mockGetItemsRequestDtoReader.Object, mockGetItemsInputAdapter.Object, - mockGetItemsResponseDtoReader.Object + mockGetItemsResponseDtoReader.Object, + "testendpoint" ); // Act @@ -79,7 +80,7 @@ public async Task GetItemsHandler_HandleAsync_Success() [Theory] [ClassData(typeof(DependenciesThrowingExceptionsData))] - public async Task GetItemsHandler_HandleAsync_WithException_ReturnsExpectedStatusCode( + public async Task GetItemsHandler_HandleAsync_WithExceptionAndEndpointPrefix_ReturnsExpectedStatusCode( IGetItemsRequestDtoReader getItemsRequestDtoReader, IGetItemsInputAdapter getItemsInputAdapter, IRetryDurableQueueRepositoryProvider retryQueueDataProvider, @@ -93,7 +94,8 @@ public async Task GetItemsHandler_HandleAsync_WithException_ReturnsExpectedStatu retryQueueDataProvider, getItemsRequestDtoReader, getItemsInputAdapter, - getItemsResponseDtoAdapter + getItemsResponseDtoAdapter, + "testendpoint" ); // Act diff --git a/src/KafkaFlow.Retry.UnitTests/API/Handlers/PatchItemsHandlerTests.cs b/src/KafkaFlow.Retry.UnitTests/API/Handlers/PatchItemsHandlerTests.cs index a9dac81e..9afd0d47 100644 --- a/src/KafkaFlow.Retry.UnitTests/API/Handlers/PatchItemsHandlerTests.cs +++ b/src/KafkaFlow.Retry.UnitTests/API/Handlers/PatchItemsHandlerTests.cs @@ -57,7 +57,8 @@ public async Task PatchItemsHandler_HandleAsync_Success() var handler = new PatchItemsHandler( retryQueueDataProvider.Object, mockUpdateItemsInputAdapter.Object, - mockUpdateItemsResponseDtoAdapter.Object + mockUpdateItemsResponseDtoAdapter.Object, + string.Empty ); // Act @@ -103,7 +104,8 @@ public async Task PatchItemsHandler_HandleAsync_WithErrorInDeserialization() var handler = new PatchItemsHandler( Mock.Of(), Mock.Of(), - Mock.Of() + Mock.Of(), + string.Empty ); // act @@ -129,7 +131,8 @@ public async Task PatchItemsHandler_HandleAsync_WithException_ReturnsExpectedSta var handler = new PatchItemsHandler( retryQueueDataProvider, updateItemsInputAdapter, - updateItemsResponseDtoAdapter + updateItemsResponseDtoAdapter, + string.Empty ); // act diff --git a/src/KafkaFlow.Retry.UnitTests/API/Handlers/PatchQueuesHandlerTests.cs b/src/KafkaFlow.Retry.UnitTests/API/Handlers/PatchQueuesHandlerTests.cs index 54a0e74f..1ef1631e 100644 --- a/src/KafkaFlow.Retry.UnitTests/API/Handlers/PatchQueuesHandlerTests.cs +++ b/src/KafkaFlow.Retry.UnitTests/API/Handlers/PatchQueuesHandlerTests.cs @@ -51,7 +51,8 @@ public async Task PatchQueuesHandler_HandleAsync_Success() var handler = new PatchQueuesHandler( retryQueueDataProvider.Object, mockUpdateQueuesInputAdapter.Object, - mockUpdateQueuesResponseDtoAdapter.Object + mockUpdateQueuesResponseDtoAdapter.Object, + string.Empty ); // Act @@ -83,7 +84,8 @@ public async Task PatchQueuesHandler_HandleAsync_WithException_ReturnsExpectedSt var handler = new PatchQueuesHandler( retryQueueDataProvider, updateQueuesInputAdapter, - updateQueuesResponseDtoAdapter + updateQueuesResponseDtoAdapter, + string.Empty ); // act diff --git a/src/KafkaFlow.Retry.UnitTests/API/RetryRequestHandlerBaseTests.cs b/src/KafkaFlow.Retry.UnitTests/API/RetryRequestHandlerBaseTests.cs index 25ab7cb0..546358b0 100644 --- a/src/KafkaFlow.Retry.UnitTests/API/RetryRequestHandlerBaseTests.cs +++ b/src/KafkaFlow.Retry.UnitTests/API/RetryRequestHandlerBaseTests.cs @@ -13,7 +13,7 @@ public class RetryRequestHandlerBaseTests { private const string HttpMethod = "GET"; - private const string ResourcePath = "/retry"; + private const string ResourcePath = "/retry/resource"; [Fact] public async Task RetryRequestHandlerBase_HandleAsync_CallsHandleRequestAsync() @@ -44,7 +44,7 @@ public async Task RetryRequestHandlerBase_HandleAsync_CallsHandleRequestAsync() .SetupGet(ctx => ctx.Response) .Returns(httpResponse.Object); - var surrogate = new RetryRequestHandlerSurrogate(); + var surrogate = new RetryRequestHandlerSurrogate(string.Empty, "resource"); // Act var result = await surrogate.HandleAsync(mockHttpContext.Object.Request, mockHttpContext.Object.Response); @@ -62,7 +62,7 @@ public async Task RetryRequestHandlerBase_HandleAsync_WithWrongHttpMethod_DoesNo var httpContext = await HttpContextHelper.CreateContext(ResourcePath, wrongMethod); - var surrogate = new RetryRequestHandlerSurrogate(); + var surrogate = new RetryRequestHandlerSurrogate(string.Empty, "resource"); // Act var result = await surrogate.HandleAsync(httpContext.Request, httpContext.Response).ConfigureAwait(false); @@ -79,7 +79,7 @@ public async Task RetryRequestHandlerBase_HandleAsync_WithWrongResourcePath_Does var httpContext = await HttpContextHelper.CreateContext(wrongPath, HttpMethod); - var surrogate = new RetryRequestHandlerSurrogate(); + var surrogate = new RetryRequestHandlerSurrogate(string.Empty, "resource"); // Act var result = await surrogate.HandleAsync(httpContext.Request, httpContext.Response).ConfigureAwait(false); diff --git a/src/KafkaFlow.Retry.UnitTests/API/Surrogate/RetryRequestHandlerSurrogate.cs b/src/KafkaFlow.Retry.UnitTests/API/Surrogate/RetryRequestHandlerSurrogate.cs index a306e0c0..8f7a932e 100644 --- a/src/KafkaFlow.Retry.UnitTests/API/Surrogate/RetryRequestHandlerSurrogate.cs +++ b/src/KafkaFlow.Retry.UnitTests/API/Surrogate/RetryRequestHandlerSurrogate.cs @@ -7,6 +7,11 @@ internal class RetryRequestHandlerSurrogate : RetryRequestHandlerBase { + + public RetryRequestHandlerSurrogate(string endpointPrefix, string resource) : base(endpointPrefix, resource) + { + } + protected override HttpMethod HttpMethod => HttpMethod.GET; protected override async Task HandleRequestAsync(HttpRequest request, HttpResponse response)