Skip to content

Commit

Permalink
Add WebhookSender (#1687)
Browse files Browse the repository at this point in the history
  • Loading branch information
gunndabad authored Nov 18, 2024
1 parent 766206e commit 4b9fc29
Show file tree
Hide file tree
Showing 33 changed files with 590 additions and 41 deletions.
2 changes: 2 additions & 0 deletions TeachingRecordSystem/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
<PackageVersion Include="Azure.Extensions.AspNetCore.DataProtection.Blobs" Version="1.3.4" />
<PackageVersion Include="Azure.Storage.Blobs" Version="12.19.1" />
<PackageVersion Include="Castle.Core" Version="5.1.1" />
<PackageVersion Include="CloudNative.CloudEvents" Version="2.8.0" />
<PackageVersion Include="CloudNative.CloudEvents.SystemTextJson" Version="2.8.0" />
<PackageVersion Include="CsvHelper" Version="30.1.0" />
<PackageVersion Include="dbup-sqlserver" Version="5.0.37" />
<PackageVersion Include="Dfe.Analytics" Version="0.2.5" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
using Medallion.Threading;
using Microsoft.Extensions.Options;
using TeachingRecordSystem.Api.Endpoints.IdentityWebHooks.Messages;
using TeachingRecordSystem.Api.Infrastructure.Json;
using TeachingRecordSystem.Core.Dqt;
using TeachingRecordSystem.Core.Dqt.Models;
using TeachingRecordSystem.Core.Infrastructure.Json;
using TeachingRecordSystem.Core.Services.GetAnIdentityApi;

namespace TeachingRecordSystem.Api.Endpoints.IdentityWebHooks;
Expand Down

This file was deleted.

18 changes: 14 additions & 4 deletions TeachingRecordSystem/src/TeachingRecordSystem.Api/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Security.Claims;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using FluentValidation;
using FluentValidation.AspNetCore;
using idunno.Authentication.Basic;
Expand All @@ -11,7 +13,6 @@
using TeachingRecordSystem.Api.Endpoints.IdentityWebHooks;
using TeachingRecordSystem.Api.Infrastructure.ApplicationModel;
using TeachingRecordSystem.Api.Infrastructure.Filters;
using TeachingRecordSystem.Api.Infrastructure.Json;
using TeachingRecordSystem.Api.Infrastructure.Logging;
using TeachingRecordSystem.Api.Infrastructure.Mapping;
using TeachingRecordSystem.Api.Infrastructure.Middleware;
Expand All @@ -23,6 +24,7 @@
using TeachingRecordSystem.Api.Validation;
using TeachingRecordSystem.Core.Dqt;
using TeachingRecordSystem.Core.Infrastructure;
using TeachingRecordSystem.Core.Infrastructure.Json;
using TeachingRecordSystem.Core.Services.Certificates;
using TeachingRecordSystem.Core.Services.DqtOutbox;
using TeachingRecordSystem.Core.Services.GetAnIdentityApi;
Expand Down Expand Up @@ -157,10 +159,18 @@ public static void Main(string[] args)
{
options.OutputFormatters.RemoveType<StringOutputFormatter>();
})
.AddJsonOptions(options =>
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());

options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver()
{
options.JsonSerializerOptions.Configure();
});
Modifiers =
{
Modifiers.OptionProperties
}
};
});

services.Decorate<Microsoft.AspNetCore.Mvc.Infrastructure.ProblemDetailsFactory, CamelCaseErrorKeysProblemDetailsFactory>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2452,6 +2452,8 @@
"dependencies": {
"AngleSharp": "[1.1.2, )",
"Azure.Storage.Blobs": "[12.19.1, )",
"CloudNative.CloudEvents": "[2.8.0, )",
"CloudNative.CloudEvents.SystemTextJson": "[2.8.0, )",
"CsvHelper": "[30.1.0, )",
"DistributedLock.Azure": "[1.0.0, )",
"DistributedLock.FileSystem": "[1.0.2, )",
Expand Down Expand Up @@ -2560,6 +2562,21 @@
"System.Diagnostics.EventLog": "6.0.0"
}
},
"CloudNative.CloudEvents": {
"type": "CentralTransitive",
"requested": "[2.8.0, )",
"resolved": "2.8.0",
"contentHash": "RvabvAQV7u3FZcZL5UlRmFz3/T5nMl86GpChpRvHKRHbO+/I4LBcZ0xRqYnNfAh30gM+h/JkSBHEnbhl0zmGtA=="
},
"CloudNative.CloudEvents.SystemTextJson": {
"type": "CentralTransitive",
"requested": "[2.8.0, )",
"resolved": "2.8.0",
"contentHash": "En3Bvf7tTbGyB/AWJIPGw8ksh1OgiSI3cBXmNvuH9+PMR4l0vVRlp9YsTu+gY7S/0VFyJDHP66P3uZHzgsRQ7w==",
"dependencies": {
"CloudNative.CloudEvents": "2.8.0"
}
},
"CsvHelper": {
"type": "CentralTransitive",
"requested": "[30.1.0, )",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2513,6 +2513,8 @@
"dependencies": {
"AngleSharp": "[1.1.2, )",
"Azure.Storage.Blobs": "[12.19.1, )",
"CloudNative.CloudEvents": "[2.8.0, )",
"CloudNative.CloudEvents.SystemTextJson": "[2.8.0, )",
"CsvHelper": "[30.1.0, )",
"DistributedLock.Azure": "[1.0.0, )",
"DistributedLock.FileSystem": "[1.0.2, )",
Expand Down Expand Up @@ -2618,6 +2620,21 @@
"System.Text.Json": "4.7.2"
}
},
"CloudNative.CloudEvents": {
"type": "CentralTransitive",
"requested": "[2.8.0, )",
"resolved": "2.8.0",
"contentHash": "RvabvAQV7u3FZcZL5UlRmFz3/T5nMl86GpChpRvHKRHbO+/I4LBcZ0xRqYnNfAh30gM+h/JkSBHEnbhl0zmGtA=="
},
"CloudNative.CloudEvents.SystemTextJson": {
"type": "CentralTransitive",
"requested": "[2.8.0, )",
"resolved": "2.8.0",
"contentHash": "En3Bvf7tTbGyB/AWJIPGw8ksh1OgiSI3cBXmNvuH9+PMR4l0vVRlp9YsTu+gY7S/0VFyJDHP66P3uZHzgsRQ7w==",
"dependencies": {
"CloudNative.CloudEvents": "2.8.0"
}
},
"CsvHelper": {
"type": "CentralTransitive",
"requested": "[30.1.0, )",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2025,6 +2025,8 @@
"dependencies": {
"AngleSharp": "[1.1.2, )",
"Azure.Storage.Blobs": "[12.19.1, )",
"CloudNative.CloudEvents": "[2.8.0, )",
"CloudNative.CloudEvents.SystemTextJson": "[2.8.0, )",
"CsvHelper": "[30.1.0, )",
"DistributedLock.Azure": "[1.0.0, )",
"DistributedLock.FileSystem": "[1.0.2, )",
Expand Down Expand Up @@ -2089,6 +2091,21 @@
"System.Text.Json": "4.7.2"
}
},
"CloudNative.CloudEvents": {
"type": "CentralTransitive",
"requested": "[2.8.0, )",
"resolved": "2.8.0",
"contentHash": "RvabvAQV7u3FZcZL5UlRmFz3/T5nMl86GpChpRvHKRHbO+/I4LBcZ0xRqYnNfAh30gM+h/JkSBHEnbhl0zmGtA=="
},
"CloudNative.CloudEvents.SystemTextJson": {
"type": "CentralTransitive",
"requested": "[2.8.0, )",
"resolved": "2.8.0",
"contentHash": "En3Bvf7tTbGyB/AWJIPGw8ksh1OgiSI3cBXmNvuH9+PMR4l0vVRlp9YsTu+gY7S/0VFyJDHP66P3uZHzgsRQ7w==",
"dependencies": {
"CloudNative.CloudEvents": "2.8.0"
}
},
"CsvHelper": {
"type": "CentralTransitive",
"requested": "[30.1.0, )",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class WebhookMessage
{
public required Guid WebhookMessageId { get; init; }
public required Guid WebhookEndpointId { get; init; }
public virtual WebhookEndpoint WebhookEndpoint { get; } = null!;
public virtual WebhookEndpoint WebhookEndpoint { get; internal set; } = null!;
public required string CloudEventId { get; init; }
public required string CloudEventType { get; init; }
public required DateTimeOffset Timestamp { get; init; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System.Text.Json.Serialization.Metadata;
using Optional;

namespace TeachingRecordSystem.Api.Infrastructure.Json;
namespace TeachingRecordSystem.Core.Infrastructure.Json;

public static class Modifiers
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using Optional;
using Optional.Unsafe;

namespace TeachingRecordSystem.Api.Infrastructure.Json;
namespace TeachingRecordSystem.Core.Infrastructure.Json;

public class OptionJsonConverter<T> : JsonConverter<Option<T>>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace TeachingRecordSystem.Api.Infrastructure.OpenApi;
namespace TeachingRecordSystem.Core;

public static class OpenApiDocumentHelper
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.ComponentModel.DataAnnotations;

namespace TeachingRecordSystem.Core.Services.Webhooks;

public class WebhookOptions
{
[Required]
public required string CanonicalDomain { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Diagnostics;
using CloudNative.CloudEvents;
using CloudNative.CloudEvents.Http;
using CloudNative.CloudEvents.SystemTextJson;
using Microsoft.Extensions.Options;
using TeachingRecordSystem.Core.DataStore.Postgres.Models;

namespace TeachingRecordSystem.Core.Services.Webhooks;

public class WebhookSender(HttpClient httpClient, IOptions<WebhookOptions> optionsAccessor)
{
private const string DataContentType = "application/json; charset=utf-8";

private readonly CloudEventFormatter _formatter = new JsonEventFormatter();

public async Task SendMessageAsync(WebhookMessage message, CancellationToken cancellationToken = default)
{
Debug.Assert(message.WebhookEndpoint is not null);

var openApiDocumentName = OpenApiDocumentHelper.GetDocumentName(3, message.ApiVersion);
var swaggerEndpoint = OpenApiDocumentHelper.DocumentRouteTemplate.Replace("{documentName}", openApiDocumentName);
var dataSchema = new Uri(optionsAccessor.Value.CanonicalDomain + swaggerEndpoint, UriKind.Absolute);

var source = new Uri(optionsAccessor.Value.CanonicalDomain);

var cloudEvent = new CloudEvent()
{
Id = message.CloudEventId,
Source = source,
Type = message.CloudEventType,
DataContentType = DataContentType,
DataSchema = dataSchema,
Time = message.Timestamp,
Data = message.Data,
};

var request = new HttpRequestMessage(HttpMethod.Post, message.WebhookEndpoint.Address)
{
Content = cloudEvent.ToHttpContent(ContentMode.Binary, _formatter)
};

var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead, cancellationToken);
response.EnsureSuccessStatusCode();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@
<ItemGroup>
<PackageReference Include="AngleSharp" />
<PackageReference Include="Azure.Storage.Blobs" />
<PackageReference Include="CloudNative.CloudEvents" />
<PackageReference Include="CloudNative.CloudEvents.SystemTextJson" />
<PackageReference Include="CsvHelper" />
<PackageReference Include="dbup-sqlserver" />
<PackageReference Include="DistributedLock.Azure" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,21 @@
"System.Text.Json": "4.7.2"
}
},
"CloudNative.CloudEvents": {
"type": "Direct",
"requested": "[2.8.0, )",
"resolved": "2.8.0",
"contentHash": "RvabvAQV7u3FZcZL5UlRmFz3/T5nMl86GpChpRvHKRHbO+/I4LBcZ0xRqYnNfAh30gM+h/JkSBHEnbhl0zmGtA=="
},
"CloudNative.CloudEvents.SystemTextJson": {
"type": "Direct",
"requested": "[2.8.0, )",
"resolved": "2.8.0",
"contentHash": "En3Bvf7tTbGyB/AWJIPGw8ksh1OgiSI3cBXmNvuH9+PMR4l0vVRlp9YsTu+gY7S/0VFyJDHP66P3uZHzgsRQ7w==",
"dependencies": {
"CloudNative.CloudEvents": "2.8.0"
}
},
"CsvHelper": {
"type": "Direct",
"requested": "[30.1.0, )",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2357,6 +2357,8 @@
"dependencies": {
"AngleSharp": "[1.1.2, )",
"Azure.Storage.Blobs": "[12.19.1, )",
"CloudNative.CloudEvents": "[2.8.0, )",
"CloudNative.CloudEvents.SystemTextJson": "[2.8.0, )",
"CsvHelper": "[30.1.0, )",
"DistributedLock.Azure": "[1.0.0, )",
"DistributedLock.FileSystem": "[1.0.2, )",
Expand Down Expand Up @@ -2421,6 +2423,21 @@
"System.Text.Json": "4.7.2"
}
},
"CloudNative.CloudEvents": {
"type": "CentralTransitive",
"requested": "[2.8.0, )",
"resolved": "2.8.0",
"contentHash": "RvabvAQV7u3FZcZL5UlRmFz3/T5nMl86GpChpRvHKRHbO+/I4LBcZ0xRqYnNfAh30gM+h/JkSBHEnbhl0zmGtA=="
},
"CloudNative.CloudEvents.SystemTextJson": {
"type": "CentralTransitive",
"requested": "[2.8.0, )",
"resolved": "2.8.0",
"contentHash": "En3Bvf7tTbGyB/AWJIPGw8ksh1OgiSI3cBXmNvuH9+PMR4l0vVRlp9YsTu+gY7S/0VFyJDHP66P3uZHzgsRQ7w==",
"dependencies": {
"CloudNative.CloudEvents": "2.8.0"
}
},
"CsvHelper": {
"type": "CentralTransitive",
"requested": "[30.1.0, )",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2473,6 +2473,8 @@
"dependencies": {
"AngleSharp": "[1.1.2, )",
"Azure.Storage.Blobs": "[12.19.1, )",
"CloudNative.CloudEvents": "[2.8.0, )",
"CloudNative.CloudEvents.SystemTextJson": "[2.8.0, )",
"CsvHelper": "[30.1.0, )",
"DistributedLock.Azure": "[1.0.0, )",
"DistributedLock.FileSystem": "[1.0.2, )",
Expand Down Expand Up @@ -2578,6 +2580,21 @@
"System.Text.Json": "4.7.2"
}
},
"CloudNative.CloudEvents": {
"type": "CentralTransitive",
"requested": "[2.8.0, )",
"resolved": "2.8.0",
"contentHash": "RvabvAQV7u3FZcZL5UlRmFz3/T5nMl86GpChpRvHKRHbO+/I4LBcZ0xRqYnNfAh30gM+h/JkSBHEnbhl0zmGtA=="
},
"CloudNative.CloudEvents.SystemTextJson": {
"type": "CentralTransitive",
"requested": "[2.8.0, )",
"resolved": "2.8.0",
"contentHash": "En3Bvf7tTbGyB/AWJIPGw8ksh1OgiSI3cBXmNvuH9+PMR4l0vVRlp9YsTu+gY7S/0VFyJDHP66P3uZHzgsRQ7w==",
"dependencies": {
"CloudNative.CloudEvents": "2.8.0"
}
},
"CsvHelper": {
"type": "CentralTransitive",
"requested": "[30.1.0, )",
Expand Down
Loading

0 comments on commit 4b9fc29

Please sign in to comment.