Skip to content

Commit

Permalink
Add support for multiple webhooks
Browse files Browse the repository at this point in the history
  • Loading branch information
StefH committed May 18, 2021
1 parent 93ab4e1 commit 00ae055
Show file tree
Hide file tree
Showing 12 changed files with 405 additions and 237 deletions.
2 changes: 2 additions & 0 deletions WireMock.Net Solution.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Raml/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=randomizer/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Stef/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Webhook/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Webhooks/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>
5 changes: 5 additions & 0 deletions src/WireMock.Net.Abstractions/Admin/Mappings/MappingModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,10 @@ public class MappingModel
/// The Webhook.
/// </summary>
public WebhookModel Webhook { get; set; }

/// <summary>
/// The Webhooks.
/// </summary>
public WebhookModel[] Webhooks { get; set; }
}
}
4 changes: 2 additions & 2 deletions src/WireMock.Net/IMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ public interface IMapping
bool LogMapping { get; }

/// <summary>
/// The Webhook.
/// The Webhooks.
/// </summary>
IWebhook Webhook { get; }
IWebhook[] Webhooks { get; }

/// <summary>
/// ProvideResponseAsync
Expand Down
11 changes: 5 additions & 6 deletions src/WireMock.Net/Mapping.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Admin.Mappings;
using WireMock.Matchers.Request;
using WireMock.Models;
using WireMock.ResponseProviders;
Expand Down Expand Up @@ -56,8 +55,8 @@ public class Mapping : IMapping
/// <inheritdoc cref="IMapping.LogMapping" />
public bool LogMapping => !(Provider is DynamicResponseProvider || Provider is DynamicAsyncResponseProvider);

/// <inheritdoc cref="IMapping.Webhook" />
public IWebhook Webhook { get; }
/// <inheritdoc cref="IMapping.Webhooks" />
public IWebhook[] Webhooks { get; }

/// <summary>
/// Initializes a new instance of the <see cref="Mapping"/> class.
Expand All @@ -73,7 +72,7 @@ public class Mapping : IMapping
/// <param name="executionConditionState">State in which the current mapping can occur. [Optional]</param>
/// <param name="nextState">The next state which will occur after the current mapping execution. [Optional]</param>
/// <param name="stateTimes">Only when the current state is executed this number, the next state which will occur. [Optional]</param>
/// <param name="webhook">The Webhook. [Optional]</param>
/// <param name="webhooks">The Webhooks. [Optional]</param>
public Mapping(
Guid guid,
[CanBeNull] string title,
Expand All @@ -86,7 +85,7 @@ public Mapping(
[CanBeNull] string executionConditionState,
[CanBeNull] string nextState,
[CanBeNull] int? stateTimes,
[CanBeNull] IWebhook webhook)
[CanBeNull] IWebhook[] webhooks)
{
Guid = guid;
Title = title;
Expand All @@ -99,7 +98,7 @@ public Mapping(
ExecutionConditionState = executionConditionState;
NextState = nextState;
StateTimes = stateTimes;
Webhook = webhook;
Webhooks = webhooks;
}

/// <inheritdoc cref="IMapping.ProvideResponseAsync" />
Expand Down
6 changes: 1 addition & 5 deletions src/WireMock.Net/Models/Webhook.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System.Collections.Generic;
using JetBrains.Annotations;
using WireMock.Types;

namespace WireMock.Models
namespace WireMock.Models
{
/// <summary>
/// Webhook
Expand Down
27 changes: 15 additions & 12 deletions src/WireMock.Net/Owin/WireMockMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ private async Task InvokeInternal(IContext ctx)
UpdateScenarioState(targetMapping);
}

if (!targetMapping.IsAdminInterface && targetMapping.Webhook != null)
if (!targetMapping.IsAdminInterface && targetMapping.Webhooks?.Length > 0)
{
await SendToWebhookAsync(targetMapping, request, response).ConfigureAwait(false);
await SendToWebhooksAsync(targetMapping, request, response).ConfigureAwait(false);
}
}
catch (Exception ex)
Expand Down Expand Up @@ -191,18 +191,21 @@ private async Task InvokeInternal(IContext ctx)
await CompletedTask;
}

private async Task SendToWebhookAsync(IMapping mapping, RequestMessage request, ResponseMessage response)
private async Task SendToWebhooksAsync(IMapping mapping, RequestMessage request, ResponseMessage response)
{
var httpClientForWebhook = HttpClientBuilder.Build(mapping.Settings.WebhookSettings ?? new WebhookSettings());
var webhookSender = new WebhookSender(mapping.Settings);

try
{
await webhookSender.SendAsync(httpClientForWebhook, mapping.Webhook.Request, request, response).ConfigureAwait(false);
}
catch (Exception ex)
for (int index = 0; index < mapping.Webhooks.Length; index++)
{
_options.Logger.Error($"Sending message to Webhook Mapping '{mapping.Guid}' failed. Exception: {ex}");
var httpClientForWebhook = HttpClientBuilder.Build(mapping.Settings.WebhookSettings ?? new WebhookSettings());
var webhookSender = new WebhookSender(mapping.Settings);

try
{
await webhookSender.SendAsync(httpClientForWebhook, mapping.Webhooks[index].Request, request, response).ConfigureAwait(false);
}
catch (Exception ex)
{
_options.Logger.Error($"Sending message to Webhook [{index}] from Mapping '{mapping.Guid}' failed. Exception: {ex}");
}
}
}

Expand Down
12 changes: 10 additions & 2 deletions src/WireMock.Net/Serialization/MappingConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,18 @@ public MappingModel ToMappingModel(IMapping mapping)
Response = new ResponseModel
{
Delay = (int?)response.Delay?.TotalMilliseconds
},
Webhook = WebhookMapper.Map(mapping.Webhook)
}
};

if (mapping.Webhooks?.Length == 1)
{
mappingModel.Webhook = WebhookMapper.Map(mapping.Webhooks[0]);
}
else if (mapping.Webhooks?.Length > 1)
{
mappingModel.Webhooks = mapping.Webhooks.Select(WebhookMapper.Map).ToArray();
}

if (bodyMatcher?.Matchers != null)
{
mappingModel.Request.Body = new BodyModel();
Expand Down
10 changes: 5 additions & 5 deletions src/WireMock.Net/Server/IRespondWithAProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ public interface IRespondWithAProvider
IRespondWithAProvider WillSetStateTo(int state, int? times = 1);

/// <summary>
/// Add a Webbook to call after the response has been generated.
/// Add (multiple) Webhook(s) to call after the response has been generated.
/// </summary>
/// <param name="webhook">The Webhook</param>
/// <param name="webhooks">The Webhooks</param>
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
IRespondWithAProvider WithWebhook(IWebhook webhook);
IRespondWithAProvider WithWebhook(params IWebhook[] webhooks);

/// <summary>
/// Add a Webbook to call after the response has been generated.
/// Add a Webhook to call after the response has been generated.
/// </summary>
/// <param name="url">The Webhook Url</param>
/// <param name="method">The method to use. [optional]</param>
Expand All @@ -129,7 +129,7 @@ IRespondWithAProvider WithWebhook(
);

/// <summary>
/// Add a Webbook to call after the response has been generated.
/// Add a Webhook to call after the response has been generated.
/// </summary>
/// <param name="url">The Webhook Url</param>
/// <param name="method">The method to use. [optional]</param>
Expand Down
Loading

0 comments on commit 00ae055

Please sign in to comment.