mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-11 22:30:41 +01:00
Enable support for WireMock Middleware in Hosted Services (#1285)
This commit is contained in:
committed by
GitHub
parent
0fd190b5a3
commit
9392069f8a
@@ -36,7 +36,6 @@ internal class WireMockDelegationHandler : DelegatingHandler
|
|||||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Guard.NotNull(request);
|
Guard.NotNull(request);
|
||||||
Guard.NotNull(_httpContextAccessor.HttpContext);
|
|
||||||
|
|
||||||
if (_settings.AlwaysRedirect || IsWireMockRedirectHeaderSetToTrue())
|
if (_settings.AlwaysRedirect || IsWireMockRedirectHeaderSetToTrue())
|
||||||
{
|
{
|
||||||
@@ -57,16 +56,30 @@ internal class WireMockDelegationHandler : DelegatingHandler
|
|||||||
|
|
||||||
private bool IsWireMockRedirectHeaderSetToTrue()
|
private bool IsWireMockRedirectHeaderSetToTrue()
|
||||||
{
|
{
|
||||||
|
var httpContext = _httpContextAccessor.HttpContext;
|
||||||
|
if (httpContext is null)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("HttpContext is not available in current runtime environment");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
_httpContextAccessor.HttpContext!.Request.Headers.TryGetValue(AppConstants.HEADER_REDIRECT, out var values) &&
|
httpContext.Request.Headers.TryGetValue(AppConstants.HEADER_REDIRECT, out var values) &&
|
||||||
bool.TryParse(values.ToString(), out var shouldRedirectToWireMock) && shouldRedirectToWireMock;
|
bool.TryParse(values.ToString(), out var shouldRedirectToWireMock) && shouldRedirectToWireMock;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryGetDelayHeaderValue(out int delayInMs)
|
private bool TryGetDelayHeaderValue(out int delayInMs)
|
||||||
{
|
{
|
||||||
delayInMs = 0;
|
delayInMs = 0;
|
||||||
|
var httpContext = _httpContextAccessor.HttpContext;
|
||||||
|
if (httpContext is null)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("HttpContext is not available in current runtime environment");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
_httpContextAccessor.HttpContext!.Request.Headers.TryGetValue(AppConstants.HEADER_RESPONSE_DELAY, out var values) &&
|
httpContext.Request.Headers.TryGetValue(AppConstants.HEADER_RESPONSE_DELAY, out var values) &&
|
||||||
int.TryParse(values.ToString(), out delayInMs);
|
int.TryParse(values.ToString(), out delayInMs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ public class IntegrationTests
|
|||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("/real1", "Hello 1 from WireMock.Net !")]
|
[InlineData("/real1", "Hello 1 from WireMock.Net !")]
|
||||||
[InlineData("/real2", "Hello 2 from WireMock.Net !")]
|
[InlineData("/real2", "Hello 2 from WireMock.Net !")]
|
||||||
|
[InlineData("/real3", "Hello 3 from WireMock.Net !")]
|
||||||
public async Task CallingRealApi_WithAlwaysRedirectToWireMockIsTrue(string requestUri, string expectedResponse)
|
public async Task CallingRealApi_WithAlwaysRedirectToWireMockIsTrue(string requestUri, string expectedResponse)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ public class Program
|
|||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
builder.Services.AddSingleton<TaskQueue>();
|
||||||
|
builder.Services.AddHostedService<TestBackgroundService>();
|
||||||
|
|
||||||
builder.Services.AddWireMockService(server =>
|
builder.Services.AddWireMockService(server =>
|
||||||
{
|
{
|
||||||
server.Given(Request.Create()
|
server.Given(Request.Create()
|
||||||
@@ -28,6 +31,13 @@ public class Program
|
|||||||
).RespondWith(Response.Create()
|
).RespondWith(Response.Create()
|
||||||
.WithBody("Hello 2 from WireMock.Net !")
|
.WithBody("Hello 2 from WireMock.Net !")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
server.Given(Request.Create()
|
||||||
|
.WithPath("/test3")
|
||||||
|
.UsingAnyMethod()
|
||||||
|
).RespondWith(Response.Create()
|
||||||
|
.WithBody("Hello 3 from WireMock.Net !")
|
||||||
|
);
|
||||||
}, alwaysRedirectToWireMock);
|
}, alwaysRedirectToWireMock);
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
@@ -44,6 +54,11 @@ public class Program
|
|||||||
return await client.GetStringAsync("https://real-api:12345/test2");
|
return await client.GetStringAsync("https://real-api:12345/test2");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.MapGet("/real3", async (TaskQueue taskQueue, CancellationToken cancellationToken) =>
|
||||||
|
{
|
||||||
|
return await taskQueue.Enqueue("https://real-api:12345/test3", cancellationToken);
|
||||||
|
});
|
||||||
|
|
||||||
await app.RunAsync();
|
await app.RunAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
38
test/WireMock.Net.TestWebApplication/TaskQueue.cs
Normal file
38
test/WireMock.Net.TestWebApplication/TaskQueue.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
using System.Threading.Channels;
|
||||||
|
|
||||||
|
namespace WireMock.Net.TestWebApplication;
|
||||||
|
|
||||||
|
public class TaskQueue
|
||||||
|
{
|
||||||
|
private enum Status
|
||||||
|
{
|
||||||
|
Success,
|
||||||
|
Error
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Channel<string> _taskChannel = Channel.CreateUnbounded<string>();
|
||||||
|
private readonly Channel<(Status, string)> _responseChannel = Channel.CreateUnbounded<(Status, string)>();
|
||||||
|
|
||||||
|
public async Task<string> Enqueue(string taskId, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await _taskChannel.Writer.WriteAsync(taskId, cancellationToken);
|
||||||
|
var (status, result) = await _responseChannel.Reader.ReadAsync(cancellationToken);
|
||||||
|
if (status == Status.Error)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Received an error response from the task processor: ${result}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncEnumerable<string> ReadTasks(CancellationToken stoppingToken) =>
|
||||||
|
_taskChannel.Reader.ReadAllAsync(stoppingToken);
|
||||||
|
|
||||||
|
public async Task WriteResponse(string result, CancellationToken stoppingToken) =>
|
||||||
|
await _responseChannel.Writer.WriteAsync((Status.Success, result), stoppingToken);
|
||||||
|
|
||||||
|
public async Task WriteErrorResponse(string result, CancellationToken stoppingToken) =>
|
||||||
|
await _responseChannel.Writer.WriteAsync((Status.Error, result), stoppingToken);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
namespace WireMock.Net.TestWebApplication;
|
||||||
|
|
||||||
|
public class TestBackgroundService(HttpClient client, TaskQueue taskQueue, ILogger<TestBackgroundService> logger)
|
||||||
|
: BackgroundService
|
||||||
|
{
|
||||||
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||||
|
{
|
||||||
|
await foreach (var item in taskQueue.ReadTasks(stoppingToken))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await client.GetStringAsync(item, stoppingToken);
|
||||||
|
await taskQueue.WriteResponse(result, stoppingToken);
|
||||||
|
}
|
||||||
|
catch (ArgumentNullException argNullEx)
|
||||||
|
{
|
||||||
|
logger.LogError(argNullEx, "Null exception");
|
||||||
|
await taskQueue.WriteErrorResponse(argNullEx.Message, stoppingToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user