mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-02-20 01:07:41 +01:00
* UseFireAndForget * ... * delay * async * updated code accorsing to proposal * Change nuget to package reference for WireMock.Net.Console.Net472.Classic, move the new FireAndForget into the main mapping, out of individual webhook mappings making it all or nothing, update tests, change Middleware to await or not the firing of all webhooks. Update models as needed. (#804) Co-authored-by: Matt Philmon <Matt_Philmon@carmax.com> * small update * Tweak middleware and fix bug in example (#806) Co-authored-by: Matt Philmon <Matt_Philmon@carmax.com> * .ConfigureAwait(false) Co-authored-by: mattisking <mattisking@gmail.com> Co-authored-by: Matt Philmon <Matt_Philmon@carmax.com>
114 lines
4.0 KiB
C#
114 lines
4.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Stef.Validation;
|
|
using WireMock.Models;
|
|
using WireMock.Settings;
|
|
using WireMock.Transformers;
|
|
using WireMock.Transformers.Handlebars;
|
|
using WireMock.Transformers.Scriban;
|
|
using WireMock.Types;
|
|
using WireMock.Util;
|
|
|
|
namespace WireMock.Http;
|
|
|
|
internal class WebhookSender
|
|
{
|
|
private const string ClientIp = "::1";
|
|
private static readonly ThreadLocal<Random> Random = new(() => new Random(DateTime.UtcNow.Millisecond));
|
|
|
|
private readonly WireMockServerSettings _settings;
|
|
|
|
public WebhookSender(WireMockServerSettings settings)
|
|
{
|
|
_settings = Guard.NotNull(settings);
|
|
}
|
|
|
|
public async Task<HttpResponseMessage> SendAsync(
|
|
HttpClient client,
|
|
IMapping mapping,
|
|
IWebhookRequest webhookRequest,
|
|
IRequestMessage originalRequestMessage,
|
|
IResponseMessage originalResponseMessage
|
|
)
|
|
{
|
|
Guard.NotNull(client);
|
|
Guard.NotNull(mapping);
|
|
Guard.NotNull(webhookRequest);
|
|
Guard.NotNull(originalRequestMessage);
|
|
Guard.NotNull(originalResponseMessage);
|
|
|
|
IBodyData? bodyData;
|
|
IDictionary<string, WireMockList<string>>? headers;
|
|
if (webhookRequest.UseTransformer == true)
|
|
{
|
|
ITransformer responseMessageTransformer;
|
|
switch (webhookRequest.TransformerType)
|
|
{
|
|
case TransformerType.Handlebars:
|
|
var factoryHandlebars = new HandlebarsContextFactory(_settings.FileSystemHandler, _settings.HandlebarsRegistrationCallback);
|
|
responseMessageTransformer = new Transformer(factoryHandlebars);
|
|
break;
|
|
|
|
case TransformerType.Scriban:
|
|
case TransformerType.ScribanDotLiquid:
|
|
var factoryDotLiquid = new ScribanContextFactory(_settings.FileSystemHandler, webhookRequest.TransformerType);
|
|
responseMessageTransformer = new Transformer(factoryDotLiquid);
|
|
break;
|
|
|
|
default:
|
|
throw new NotImplementedException($"TransformerType '{webhookRequest.TransformerType}' is not supported.");
|
|
}
|
|
|
|
(bodyData, headers) = responseMessageTransformer.Transform(mapping, originalRequestMessage, originalResponseMessage, webhookRequest.BodyData, webhookRequest.Headers, webhookRequest.TransformerReplaceNodeOptions);
|
|
}
|
|
else
|
|
{
|
|
bodyData = webhookRequest.BodyData;
|
|
headers = webhookRequest.Headers;
|
|
}
|
|
|
|
// Create RequestMessage
|
|
var requestMessage = new RequestMessage(
|
|
new UrlDetails(webhookRequest.Url),
|
|
webhookRequest.Method,
|
|
ClientIp,
|
|
bodyData,
|
|
headers?.ToDictionary(x => x.Key, x => x.Value.ToArray())
|
|
)
|
|
{
|
|
DateTime = DateTime.UtcNow
|
|
};
|
|
|
|
// Create HttpRequestMessage
|
|
var httpRequestMessage = HttpRequestMessageHelper.Create(requestMessage, webhookRequest.Url);
|
|
|
|
// Delay (if required)
|
|
if (TryGetDelay(webhookRequest, out var delay))
|
|
{
|
|
await Task.Delay(delay.Value).ConfigureAwait(false);
|
|
}
|
|
|
|
// Call the URL
|
|
return await client.SendAsync(httpRequestMessage).ConfigureAwait(false);
|
|
}
|
|
|
|
private static bool TryGetDelay(IWebhookRequest webhookRequest, [NotNullWhen(true)] out int? delay)
|
|
{
|
|
delay = webhookRequest.Delay;
|
|
var minimumDelay = webhookRequest.MinimumRandomDelay;
|
|
var maximumDelay = webhookRequest.MaximumRandomDelay;
|
|
|
|
if (minimumDelay is not null && maximumDelay is not null && maximumDelay >= minimumDelay)
|
|
{
|
|
delay = Random.Value!.Next(minimumDelay.Value, maximumDelay.Value);
|
|
return true;
|
|
}
|
|
|
|
return delay is not null;
|
|
}
|
|
} |