From 3983461d6ff76168b7ff0dd9fb541edb61b9a16e Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sun, 24 Mar 2024 14:54:44 +0100 Subject: [PATCH] Add missing types. --- .../Internal/ExpectationHandler.cs | 52 ++++++++++++ .../Internal/Extensions.cs | 83 +++++++++++++++++++ .../Squidex.Messaging.Tests/Internal/Types.cs | 36 ++++++++ .../Implementation/MessagingDataProvider.cs | 2 +- .../Squidex.Messaging/MessagingBuilder.cs | 15 ++++ 5 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 messaging/Squidex.Messaging.Tests/Internal/ExpectationHandler.cs create mode 100644 messaging/Squidex.Messaging.Tests/Internal/Extensions.cs create mode 100644 messaging/Squidex.Messaging.Tests/Internal/Types.cs create mode 100644 messaging/Squidex.Messaging/MessagingBuilder.cs diff --git a/messaging/Squidex.Messaging.Tests/Internal/ExpectationHandler.cs b/messaging/Squidex.Messaging.Tests/Internal/ExpectationHandler.cs new file mode 100644 index 0000000..026a909 --- /dev/null +++ b/messaging/Squidex.Messaging.Tests/Internal/ExpectationHandler.cs @@ -0,0 +1,52 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.Collections.Concurrent; + +namespace Squidex.Messaging.Internal; + +internal sealed class ExpectationHandler : IMessageHandler +{ + private readonly int expectCount; + private readonly Guid expectedId; + private readonly TaskCompletionSource tcs = new TaskCompletionSource(); + private readonly ConcurrentBag messagesReceives = []; + private readonly CancellationTokenSource cts; + + public Task Completion => tcs.Task; + + public IEnumerable MessagesReceives => messagesReceives.OrderBy(x => x); + + public ExpectationHandler(int expectCount, Guid expectedId) + { + this.expectCount = expectCount; + this.expectedId = expectedId; + + cts = new CancellationTokenSource(30 * 1000); + + cts.Token.Register(() => + { + _ = tcs.TrySetResult(); + }); + } + + public Task HandleAsync(TestMessage message, + CancellationToken ct) + { + if (message.TestId == expectedId) + { + messagesReceives.Add(message.Value); + } + + if (expectCount == messagesReceives.Count) + { + tcs.TrySetResult(); + } + + return Task.CompletedTask; + } +} diff --git a/messaging/Squidex.Messaging.Tests/Internal/Extensions.cs b/messaging/Squidex.Messaging.Tests/Internal/Extensions.cs new file mode 100644 index 0000000..4f98deb --- /dev/null +++ b/messaging/Squidex.Messaging.Tests/Internal/Extensions.cs @@ -0,0 +1,83 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Squidex.Hosting; + +#pragma warning disable MA0048 // File name must match type name + +namespace Squidex.Messaging.Internal; + +internal static class Extensions +{ + public static async Task> CreateAsync(this IServiceProvider serviceProvider) where T : class + { + var provider = new Provider(serviceProvider); + + await provider.StartAsync(); + + return provider; + } + + public static MessagingBuilder Configure(this MessagingBuilder builder, Action? configure) where T : class + { + if (configure != null) + { + builder.Services.ConfigureOptional(configure); + } + + return builder; + } + + public static MessagingBuilder AddHandler(this MessagingBuilder builder, IMessageHandler? handler) + { + if (handler != null) + { + builder.Services.AddSingleton(handler); + } + + return builder; + } + + public static MessagingBuilder AddOverride(this MessagingBuilder builder, Action? configure) + { + configure?.Invoke(builder); + return builder; + } +} + +public sealed class Provider(IServiceProvider serviceProvider) : IAsyncDisposable where T : class +{ + public T Sut => serviceProvider.GetRequiredService(); + + public async Task StartAsync() + { + foreach (var initializable in serviceProvider.GetRequiredService>()) + { + await initializable.InitializeAsync(default); + } + + foreach (var process in serviceProvider.GetRequiredService>()) + { + await process.StartAsync(default); + } + } + + public async ValueTask DisposeAsync() + { + foreach (var process in serviceProvider.GetRequiredService>()) + { + await process.StopAsync(default); + } + + foreach (var initializable in serviceProvider.GetRequiredService>()) + { + await initializable.ReleaseAsync(default); + } + + (serviceProvider as IDisposable)?.Dispose(); + } +} diff --git a/messaging/Squidex.Messaging.Tests/Internal/Types.cs b/messaging/Squidex.Messaging.Tests/Internal/Types.cs new file mode 100644 index 0000000..cfc58e3 --- /dev/null +++ b/messaging/Squidex.Messaging.Tests/Internal/Types.cs @@ -0,0 +1,36 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +namespace Squidex.Messaging.Internal; + +#pragma warning disable MA0048 // File name must match type name + +public sealed class TestValue(string value) +{ + public string Value { get; } = value; +} + +public sealed class TestMessage : BaseMessage +{ + public int Value { get; } + + public TestMessage(Guid testId, int value) + : base(testId) + { + Value = value; + } +} + +public abstract class BaseMessage +{ + public Guid TestId { get; } + + protected BaseMessage(Guid testId) + { + TestId = testId; + } +} diff --git a/messaging/Squidex.Messaging/Implementation/MessagingDataProvider.cs b/messaging/Squidex.Messaging/Implementation/MessagingDataProvider.cs index 79505b8..d5655b0 100644 --- a/messaging/Squidex.Messaging/Implementation/MessagingDataProvider.cs +++ b/messaging/Squidex.Messaging/Implementation/MessagingDataProvider.cs @@ -46,7 +46,7 @@ public Task StartAsync( } public Task UpdateAliveAsync( - CancellationToken ct) + CancellationToken ct = default) { KeyValuePair<(string Group, string Key), (SerializedObject Value, TimeSpan Expires)>[] localEntries; diff --git a/messaging/Squidex.Messaging/MessagingBuilder.cs b/messaging/Squidex.Messaging/MessagingBuilder.cs new file mode 100644 index 0000000..6082dfa --- /dev/null +++ b/messaging/Squidex.Messaging/MessagingBuilder.cs @@ -0,0 +1,15 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.DependencyInjection; + +namespace Squidex.Messaging; + +public sealed class MessagingBuilder(IServiceCollection services) +{ + public IServiceCollection Services { get; } = services; +}