diff --git a/PettingZoo.Core/Connection/ISubscriber.cs b/PettingZoo.Core/Connection/ISubscriber.cs index e18c9e1..34ea83a 100644 --- a/PettingZoo.Core/Connection/ISubscriber.cs +++ b/PettingZoo.Core/Connection/ISubscriber.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace PettingZoo.Core.Connection { - public interface ISubscriber : IAsyncDisposable + public interface ISubscriber : IDisposable { string? QueueName { get; } string? Exchange {get; } diff --git a/PettingZoo.Core/ExportImport/ImportSubscriber.cs b/PettingZoo.Core/ExportImport/ImportSubscriber.cs index 067fee4..49ffaca 100644 --- a/PettingZoo.Core/ExportImport/ImportSubscriber.cs +++ b/PettingZoo.Core/ExportImport/ImportSubscriber.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Threading.Tasks; using PettingZoo.Core.Connection; namespace PettingZoo.Core.ExportImport @@ -13,7 +12,10 @@ namespace PettingZoo.Core.ExportImport public string? QueueName { get; } public string? Exchange => null; public string? RoutingKey => null; + + #pragma warning disable CS0067 // "The event ... is never used" - it's part of the interface so it's required. public event EventHandler? MessageReceived; + #pragma warning restore CS0067 public ImportSubscriber(string filename, IReadOnlyList messages) @@ -23,10 +25,9 @@ namespace PettingZoo.Core.ExportImport } - public ValueTask DisposeAsync() + public void Dispose() { GC.SuppressFinalize(this); - return default; } diff --git a/PettingZoo.Core/ExportImport/StreamProgressDecorator.cs b/PettingZoo.Core/ExportImport/StreamProgressDecorator.cs index 76ee710..b2abeaa 100644 --- a/PettingZoo.Core/ExportImport/StreamProgressDecorator.cs +++ b/PettingZoo.Core/ExportImport/StreamProgressDecorator.cs @@ -58,7 +58,7 @@ namespace PettingZoo.Core.ExportImport public StreamWrapper(StreamProgressDecorator owner, Stream decoratedStream) { this.owner = owner; - this.DecoratedStream = decoratedStream; + DecoratedStream = decoratedStream; } diff --git a/PettingZoo.Core/Generator/IExampleGenerator.cs b/PettingZoo.Core/Generator/IExampleGenerator.cs index f8fdf44..b39e313 100644 --- a/PettingZoo.Core/Generator/IExampleGenerator.cs +++ b/PettingZoo.Core/Generator/IExampleGenerator.cs @@ -17,11 +17,13 @@ namespace PettingZoo.Core.Generator public interface IClassTypeExample : IExample { - public string AssemblyName { get; } - public string? Namespace { get; } - public string ClassName { get; } + string AssemblyName { get; } + string? Namespace { get; } + string ClassName { get; } - public string FullClassName => (!string.IsNullOrEmpty(Namespace) ? Namespace + "." : "") + ClassName; + string FullClassName => (!string.IsNullOrEmpty(Namespace) ? Namespace + "." : "") + ClassName; + + bool TryGetPublishDestination(out string exchange, out string routingKey); } diff --git a/PettingZoo.Core/Macros/BasePayloadMacro.cs b/PettingZoo.Core/Macros/BasePayloadMacro.cs new file mode 100644 index 0000000..13f40fe --- /dev/null +++ b/PettingZoo.Core/Macros/BasePayloadMacro.cs @@ -0,0 +1,22 @@ +namespace PettingZoo.Core.Macros +{ + public abstract class BasePayloadMacro : IPayloadMacro + { + public string DisplayName { get; } + public string MacroText { get; } + + public string MacroCommand { get; } + + + protected BasePayloadMacro(string macroCommand, string displayName) + { + MacroCommand = macroCommand; + + DisplayName = displayName; + MacroText = "{{" + macroCommand + "}}"; + } + + + public abstract string GetValue(); + } +} diff --git a/PettingZoo.Core/Macros/DateTimePayloadMacro.cs b/PettingZoo.Core/Macros/DateTimePayloadMacro.cs new file mode 100644 index 0000000..2e6dec3 --- /dev/null +++ b/PettingZoo.Core/Macros/DateTimePayloadMacro.cs @@ -0,0 +1,18 @@ +using System; + +namespace PettingZoo.Core.Macros +{ + public class JsonDateTimePayloadMacro : BasePayloadMacro + { + public JsonDateTimePayloadMacro() + : base("JsonUtcNow", "Current date/time (yyyy-mm-ddThh:mm:ss.mmmZ)") + { + } + + + public override string GetValue() + { + return DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss.fff'Z'"); + } + } +} diff --git a/PettingZoo.Core/Macros/IPayloadMacroProcessor.cs b/PettingZoo.Core/Macros/IPayloadMacroProcessor.cs new file mode 100644 index 0000000..4cb7b34 --- /dev/null +++ b/PettingZoo.Core/Macros/IPayloadMacroProcessor.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace PettingZoo.Core.Macros +{ + public interface IPayloadMacroProcessor + { + string Apply(string payload); + + IEnumerable Macros { get; } + } + + + public interface IPayloadMacro + { + public string DisplayName { get; } + public string MacroText { get; } + } +} diff --git a/PettingZoo.Core/Macros/NewGuidPayloadMacro.cs b/PettingZoo.Core/Macros/NewGuidPayloadMacro.cs new file mode 100644 index 0000000..325eb4d --- /dev/null +++ b/PettingZoo.Core/Macros/NewGuidPayloadMacro.cs @@ -0,0 +1,18 @@ +using System; + +namespace PettingZoo.Core.Macros +{ + public class NewGuidPayloadMacro : BasePayloadMacro + { + public NewGuidPayloadMacro() + : base("NewGuid", "Generate GUID") + { + } + + + public override string GetValue() + { + return Guid.NewGuid().ToString(); + } + } +} diff --git a/PettingZoo.Core/Macros/PayloadMacroProcessor.cs b/PettingZoo.Core/Macros/PayloadMacroProcessor.cs new file mode 100644 index 0000000..10cc9a8 --- /dev/null +++ b/PettingZoo.Core/Macros/PayloadMacroProcessor.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; + +namespace PettingZoo.Core.Macros +{ + public class PayloadMacroProcessor : IPayloadMacroProcessor + { + private readonly BasePayloadMacro[] macros; + public IEnumerable Macros => macros; + + + public PayloadMacroProcessor() + { + macros = new BasePayloadMacro[] + { + new NewGuidPayloadMacro(), + new JsonDateTimePayloadMacro() + }; + } + + + // For now we only support simple one-keyboard macros, but this could be extended with parameters if required + private static readonly Regex MacroRegex = new("{{(.+?)}}", RegexOptions.Compiled); + + + public string Apply(string payload) + { + return MacroRegex.Replace(payload, match => + { + var macroCommand = match.Groups[1].Value.Trim(); + var macro = macros.FirstOrDefault(m => string.Equals(m.MacroCommand, macroCommand, StringComparison.CurrentCultureIgnoreCase)); + + return macro != null + ? macro.GetValue() + : match.Groups[0].Value; + }); + } + } +} diff --git a/PettingZoo.RabbitMQ/RabbitMQClientSubscriber.cs b/PettingZoo.RabbitMQ/RabbitMQClientSubscriber.cs index 9da4068..98fb4f3 100644 --- a/PettingZoo.RabbitMQ/RabbitMQClientSubscriber.cs +++ b/PettingZoo.RabbitMQ/RabbitMQClientSubscriber.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using PettingZoo.Core.Connection; using RabbitMQ.Client; using RabbitMQ.Client.Events; @@ -29,14 +28,12 @@ namespace PettingZoo.RabbitMQ } - public ValueTask DisposeAsync() + public void Dispose() { GC.SuppressFinalize(this); if (model != null && consumerTag != null && model.IsOpen) model.BasicCancelNoWait(consumerTag); - - return default; } diff --git a/PettingZoo.Tapeti/AssemblyParser/AssemblyParser.cs b/PettingZoo.Tapeti/AssemblyParser/AssemblyParser.cs index 50c5168..14be17f 100644 --- a/PettingZoo.Tapeti/AssemblyParser/AssemblyParser.cs +++ b/PettingZoo.Tapeti/AssemblyParser/AssemblyParser.cs @@ -7,6 +7,7 @@ using System.Runtime.Loader; using Newtonsoft.Json; using PettingZoo.Core.Generator; using PettingZoo.Core.Validation; +using Tapeti.Default; namespace PettingZoo.Tapeti.AssemblyParser { @@ -83,6 +84,24 @@ namespace PettingZoo.Tapeti.AssemblyParser } + public bool TryGetPublishDestination(out string exchange, out string routingKey) + { + try + { + // Assume default strategies are used + exchange = new NamespaceMatchExchangeStrategy().GetExchange(type); + routingKey = new TypeNameRoutingKeyStrategy().GetRoutingKey(type); + return true; + } + catch + { + exchange = ""; + routingKey = ""; + return false; + } + } + + public bool CanValidate() { return InitializeValidation(); diff --git a/PettingZoo.Tapeti/PettingZoo.Tapeti.csproj b/PettingZoo.Tapeti/PettingZoo.Tapeti.csproj index 3bf7adf..68c879d 100644 --- a/PettingZoo.Tapeti/PettingZoo.Tapeti.csproj +++ b/PettingZoo.Tapeti/PettingZoo.Tapeti.csproj @@ -17,6 +17,7 @@ + diff --git a/PettingZoo.Tapeti/TapetiClassLibraryExampleGenerator.cs b/PettingZoo.Tapeti/TapetiClassLibraryExampleGenerator.cs index 6cd0eae..60974e3 100644 --- a/PettingZoo.Tapeti/TapetiClassLibraryExampleGenerator.cs +++ b/PettingZoo.Tapeti/TapetiClassLibraryExampleGenerator.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; -using System.Windows.Threading; using PettingZoo.Core.Generator; using PettingZoo.Core.Settings; using PettingZoo.Tapeti.AssemblyLoader; diff --git a/PettingZoo.Tapeti/UI/ClassSelection/ClassSelectionViewModel.cs b/PettingZoo.Tapeti/UI/ClassSelection/ClassSelectionViewModel.cs index 51f8623..f17c497 100644 --- a/PettingZoo.Tapeti/UI/ClassSelection/ClassSelectionViewModel.cs +++ b/PettingZoo.Tapeti/UI/ClassSelection/ClassSelectionViewModel.cs @@ -300,6 +300,14 @@ namespace PettingZoo.Tapeti.UI.ClassSelection { return ""; } + + + public bool TryGetPublishDestination(out string exchange, out string routingKey) + { + exchange = ""; + routingKey = ""; + return false; + } } } } diff --git a/PettingZoo.WPF/Style.xaml b/PettingZoo.WPF/Style.xaml index 96fa4f5..4a53851 100644 --- a/PettingZoo.WPF/Style.xaml +++ b/PettingZoo.WPF/Style.xaml @@ -67,6 +67,12 @@ + +