├── _config.yml ├── logo_banner.jpg ├── logo_nuget.png ├── logo_symbol_nuget.png ├── MessageQueue.Core ├── packages.config ├── Properties │ ├── AssemblyInfo.cs │ ├── InfoMessages.Designer.cs │ └── InfoMessages.resx ├── Abstract │ ├── IMessageQueue.cs │ ├── MessageQueueConfiguration.cs │ ├── RequestMessage.cs │ ├── Outbound │ │ ├── IOutboundFaFMq.cs │ │ └── IOutboundRaRMq.cs │ ├── IMessageReceiveOptions.cs │ └── Inbound │ │ ├── IInboundRaRMq.cs │ │ └── IInboundFaFMq.cs ├── Helper │ ├── CommonConfigurationKeys.cs │ ├── CommonContextKeys.cs │ └── InterfaceImplementationInfo.cs ├── Concrete │ ├── NoLog.cs │ ├── QueueException.cs │ └── QueueErrorCode.cs └── MessageQueue.Core.csproj ├── MessageQueue.RabbitMq ├── packages.config ├── Properties │ └── AssemblyInfo.cs ├── Helper │ ├── AmqpExchangeType.cs │ ├── Defaults.cs │ ├── ContextKeys.cs │ └── RabbitMqConfigurationKeys.cs ├── Concrete │ ├── RabbitMqConfiguration.cs │ ├── RmqRequestMessage.cs │ ├── RmqMessageReceiveOptions.cs │ └── Outbound │ │ └── RmqOutboundFaF.cs ├── MessageQueue.RabbitMq.nuspec └── MessageQueue.RabbitMq.csproj ├── MessageQueue.ServiceBus ├── packages.config ├── Properties │ └── AssemblyInfo.cs ├── Helper │ ├── Defaults.cs │ └── ServiceBusConfigurationKeys.cs ├── Concrete │ ├── ServiceBusConfiguration.cs │ ├── SbMessageReceiveOptions.cs │ └── Outbound │ │ └── SbOutboundFaF.cs ├── MessageQueue.ServiceBus.nuspec └── MessageQueue.ServiceBus.csproj ├── MessageQueue.Log.Core ├── Properties │ └── AssemblyInfo.cs ├── Abstract │ ├── IQueueLogger.cs │ └── IQueueLoggerAsync.cs └── MessageQueue.Log.Core.csproj ├── MessageQueue.ZeroMq ├── Properties │ └── AssemblyInfo.cs ├── packages.config ├── Helper │ ├── ZeroMqSocketType.cs │ ├── Defaults.cs │ ├── ZeroMqConfigurationKeys.cs │ └── CommonItems.cs ├── Concrete │ ├── ZeroMqConfiguration.cs │ ├── ZmqRequestMessage.cs │ ├── ZmqMessageReceiveOptions.cs │ ├── Outbound │ │ ├── ZmqOutboundFaF.cs │ │ ├── ZmqIpOutboundFaF.cs │ │ └── ZmqOutboundRaR.cs │ └── Inbound │ │ ├── ZmqInboundRaR.cs │ │ └── ZmqInboundFaF.cs ├── MessageQueue.ZeroMq.nuspec ├── MessageQueue.ZeroMq.csproj └── Abstract │ └── BaseZeroMq.cs ├── MessageQueue.Log.NLog ├── Properties │ └── AssemblyInfo.cs ├── packages.config ├── MessageQueue.Log.NLog.nuspec ├── Concrete │ └── NQueueLogger.cs └── MessageQueue.Log.NLog.csproj ├── Tests ├── MessageQueue.Sender │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── App.config │ ├── MessageQueue.Sender.csproj │ └── Program.cs ├── MessageQueue.Receiver │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── App.config │ └── MessageQueue.Receiver.csproj ├── MessageQueue.RaR.Client │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── App.config │ ├── MessageQueue.RaR.Client.csproj │ └── Program.cs └── MessageQueue.RaR.Server │ ├── Properties │ └── AssemblyInfo.cs │ ├── App.config │ ├── MessageQueue.RaR.Server.csproj │ └── Program.cs ├── MessageQueue.CofigurationProvider.Core ├── Properties │ └── AssemblyInfo.cs ├── Abstract │ └── IQueueConfigurationProvider.cs └── MessageQueue.CofigurationProvider.Core.csproj ├── MessageQueue.CofigurationProvider.AppSettings ├── Properties │ ├── AssemblyInfo.cs │ ├── ErrorMessages.Designer.cs │ └── ErrorMessages.resx ├── Concrete │ └── AppSettingsConfigurationProvider.cs └── MessageQueue.CofigurationProvider.AppSettings.csproj ├── Shared ├── SharedAssemblyInfo.cs ├── NLog.config └── appSettings.config └── .gitignore /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /logo_banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muhamad-ahsan/dynamic-queue/HEAD/logo_banner.jpg -------------------------------------------------------------------------------- /logo_nuget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muhamad-ahsan/dynamic-queue/HEAD/logo_nuget.png -------------------------------------------------------------------------------- /logo_symbol_nuget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muhamad-ahsan/dynamic-queue/HEAD/logo_symbol_nuget.png -------------------------------------------------------------------------------- /MessageQueue.Core/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /MessageQueue.RabbitMq/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /MessageQueue.ServiceBus/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /MessageQueue.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MessageQueue.Core")] 5 | [assembly: Guid("834caa3e-15aa-4d5d-82a4-884cab986aac")] -------------------------------------------------------------------------------- /MessageQueue.Log.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MessageQueue.Log.Core")] 5 | [assembly: Guid("304aaf94-6055-4ad7-942d-6ee000cd3d75")] -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MessageQueue.ZeroMq")] 5 | [assembly: Guid("74ba1d1d-8536-4480-8f96-df2621e8fbce")] 6 | -------------------------------------------------------------------------------- /MessageQueue.Log.NLog/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MessageQueue.Log.NLog")] 5 | [assembly: Guid("e2497f7e-11b5-4850-b1fd-2d3990368970")] 6 | -------------------------------------------------------------------------------- /MessageQueue.RabbitMq/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MessageQueue.RabbitMq")] 5 | [assembly: Guid("89733e22-2d91-4ace-b4ae-646104f2591e")] 6 | -------------------------------------------------------------------------------- /Tests/MessageQueue.Sender/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MessageQueue.Sender")] 5 | [assembly: Guid("eda7c5cb-e537-454c-976e-48ab241e4aaa")] 6 | -------------------------------------------------------------------------------- /MessageQueue.ServiceBus/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MessageQueue.ServiceBus")] 5 | [assembly: Guid("dec06ed4-dfad-47d3-9277-ffd1f43ee8be")] 6 | -------------------------------------------------------------------------------- /Tests/MessageQueue.Receiver/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MessageQueue.Receiver")] 5 | [assembly: Guid("36a654ea-1acc-4f00-a31d-5805d89ce035")] 6 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Tests/MessageQueue.RaR.Client/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MessageQueue.RaR.Client")] 5 | [assembly: Guid("b88d6d9a-7fba-40c7-a5db-07625bc7278b")] 6 | -------------------------------------------------------------------------------- /Tests/MessageQueue.RaR.Server/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MessageQueue.RaR.Server")] 5 | [assembly: Guid("6c8f8685-8b2f-4767-b3cb-10a3ebd464fb")] 6 | -------------------------------------------------------------------------------- /MessageQueue.CofigurationProvider.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MessageQueue.CofigurationProvider.Core")] 5 | [assembly: Guid("e4880d7e-40ad-4936-88e7-0e6a28f5fb0a")] 6 | -------------------------------------------------------------------------------- /MessageQueue.CofigurationProvider.AppSettings/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("MessageQueue.CofigurationProvider.AppSettings")] 5 | [assembly: Guid("4fae7ce2-12fd-4434-9403-79f520b00481")] 6 | -------------------------------------------------------------------------------- /Tests/MessageQueue.RaR.Client/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tests/MessageQueue.RaR.Server/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tests/MessageQueue.Receiver/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tests/MessageQueue.Sender/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MessageQueue.Log.NLog/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MessageQueue.RabbitMq/Helper/AmqpExchangeType.cs: -------------------------------------------------------------------------------- 1 | namespace MessageQueue.RabbitMq.Helper 2 | { 3 | /// 4 | /// Represents AMQP exchange types. 5 | /// 6 | internal enum AmqpExchangeType : ushort 7 | { 8 | Direct, 9 | Fanout, 10 | Topic, 11 | Header 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Helper/ZeroMqSocketType.cs: -------------------------------------------------------------------------------- 1 | namespace MessageQueue.ZeroMq.Helper 2 | { 3 | /// 4 | /// Represents ZeroMq socket types. 5 | /// 6 | internal enum ZeroMqSocketType : ushort 7 | { 8 | Pair, 9 | Pull, 10 | Push, 11 | Dealer, 12 | Router 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Shared/SharedAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyProduct("DynamicQueue")] 5 | [assembly: AssemblyCopyright("Copyright © 2017")] 6 | [assembly: AssemblyTrademark("")] 7 | 8 | [assembly: ComVisible(false)] 9 | [assembly: AssemblyVersion("1.0.0.0")] 10 | [assembly: AssemblyFileVersion("1.0.0.0")] 11 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Concrete/ZeroMqConfiguration.cs: -------------------------------------------------------------------------------- 1 | using MessageQueue.Core.Abstract; 2 | 3 | namespace MessageQueue.ZeroMq.Concrete 4 | { 5 | /// 6 | /// Contains ZeroMq settings. 7 | /// 8 | internal sealed class ZeroMqConfiguration : MessageQueueConfiguration 9 | { 10 | #region Public Data Members 11 | #endregion 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MessageQueue.Core/Abstract/IMessageQueue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageQueue.Core.Abstract 4 | { 5 | /// 6 | /// Common interface for all different messaging queue interfaces. 7 | /// 8 | public interface IMessageQueue : IDisposable 9 | { 10 | #region Properties 11 | /// 12 | /// The queue address. 13 | /// 14 | string Address { get; } 15 | #endregion 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MessageQueue.Core/Abstract/MessageQueueConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace MessageQueue.Core.Abstract 2 | { 3 | /// 4 | /// Contains common configuration properties. 5 | /// 6 | public abstract class MessageQueueConfiguration 7 | { 8 | #region Public Data Members 9 | /// 10 | /// The address of the queue (host or server). 11 | /// 12 | public string Address { get; set; } 13 | #endregion 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MessageQueue.RabbitMq/Helper/Defaults.cs: -------------------------------------------------------------------------------- 1 | namespace MessageQueue.RabbitMq.Helper 2 | { 3 | /// 4 | /// Contains default values. 5 | /// 6 | internal static class Defaults 7 | { 8 | #region Public Data Members 9 | public const int RabbitMqConnectionTimeoutInMinutes = 3; 10 | public const int RabbitMqNetworkRecoveryIntervalInSeconds = 30; 11 | public const int MaxConcurrentReceiveCallback = 1; 12 | #endregion 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Helper/Defaults.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageQueue.ZeroMq.Helper 4 | { 5 | /// 6 | /// Contains default values. 7 | /// 8 | internal static class Defaults 9 | { 10 | #region Public Data Members 11 | public static TimeSpan ZeroMqLinger = new TimeSpan(0, 0, -1); // Need to set to avoid messages lost. 12 | public const int ZeroMqSendHighWatermark = 10000; 13 | public const int ZeroMqReceiveHighWatermark = 10000; 14 | #endregion 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MessageQueue.CofigurationProvider.Core/Abstract/IQueueConfigurationProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MessageQueue.CofigurationProvider.Core.Abstract 4 | { 5 | /// 6 | /// Provides configuration for queues initialization. 7 | /// 8 | public interface IQueueConfigurationProvider 9 | { 10 | #region Methods 11 | /// 12 | /// Returns configuration based on the configuration identifier. 13 | /// 14 | /// The configuration identifier 15 | /// Key value pair of configuration 16 | Dictionary GetConfiguration(string configurationIdentifier); 17 | #endregion 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Helper/ZeroMqConfigurationKeys.cs: -------------------------------------------------------------------------------- 1 | using MessageQueue.Core.Helper; 2 | using System.Collections.Generic; 3 | 4 | namespace MessageQueue.ZeroMq.Helper 5 | { 6 | /// 7 | /// Contains configuration keys related to ZeroMQ. 8 | /// 9 | internal static class ZeroMqConfigurationKeys 10 | { 11 | #region Keys 12 | #endregion 13 | 14 | #region Public Methods 15 | /// 16 | /// Returns all the keys available in the class. 17 | /// 18 | public static IEnumerable GetAllKeys() 19 | { 20 | #region Return 21 | return MessageQueueCommonItems.GetAllStringConstants(typeof(ZeroMqConfigurationKeys)); 22 | #endregion 23 | } 24 | #endregion 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MessageQueue.Core/Abstract/RequestMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MessageQueue.Core.Abstract 8 | { 9 | /// 10 | /// Base class for different types of request message. 11 | /// 12 | public abstract class RequestMessage 13 | { 14 | #region Public Data Members 15 | /// 16 | /// Request data. 17 | /// 18 | public TRequest RequestData { get; protected set; } 19 | #endregion 20 | 21 | #region Public Methods 22 | /// 23 | /// Responses back to the client. 24 | /// 25 | /// The response object 26 | public abstract void Response(TResponse response); 27 | #endregion 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MessageQueue.Core/Abstract/Outbound/IOutboundFaFMq.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace MessageQueue.Core.Abstract.Outbound 4 | { 5 | /// 6 | /// Interface which provides functionality to send message into queue 7 | /// in fire and forget pattern (Push-Pull, Producer-Consumer). 8 | /// 9 | /// The type of the message 10 | public interface IOutboundFaFMq : IMessageQueue 11 | { 12 | #region Methods 13 | /// 14 | /// Send message. 15 | /// 16 | /// The message 17 | void SendMessage(TMessage message); 18 | 19 | /// 20 | /// Sends message asynchronously. 21 | /// 22 | /// The message 23 | Task SendMessageAsync(TMessage message); 24 | #endregion 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MessageQueue.Core/Helper/CommonConfigurationKeys.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MessageQueue.Core.Helper 4 | { 5 | /// 6 | /// Contains configuration keys common to all implementations. 7 | /// 8 | public static class CommonConfigurationKeys 9 | { 10 | #region Keys 11 | public const string Address = "Address"; 12 | public const string QueueName = "QueueName"; 13 | public const string Implementation = "Implementation"; 14 | #endregion 15 | 16 | #region Public Methods 17 | /// 18 | /// Returns all the keys available in the class. 19 | /// 20 | public static IEnumerable GetAllKeys() 21 | { 22 | #region Return 23 | return MessageQueueCommonItems.GetAllStringConstants(typeof(CommonConfigurationKeys)); 24 | #endregion 25 | } 26 | #endregion 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /MessageQueue.RabbitMq/Helper/ContextKeys.cs: -------------------------------------------------------------------------------- 1 | using MessageQueue.Core.Helper; 2 | using System.Collections.Generic; 3 | 4 | namespace MessageQueue.RabbitMq.Helper 5 | { 6 | /// 7 | /// Contains context keys used to add contextual data in exception. 8 | /// 9 | internal static class ContextKeys 10 | { 11 | #region Keys 12 | public const string ReplyTo = "ReplyTo"; 13 | public const string ReplyCode = "ReplyCode"; 14 | public const string ReplyText = "ReplyText"; 15 | #endregion 16 | 17 | #region Public Methods 18 | /// 19 | /// Returns all the keys available in the class. 20 | /// 21 | public static IEnumerable GetAllKeys() 22 | { 23 | #region Return 24 | return MessageQueueCommonItems.GetAllStringConstants(typeof(ContextKeys)); 25 | #endregion 26 | } 27 | #endregion 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MessageQueue.RabbitMq/Concrete/RabbitMqConfiguration.cs: -------------------------------------------------------------------------------- 1 | using MessageQueue.Core.Abstract; 2 | 3 | namespace MessageQueue.RabbitMq.Concrete 4 | { 5 | /// 6 | /// Contains RabbitMq configuration. 7 | /// 8 | internal class RabbitMqConfiguration : MessageQueueConfiguration 9 | { 10 | #region Public Data Members 11 | public int Port { get; set; } 12 | public string UserName { get; set; } 13 | public string Password { get; set; } 14 | public string QueueName { get; set; } 15 | public string ExchangeName { get; set; } 16 | public string RoutingKey { get; set; } 17 | public bool DurableQueue { get; set; } 18 | public bool DurableExchange { get; set; } 19 | public bool DurableMessage { get; set; } 20 | public bool Acknowledgment { get; set; } 21 | public int ConnectionTimeoutInMinutes { get; set; } 22 | public ushort MaxConcurrentReceiveCallback { get; set; } 23 | #endregion 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /MessageQueue.ServiceBus/Helper/Defaults.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageQueue.ServiceBus.Helper 4 | { 5 | /// 6 | /// Contains default values. 7 | /// 8 | internal static class Defaults 9 | { 10 | #region Public Data Members 11 | public const short MaxDeliveryCount = 5; 12 | public const long MaxSizeInMegabytes = 1024; // This is the minimum as of 25-Jan-2017 13 | public static TimeSpan LockDurationInSeconds = TimeSpan.FromSeconds(300); // 5 minutes and this is the max value as of 25-Jan-2017 14 | public static TimeSpan MessageTimeToLive = TimeSpan.FromDays(30); 15 | public const bool Acknowledgment = true; 16 | public const bool EnablePartitioning = false; 17 | public const bool EnableDeadLettering = true; 18 | public const bool EnableBatchedOperations = false; 19 | public const bool RequiresDuplicateDetection = false; 20 | public const int MaxConcurrentReceiveCallback = 1; 21 | #endregion 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /MessageQueue.Core/Abstract/Outbound/IOutboundRaRMq.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageQueue.Core.Abstract.Outbound 4 | { 5 | /// 6 | /// Interface which provides functionality to send message into queue 7 | /// in request-response pattern. 8 | /// 9 | /// The expected type of the response 10 | /// The type of the request message 11 | public interface IOutboundRaRMq : IMessageQueue 12 | { 13 | #region Events 14 | /// 15 | /// Event that will be triggered when response message would be received from the queue. 16 | /// 17 | event Action OnResponseReady; 18 | #endregion 19 | 20 | #region Methods 21 | /// 22 | /// Send request message. 23 | /// 24 | /// The message 25 | void SendRequest(TRequest message); 26 | #endregion 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /MessageQueue.ServiceBus/Concrete/ServiceBusConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageQueue.Core.Abstract; 3 | 4 | namespace MessageQueue.ServiceBus.Concrete 5 | { 6 | /// 7 | /// Contains ServiceBus settings. 8 | /// 9 | internal sealed class ServiceBusConfiguration : MessageQueueConfiguration 10 | { 11 | #region Public Data Members 12 | public string QueueName { get; set; } 13 | public bool Acknowledgment { get; set; } 14 | public string NamespaceAddress { get; set; } 15 | public short MaxDeliveryCount { get; set; } 16 | public long MaxSizeInMegabytes { get; set; } 17 | public bool EnableDeadLettering { get; set; } 18 | public bool EnablePartitioning { get; set; } 19 | public bool RequiresDuplicateDetection { get; set; } 20 | public bool EnableBatchedOperations { get; set; } 21 | public TimeSpan MessageTimeToLiveInMinutes { get; set; } 22 | public TimeSpan LockDurationInSeconds { get; set; } 23 | public ushort MaxConcurrentReceiveCallback { get; set; } 24 | #endregion 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MessageQueue.Core/Concrete/NoLog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageQueue.Log.Core.Abstract; 3 | 4 | namespace MessageQueue.Core.Concrete 5 | { 6 | /// 7 | /// Dummy logger to be used when no logger is passed. 8 | /// 9 | internal sealed class NoLog : IQueueLogger 10 | { 11 | #region IQueueLogger Implementation 12 | public void Error(Exception exception, string message, params object[] args) 13 | { 14 | // Swallow... 15 | } 16 | 17 | public void Fatal(Exception exception, string message, params object[] args) 18 | { 19 | // Swallow... 20 | } 21 | 22 | public void Info(Exception exception, string message, params object[] args) 23 | { 24 | // Swallow... 25 | } 26 | 27 | public void Trace(Exception exception, string message, params object[] args) 28 | { 29 | // Swallow... 30 | } 31 | 32 | public void Warn(Exception exception, string message, params object[] args) 33 | { 34 | // Swallow... 35 | } 36 | #endregion 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MessageQueue.Log.NLog/MessageQueue.Log.NLog.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DynamicQueue.Log.NLog 5 | 1.0.0.0 6 | DynamicQueue logging using NLog 7 | muhamad.ahsan 8 | https://github.com/muhamad-ahsan/dynamic-queue/blob/master/LICENSE 9 | https://github.com/muhamad-ahsan/dynamic-queue 10 | false 11 | NLog based logging in Dynamic Queue. 12 | The initial release. 13 | Copyright 2017 14 | DynamicQueue ZeroMq Queue Dynamic 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /MessageQueue.Core/Concrete/QueueException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace MessageQueue.Core.Concrete 5 | { 6 | /// 7 | /// Standard exception class for all the exceptions thrown from module. 8 | /// 9 | public sealed class QueueException : Exception 10 | { 11 | #region Public Data Members 12 | /// 13 | /// The exception error code. 14 | /// 15 | public QueueErrorCode ErrorCode { get; } 16 | #endregion 17 | 18 | #region Constructors 19 | public QueueException(QueueErrorCode errorCode, string message, Exception innerException = null, Dictionary context = null) : base(message, innerException) 20 | { 21 | #region Initialization 22 | ErrorCode = errorCode; 23 | 24 | if (context != null) 25 | { 26 | foreach (var currentKeyValuePair in context) 27 | { 28 | Data.Add(currentKeyValuePair.Key, currentKeyValuePair.Value); 29 | } 30 | } 31 | #endregion 32 | } 33 | #endregion 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Shared/NLog.config: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | 14 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MessageQueue.Core/Helper/CommonContextKeys.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MessageQueue.Core.Helper 4 | { 5 | /// 6 | /// Contains context keys used to add contextual data in exception, common to all implementations. 7 | /// 8 | public static class CommonContextKeys 9 | { 10 | #region Keys 11 | public const string Address = "Address"; 12 | public const string QueueName = "QueueName"; 13 | public const string RoutingKey = "RoutingKey"; 14 | public const string ExchangeName = "ExchangeName"; 15 | public const string QueueContext = "QueueContext"; 16 | public const string ParameterName = "ParameterName"; 17 | public const string ReplyQueueName = "ReplyQueueName"; 18 | public const string NotSupportedParameters = "NotSupportedParameter(s)"; 19 | #endregion 20 | 21 | #region Public Methods 22 | /// 23 | /// Returns all the keys available in the class. 24 | /// 25 | public static IEnumerable GetAllKeys() 26 | { 27 | #region Return 28 | return MessageQueueCommonItems.GetAllStringConstants(typeof(CommonContextKeys)); 29 | #endregion 30 | } 31 | #endregion 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /MessageQueue.Core/Abstract/IMessageReceiveOptions.cs: -------------------------------------------------------------------------------- 1 | namespace MessageQueue.Core.Abstract 2 | { 3 | /// 4 | /// Generic interface which provides different options on message receive. 5 | /// 6 | public interface IMessageReceiveOptions 7 | { 8 | #region Properties 9 | /// 10 | /// Returns true if message acknowledgment is configured; false otherwise. 11 | /// 12 | bool IsAcknowledgmentConfigured { get; } 13 | #endregion 14 | 15 | #region Methods 16 | /// 17 | /// Acknowledges message. 18 | /// If acknowledgment is not configured, it will throw exception 19 | /// NOTE: Any exception will be swallowed if ignoreError is set to true (default). 20 | /// 21 | void Acknowledge(bool ignoreError = true); 22 | 23 | /// 24 | /// When acknowledgment is configured and processing is failed due to any reason, 25 | /// calling this method will abandon the lock and message will be released from lock. 26 | /// If acknowledgment is not configured, it will throw exception 27 | /// NOTE: Any exception will be swallowed if ignoreError is set to true (default). 28 | /// 29 | void AbandonAcknowledgment(bool ignoreError = true); 30 | #endregion 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /MessageQueue.RabbitMq/MessageQueue.RabbitMq.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DynamicQueue.RabbitMq 5 | 1.0.0.0 6 | DynamicQueue using RabbitMq 7 | muhamad.ahsan 8 | https://github.com/muhamad-ahsan/dynamic-queue/blob/master/LICENSE 9 | https://github.com/muhamad-ahsan/dynamic-queue 10 | false 11 | RabbitMq based implementation of Dynamic Queue. 12 | The initial release. 13 | Copyright 2017 14 | DynamicQueue RabbitMq Queue Dynamic 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /MessageQueue.ServiceBus/MessageQueue.ServiceBus.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DynamicQueue.ServiceBus 5 | 1.0.0.0 6 | DynamicQueue using Microsoft ServiceBus 7 | muhamad.ahsan 8 | https://github.com/muhamad-ahsan/dynamic-queue/blob/master/LICENSE 9 | https://github.com/muhamad-ahsan/dynamic-queue 10 | false 11 | Microsoft ServiceBus based implementation of Dynamic Queue. 12 | The initial release. 13 | Copyright 2017 14 | DynamicQueue ServiceBus Queue Dynamic 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/MessageQueue.ZeroMq.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DynamicQueue.ZeroMq 5 | 1.0.0.0 6 | DynamicQueue using ZeroMq 7 | muhamad.ahsan 8 | https://github.com/muhamad-ahsan/dynamic-queue/blob/master/LICENSE 9 | https://github.com/muhamad-ahsan/dynamic-queue 10 | false 11 | ZeroMq based implementation of Dynamic Queue. 12 | The initial release. 13 | Copyright 2017 14 | DynamicQueue ZeroMq Queue Dynamic 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MessageQueue.Core/Abstract/Inbound/IInboundRaRMq.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageQueue.Core.Abstract.Inbound 4 | { 5 | /// 6 | /// Interface which provides functionality to receive message from queue 7 | /// and response to client in request-response pattern. 8 | /// 9 | /// The expected type of the request 10 | /// The type of the response 11 | public interface IInboundRaRMq : IMessageQueue 12 | { 13 | #region Events 14 | /// 15 | /// Event that will be triggered when request message would be received from the queue. 16 | /// 17 | event Action> OnRequestReady; 18 | #endregion 19 | 20 | #region Methods 21 | /// 22 | /// Will start listening the queue for messages. 23 | /// 24 | void StartReceivingRequest(); 25 | 26 | /// 27 | /// Will stop listening the queue for messages. 28 | /// 29 | void StopReceivingRequest(); 30 | 31 | /// 32 | /// Will check if the queue has any message. 33 | /// NOTE: This method will check for the message regardless of queue listening status (start or stop). 34 | /// 35 | /// True if there is message; otherwise false. 36 | bool HasMessage(); 37 | #endregion 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MessageQueue.RabbitMq/Helper/RabbitMqConfigurationKeys.cs: -------------------------------------------------------------------------------- 1 | using MessageQueue.Core.Helper; 2 | using System.Collections.Generic; 3 | 4 | namespace MessageQueue.RabbitMq.Helper 5 | { 6 | /// 7 | /// Contains configuration keys related to RabbitMq. 8 | /// 9 | internal static class RabbitMqConfigurationKeys 10 | { 11 | #region Keys 12 | public const string Port = "Port"; 13 | public const string Password = "Password"; 14 | public const string UserName = "UserName"; 15 | public const string ExchangeName = "ExchangeName"; 16 | public const string Acknowledgment = "Acknowledgment"; 17 | public const string RoutingKey = "RoutingKey"; 18 | public const string DurableExchange = "DurableExchange"; 19 | public const string DurableQueue = "DurableQueue"; 20 | public const string DurableMessage = "DurableMessage"; 21 | public const string ConnectionTimeoutInMinutes = "ConnectionTimeoutInMinutes"; 22 | public const string MaxConcurrentReceiveCallback = "MaxConcurrentReceiveCallback"; 23 | #endregion 24 | 25 | #region Public Methods 26 | /// 27 | /// Returns all the keys available in the class. 28 | /// 29 | public static IEnumerable GetAllKeys() 30 | { 31 | #region Return 32 | return MessageQueueCommonItems.GetAllStringConstants(typeof(RabbitMqConfigurationKeys)); 33 | #endregion 34 | } 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /MessageQueue.ServiceBus/Helper/ServiceBusConfigurationKeys.cs: -------------------------------------------------------------------------------- 1 | using MessageQueue.Core.Helper; 2 | using System.Collections.Generic; 3 | 4 | namespace MessageQueue.ServiceBus.Helper 5 | { 6 | /// 7 | /// Contains configuration keys related to ServiceBus. 8 | /// 9 | internal static class ServiceBusConfigurationKeys 10 | { 11 | #region Keys 12 | public const string EnableDeadLettering = "EnableDeadLettering"; 13 | public const string MessageTimeToLiveInMinutes = "MessageTimeToLiveInMinutes"; 14 | public const string Acknowledgment = "Acknowledgment"; 15 | public const string LockDurationInSeconds = "LockDurationInSeconds"; 16 | public const string MaxDeliveryCount = "MaxDeliveryCount"; 17 | public const string MaxSizeInMegabytes = "MaxSizeInMegabytes"; 18 | public const string EnablePartitioning = "EnablePartitioning"; 19 | public const string EnableBatchedOperations = "EnableBatchedOperations"; 20 | public const string RequiresDuplicateDetection = "RequiresDuplicateDetection"; 21 | public const string NamespaceAddress = "NamespaceAddress"; 22 | public const string MaxConcurrentReceiveCallback = "MaxConcurrentReceiveCallback"; 23 | #endregion 24 | 25 | #region Public Methods 26 | /// 27 | /// Returns all the keys available in the class. 28 | /// 29 | public static IEnumerable GetAllKeys() 30 | { 31 | #region Return 32 | return MessageQueueCommonItems.GetAllStringConstants(typeof(ServiceBusConfigurationKeys)); 33 | #endregion 34 | } 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /MessageQueue.Core/Abstract/Inbound/IInboundFaFMq.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace MessageQueue.Core.Abstract.Inbound 5 | { 6 | /// 7 | /// Interface which provides functionality to receive message from queue 8 | /// in fire and forget pattern (Push-Pull, Producer-Consumer). 9 | /// 10 | /// The type of the message 11 | public interface IInboundFaFMq : IMessageQueue 12 | { 13 | #region Events 14 | /// 15 | /// Event that will be triggered when message would be received from the queue. 16 | /// 17 | event Action OnMessageReady; 18 | 19 | /// 20 | /// Asynchronous event that will be triggered when message would be received from the queue. 21 | /// NOTE: If handler is registered with both events (sync and asyns) then async will be triggered only. 22 | /// 23 | event Func OnMessageReadyAsync; 24 | #endregion 25 | 26 | #region Methods 27 | /// 28 | /// Will start listening the queue for messages. 29 | /// 30 | void StartReceivingMessage(); 31 | 32 | /// 33 | /// Will stop listening the queue for messages. 34 | /// 35 | void StopReceivingMessage(); 36 | 37 | /// 38 | /// Will check if the queue has any message. 39 | /// NOTE: This method will check for the message regardless of queue listening status (start or stop). 40 | /// 41 | /// True if there is message; otherwise false. 42 | bool HasMessage(); 43 | #endregion 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /MessageQueue.Core/Helper/InterfaceImplementationInfo.cs: -------------------------------------------------------------------------------- 1 | namespace MessageQueue.Core.Helper 2 | { 3 | /// 4 | /// Contains fully qualified class name with assembly name of different implementation of message queue interfaces. 5 | /// This is just a helper class to find easily different implementation details of queue interfaces. 6 | /// 7 | public static class InterfaceImplementationInfo 8 | { 9 | #region ZeroMq (NetMq) 10 | // Inbound 11 | public const string InboundFaFZeroMq = "MessageQueue.ZeroMq.Concrete.Inbound.ZmqInboundFaF`1, MessageQueue.ZeroMq"; 12 | public const string InboundRaRZeroMq = "MessageQueue.ZeroMq.Concrete.Inbound.ZmqInboundRaR`2, MessageQueue.ZeroMq"; 13 | 14 | // Outbound 15 | public const string OutboundFaFZeroMq = "MessageQueue.ZeroMq.Concrete.Outbound.ZmqOutboundFaF`1, MessageQueue.ZeroMq"; 16 | public const string OutboundRaRZeroMq = "MessageQueue.ZeroMq.Concrete.Outbound.ZmqOutboundRaR`2, MessageQueue.ZeroMq"; 17 | #endregion 18 | 19 | #region RabbitMq 20 | // Inbound 21 | public const string InboundFaFRabbitMq = "MessageQueue.RabbitMq.Concrete.Inbound.RmqInboundFaF`1, MessageQueue.RabbitMq"; 22 | public const string InboundRaRRabbitMq = "MessageQueue.RabbitMq.Concrete.Inbound.RmqInboundRaR`2, MessageQueue.RabbitMq"; 23 | 24 | // Outbound 25 | public const string OutboundFaFRabbitMq = "MessageQueue.RabbitMq.Concrete.Outbound.RmqOutboundFaF`1, MessageQueue.RabbitMq"; 26 | public const string OutboundRaRRabbitMq = "MessageQueue.RabbitMq.Concrete.Outbound.RmqOutboundRaR`2, MessageQueue.RabbitMq"; 27 | #endregion 28 | 29 | #region ServiceBus 30 | // Inbound 31 | public const string InboundFaFServiceBus = "MessageQueue.ServiceBus.Concrete.Inbound.SbInboundFaF`1, MessageQueue.ServiceBus"; 32 | 33 | // Outbound 34 | public const string OutboundFaFServiceBus = "MessageQueue.ServiceBus.Concrete.Outbound.SbOutboundFaF`1, MessageQueue.ServiceBus"; 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /MessageQueue.Log.Core/Abstract/IQueueLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageQueue.Log.Core.Abstract 4 | { 5 | /// 6 | /// Logging interface for different level of logging (trace, error etc.). 7 | /// 8 | public interface IQueueLogger 9 | { 10 | #region Methods 11 | /// 12 | /// Logs provided data as Trace logging level. 13 | /// 14 | /// The exception 15 | /// The message 16 | /// The place holder values in message 17 | void Trace(Exception exception, string message, params object[] args); 18 | 19 | /// 20 | /// Logs provided data as Info logging level. 21 | /// 22 | /// The exception 23 | /// The message 24 | /// The place holder values in message 25 | void Info(Exception exception, string message, params object[] args); 26 | 27 | /// 28 | /// Logs provided data as Warning logging level. 29 | /// 30 | /// The exception 31 | /// The message 32 | /// The place holder values in message 33 | void Warn(Exception exception, string message, params object[] args); 34 | 35 | /// 36 | /// Logs provided data as Error logging level. 37 | /// 38 | /// The exception 39 | /// The message 40 | /// The place holder values in message 41 | void Error(Exception exception, string message, params object[] args); 42 | 43 | /// 44 | /// Logs provided data as Fatal logging level. 45 | /// 46 | /// The exception 47 | /// The message 48 | /// The place holder values in message 49 | void Fatal(Exception exception, string message, params object[] args); 50 | #endregion 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /MessageQueue.Core/Concrete/QueueErrorCode.cs: -------------------------------------------------------------------------------- 1 | namespace MessageQueue.Core.Concrete 2 | { 3 | /// 4 | /// Queue exception error codes. 5 | /// 6 | public enum QueueErrorCode : ushort 7 | { 8 | // Instantiation related 9 | FailedToInstantiateInboundFaFMq, 10 | FailedToInstantiateOutboundFaFMq, 11 | FailedToInstantiateInboundRaRMq, 12 | FailedToInstantiateOutboundRaRMq, 13 | 14 | // Initialization related 15 | FailedToInitializeMessageQueue, 16 | 17 | // Configuration related 18 | NotSupportedConfigurationParameters, 19 | MissingRequiredConfigurationParameter, 20 | InvalidValueForConfigurationParameter, 21 | ParameterNotApplicationInCurrentConfiguration, 22 | ParameterRequiredInCurrentConfiguration, 23 | FailedToExtractConstantFields, 24 | GeneralConfigurationParsingError, 25 | 26 | // Serialization related 27 | FailedToSerializeObjectIntoJsonString, 28 | FailedToSerializeObjectIntoJsonBytes, 29 | FailedToDeserializeJsonString, 30 | FailedToDeserializeJsonBytes, 31 | FailedToSerializeMessage, 32 | FailedToDeserializeMessage, 33 | 34 | // Message related 35 | FailedToReceiveMessage, 36 | FailedToSendMessage, 37 | FailedToReceiveRequestMessage, 38 | FailedToReceiveResponseMessage, 39 | FailedToSendResponseMessage, 40 | 41 | // Queue related 42 | MessageQueueIsNotInitialized, 43 | FailedToCreateMessageQueue, 44 | FailedToStartReceivingMessage, 45 | FailedToStartReceivingRequest, 46 | FailedToStopReceivingMessage, 47 | FailedToStopReceivingRequest, 48 | FailedToStipReceivingRequest, 49 | FailedToCheckQueueExistence, 50 | FailedToCheckExchangeExistence, 51 | FailedToCheckQueueHasMessage, 52 | FailedToCreateExchange, 53 | QueueDoesNotExist, 54 | ExchangeDoesNotExist, 55 | AcknowledgmentIsNotConfiguredForQueue, 56 | FailedToAcknowledgeMessage, 57 | FailedToAbandonMessageAcknowledgment, 58 | MessageReturnedFromQueue, 59 | 60 | // ZeroMq related 61 | InvalidZeroMqSocketType, 62 | FailedToCreateZeroMqSocket, 63 | 64 | // ServiceBus related 65 | MissingNamespaceAddressInConfiguration, 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /MessageQueue.Log.Core/Abstract/IQueueLoggerAsync.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace MessageQueue.Log.Core.Abstract 5 | { 6 | /// 7 | /// Asynchronous logging interface for different level of logging (trace, error etc.). 8 | /// 9 | public interface IQueueLoggerAsync 10 | { 11 | #region Methods 12 | /// 13 | /// Logs provided data asynchronously as Trace logging level. 14 | /// 15 | /// The exception 16 | /// The message 17 | /// The place holder values in message 18 | Task TraceAsync(Exception exception, string message, params object[] args); 19 | 20 | /// 21 | /// Logs provided data asynchronously as Info logging level. 22 | /// 23 | /// The exception 24 | /// The message 25 | /// The place holder values in message 26 | Task InfoAsync(Exception exception, string message, params object[] args); 27 | 28 | /// 29 | /// Logs provided data asynchronously as Warning logging level. 30 | /// 31 | /// The exception 32 | /// The message 33 | /// The place holder values in message 34 | Task WarnAsync(Exception exception, string message, params object[] args); 35 | 36 | /// 37 | /// Logs provided data asynchronously as Error logging level. 38 | /// 39 | /// The exception 40 | /// The message 41 | /// The place holder values in message 42 | Task ErrorAsync(Exception exception, string message, params object[] args); 43 | 44 | /// 45 | /// Logs provided data asynchronously as Fatal logging level. 46 | /// 47 | /// The exception 48 | /// The message 49 | /// The place holder values in message 50 | Task FatalAsync(Exception exception, string message, params object[] args); 51 | #endregion 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /MessageQueue.CofigurationProvider.AppSettings/Concrete/AppSettingsConfigurationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Configuration; 4 | using System.Collections.Generic; 5 | using MessageQueue.CofigurationProvider.Core.Abstract; 6 | using MessageQueue.CofigurationProvider.AppSettings.Properties; 7 | 8 | namespace MessageQueue.CofigurationProvider.AppSettings.Concrete 9 | { 10 | /// 11 | /// Implementation of IQueueConfigurationProvider provider which returns configuration from .config file (app or web). 12 | /// 13 | public class AppSettingsConfigurationProvider : IQueueConfigurationProvider 14 | { 15 | #region Private Data Members 16 | private const string configIdentiferKeySeparator = ":"; 17 | #endregion 18 | 19 | #region IQueueConfigurationProvider Implementation 20 | public Dictionary GetConfiguration(string configurationIdentifier) 21 | { 22 | try 23 | { 24 | #region Business Description 25 | // 1- All the keys in appSettings should be prefixed with configuration identifier 26 | // and separated by ":". E.g. MyConfig:Key1, MyConfig:Key2 and so on. 27 | #endregion 28 | 29 | #region Validation 30 | if (string.IsNullOrEmpty(configurationIdentifier)) 31 | { 32 | throw new ArgumentNullException(nameof(configurationIdentifier)); 33 | } 34 | #endregion 35 | 36 | #region Configuration Retrieval 37 | configurationIdentifier = configurationIdentifier.ToUpper(); 38 | var appSettings = ConfigurationManager.AppSettings; 39 | 40 | return ConfigurationManager.AppSettings 41 | .AllKeys 42 | .Where(x => x.ToUpper().Contains(configurationIdentifier)) 43 | .ToDictionary( 44 | key => key.Substring(key.IndexOf(configIdentiferKeySeparator, StringComparison.Ordinal) + 1), 45 | val => appSettings[val]); 46 | #endregion 47 | } 48 | catch (Exception exception) 49 | { 50 | throw new ApplicationException(string.Format(ErrorMessages.FailedToReadConfiguration, configurationIdentifier), exception); 51 | } 52 | } 53 | #endregion 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Helper/CommonItems.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageQueue.Core.Helper; 3 | using System.Collections.Generic; 4 | using MessageQueue.Core.Concrete; 5 | using MessageQueue.Core.Properties; 6 | using MessageQueue.ZeroMq.Concrete; 7 | using MessageQueue.Log.Core.Abstract; 8 | 9 | namespace MessageQueue.ZeroMq.Helper 10 | { 11 | /// 12 | /// Contains common functionality. 13 | /// 14 | internal static class CommonItems 15 | { 16 | #region Public Data Members 17 | public const string ZeroMqName = "ZeroMq"; 18 | #endregion 19 | 20 | #region Public Methods 21 | /// 22 | /// Helper method to validate and collect ZeroMq parameters. 23 | /// 24 | public static ZeroMqConfiguration CollectZmqConfiguration(ref Dictionary rawConfiguration, bool isInbound, ref IQueueLogger logger) 25 | { 26 | try 27 | { 28 | #region Initialization 29 | var zeroMqConfiguration = new ZeroMqConfiguration(); 30 | rawConfiguration = rawConfiguration ?? new Dictionary(); 31 | #endregion 32 | 33 | #region Collecting Common Configuration 34 | MessageQueueCommonItems.CollectCommonConfiguration(ref rawConfiguration, zeroMqConfiguration, ZeroMqConfigurationKeys.GetAllKeys()); 35 | #endregion 36 | 37 | #region Collecting Other Configuration 38 | // Nothing to collect. 39 | #endregion 40 | 41 | #region Return 42 | return zeroMqConfiguration; 43 | #endregion 44 | } 45 | catch (QueueException queueException) 46 | { 47 | #region Adding Context Data 48 | queueException.Data.Add(CommonContextKeys.QueueContext, ZeroMqName); 49 | #endregion 50 | 51 | #region Logging - Error 52 | logger.Error(queueException, queueException.Message); 53 | #endregion 54 | 55 | throw; 56 | } 57 | catch (Exception ex) 58 | { 59 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 60 | QueueErrorCode.GeneralConfigurationParsingError 61 | , ErrorMessages.GeneralConfigurationParsingError, ex, ZeroMqName, logger: logger); 62 | } 63 | } 64 | #endregion 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /MessageQueue.CofigurationProvider.AppSettings/obj/Debug 6 | *.vspscc 7 | /MessageQueue.CofigurationProvider.AppSettings/MessageQueue.CofigurationProvider.AppSettings.csproj.vspscc 8 | /MessageQueue.CofigurationProvider.AppSettings/MessageQueue.CofigurationProvider.AppSettings.csproj.vspscc 9 | /MessageQueue.CofigurationProvider.Core/obj/Debug 10 | /MessageQueue.Core/obj/Debug 11 | /packages 12 | /Tests/MessageQueue.RaR.Client/bin/Release 13 | /Tests/MessageQueue.RaR.Client/obj/Release 14 | /MessageQueue.ZeroMq/DynamicQueue.ZeroMq.1.0.0/lib 15 | /MessageQueue.ZeroMq/DynamicQueue.ZeroMq.1.0.0/package/services/metadata/core-properties 16 | /MessageQueue.ZeroMq/DynamicQueue.ZeroMq.1.0.0/_rels 17 | /MessageQueue.ZeroMq/DynamicQueue.ZeroMq.1.0.0/[Content_Types].xml 18 | /.vs/DynamicQueue/v15 19 | /MessageQueue.CofigurationProvider.AppSettings/obj/Release/TempPE 20 | /MessageQueue.CofigurationProvider.Core/obj/Release 21 | /MessageQueue.CofigurationProvider.AppSettings/obj/Release 22 | /MessageQueue.Core/obj/Release 23 | /MessageQueue.Log.Core/obj/Release 24 | /MessageQueue.Log.NLog/nuget.exe 25 | *.user 26 | /MessageQueue.Log.NLog/DynamicQueue.Log.NLog.1.0.0.nupkg 27 | /MessageQueue.Log.NLog/obj/Release 28 | /MessageQueue.RabbitMq/obj/Release 29 | /MessageQueue.ServiceBus/obj 30 | /MessageQueue.RabbitMq/nuget.exe 31 | /MessageQueue.RabbitMq/DynamicQueue.RabbitMq.1.0.0.nupkg 32 | /MessageQueue.ServiceBus/nuget.exe 33 | /MessageQueue.ServiceBus/DynamicQueue.ServiceBus.1.0.0.nupkg 34 | /MessageQueue.ZeroMq/nuget.exe 35 | /Tests/MessageQueue.RaR.Server/obj/Release 36 | /Tests/MessageQueue.RaR.Server/bin/Release 37 | /Tests/MessageQueue.Sender/obj/Release 38 | /Tests/MessageQueue.Sender/bin/Debug 39 | /Tests/MessageQueue.Receiver/obj/Release 40 | /Tests/MessageQueue.Receiver/bin/Release 41 | /_Output/bin/Release 42 | /MessageQueue.ZeroMq/DynamicQueue.ZeroMq.1.0.0 43 | /MessageQueue.ZeroMq/obj/Release 44 | /MessageQueue.Log.Core/obj/Debug 45 | /MessageQueue.Log.NLog/obj/Debug 46 | /MessageQueue.RabbitMq/obj/Debug 47 | /MessageQueue.ZeroMq/obj/Debug 48 | /Tests/MessageQueue.RaR.Client/bin/Debug/logs 49 | /Tests/MessageQueue.RaR.Client/bin/Debug 50 | /Tests/MessageQueue.RaR.Client/obj/Debug 51 | /Tests/MessageQueue.RaR.Server/bin/Debug 52 | /Tests/MessageQueue.Receiver/bin/Debug 53 | /Tests/MessageQueue.RaR.Server/obj/Debug 54 | /Tests/MessageQueue.Receiver/obj/Debug 55 | /_Output/bin/Debug 56 | /Tests/MessageQueue.Sender/obj/Debug 57 | /.vs/slnx.sqlite 58 | /.vs/slnx.sqlite-journal 59 | -------------------------------------------------------------------------------- /MessageQueue.Log.Core/MessageQueue.Log.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {304AAF94-6055-4AD7-942D-6EE000CD3D75} 8 | Library 9 | Properties 10 | MessageQueue.Log.Core 11 | MessageQueue.Log.Core 12 | v4.5.2 13 | 512 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | true 21 | full 22 | false 23 | ..\_Output\bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | pdbonly 30 | true 31 | ..\_Output\bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Properties\SharedAssemblyInfo.cs 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Concrete/ZmqRequestMessage.cs: -------------------------------------------------------------------------------- 1 | using NetMQ; 2 | using System; 3 | using MessageQueue.Core.Helper; 4 | using MessageQueue.Core.Abstract; 5 | using MessageQueue.ZeroMq.Helper; 6 | using MessageQueue.Core.Concrete; 7 | using MessageQueue.Core.Properties; 8 | using MessageQueue.Log.Core.Abstract; 9 | 10 | namespace MessageQueue.ZeroMq.Concrete 11 | { 12 | /// 13 | /// RequestMessage implementation for ZeroMq. 14 | /// 15 | internal sealed class ZmqRequestMessage : RequestMessage 16 | { 17 | #region Private Data Members 18 | private IQueueLogger logger; 19 | private NetMQFrame clientAddress; 20 | private NetMQSocket responseChannel; 21 | #endregion 22 | 23 | #region Constructors 24 | internal ZmqRequestMessage(NetMQFrame clientAddress, NetMQSocket responseChannel, TRequest requestData, ref IQueueLogger loggerObject) 25 | { 26 | #region Initialization 27 | logger = loggerObject; 28 | RequestData = requestData; 29 | this.clientAddress = clientAddress; 30 | this.responseChannel = responseChannel; 31 | #endregion 32 | } 33 | #endregion 34 | 35 | #region RequestMessage Implementation 36 | public override void Response(TResponse response) 37 | { 38 | try 39 | { 40 | #region Sending Response 41 | // Preparing response. 42 | var messageToClient = new NetMQMessage(); 43 | messageToClient.Append(clientAddress); 44 | messageToClient.AppendEmptyFrame(); 45 | messageToClient.Append(MessageQueueCommonItems.SerializeToJson(response)); 46 | 47 | // Sending response. 48 | responseChannel.SendMultipartMessage(messageToClient); 49 | #endregion 50 | } 51 | catch (QueueException queueException) 52 | { 53 | #region Logging - Error 54 | logger.Error(queueException, queueException.Message); 55 | #endregion 56 | 57 | throw; 58 | } 59 | catch (Exception ex) 60 | { 61 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 62 | errorCode: QueueErrorCode.FailedToSendResponseMessage, 63 | message: ErrorMessages.FailedToSendResponseMessage, 64 | innerException: ex, 65 | queueContext: CommonItems.ZeroMqName, 66 | logger: logger); 67 | } 68 | } 69 | #endregion 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /MessageQueue.Log.NLog/Concrete/NQueueLogger.cs: -------------------------------------------------------------------------------- 1 | using NLog; 2 | using System; 3 | using System.Threading.Tasks; 4 | using MessageQueue.Log.Core.Abstract; 5 | 6 | namespace MessageQueue.Log.NLog.Concrete 7 | { 8 | public class NQueueLogger : IQueueLogger, IQueueLoggerAsync 9 | { 10 | #region Private Data Members 11 | private readonly Logger logger; 12 | #endregion 13 | 14 | #region Constructors 15 | public NQueueLogger(string loggerIdentifier) 16 | { 17 | #region Initialization 18 | logger = LogManager.GetLogger(loggerIdentifier); 19 | #endregion 20 | } 21 | #endregion 22 | 23 | #region IQueueLogger Implementation 24 | public void Trace(Exception exception, string message, params object[] args) 25 | { 26 | logger.Trace(exception, message, args); 27 | } 28 | 29 | public void Info(Exception exception, string message, params object[] args) 30 | { 31 | logger.Info(exception, message, args); 32 | } 33 | 34 | public void Warn(Exception exception, string message, params object[] args) 35 | { 36 | logger.Warn(exception, message, args); 37 | } 38 | 39 | public void Error(Exception exception, string message, params object[] args) 40 | { 41 | logger.Error(exception, message, args); 42 | } 43 | 44 | public void Fatal(Exception exception, string message, params object[] args) 45 | { 46 | logger.Fatal(exception, message, args); 47 | } 48 | #endregion 49 | 50 | #region IQueueLoggerAsync Implementation 51 | public async Task TraceAsync(Exception exception, string message, params object[] args) 52 | { 53 | await Task.Run(() => logger.Trace(exception, message, args)); 54 | } 55 | 56 | public async Task InfoAsync(Exception exception, string message, params object[] args) 57 | { 58 | await Task.Run(() => logger.Info(exception, message, args)); 59 | } 60 | 61 | public async Task WarnAsync(Exception exception, string message, params object[] args) 62 | { 63 | await Task.Run(() => logger.Warn(exception, message, args)); 64 | } 65 | 66 | public async Task ErrorAsync(Exception exception, string message, params object[] args) 67 | { 68 | await Task.Run(() => logger.Error(exception, message, args)); 69 | } 70 | 71 | public async Task FatalAsync(Exception exception, string message, params object[] args) 72 | { 73 | await Task.Run(() => logger.Fatal(exception, message, args)); 74 | } 75 | #endregion 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /MessageQueue.CofigurationProvider.Core/MessageQueue.CofigurationProvider.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E4880D7E-40AD-4936-88E7-0E6A28F5FB0A} 8 | Library 9 | Properties 10 | MessageQueue.CofigurationProvider.Core 11 | MessageQueue.CofigurationProvider.Core 12 | v4.5.2 13 | 512 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | true 21 | full 22 | false 23 | ..\_Output\bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | pdbonly 30 | true 31 | ..\_Output\bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | Properties\SharedAssemblyInfo.cs 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /MessageQueue.Core/Properties/InfoMessages.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MessageQueue.Core.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | public class InfoMessages { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal InfoMessages() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | public static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MessageQueue.Core.Properties.InfoMessages", typeof(InfoMessages).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | public static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /MessageQueue.Log.NLog/MessageQueue.Log.NLog.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E2497F7E-11B5-4850-B1FD-2D3990368970} 8 | Library 9 | Properties 10 | MessageQueue.Log.NLog 11 | MessageQueue.Log.NLog 12 | v4.5.2 13 | 512 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | true 21 | full 22 | false 23 | ..\_Output\bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | pdbonly 30 | true 31 | ..\_Output\bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | ..\packages\NLog.4.4.10\lib\net45\NLog.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Properties\SharedAssemblyInfo.cs 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | Designer 61 | 62 | 63 | 64 | 65 | 66 | {304aaf94-6055-4ad7-942d-6ee000cd3d75} 67 | MessageQueue.Log.Core 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /MessageQueue.CofigurationProvider.AppSettings/Properties/ErrorMessages.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MessageQueue.CofigurationProvider.AppSettings.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class ErrorMessages { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal ErrorMessages() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MessageQueue.CofigurationProvider.AppSettings.Properties.ErrorMessages", typeof(ErrorMessages).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to Failed to retrieve configuration (identifier: {0}) from cofiguration file.. 65 | /// 66 | internal static string FailedToReadConfiguration { 67 | get { 68 | return ResourceManager.GetString("FailedToReadConfiguration", resourceCulture); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /MessageQueue.RabbitMq/Concrete/RmqRequestMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using RabbitMQ.Client; 3 | using MessageQueue.Core.Helper; 4 | using System.Collections.Generic; 5 | using MessageQueue.Core.Abstract; 6 | using MessageQueue.Core.Concrete; 7 | using MessageQueue.Core.Properties; 8 | using MessageQueue.RabbitMq.Helper; 9 | using MessageQueue.Log.Core.Abstract; 10 | 11 | namespace MessageQueue.RabbitMq.Concrete 12 | { 13 | /// 14 | /// RequestMessage implementation for RabbitMq. 15 | /// 16 | internal sealed class RmqRequestMessage : RequestMessage 17 | { 18 | #region Private Data Members 19 | private readonly IModel model; 20 | private readonly IQueueLogger logger; 21 | private readonly ulong deliveryTag; 22 | private readonly bool acknowledgment; 23 | private readonly string exchange, routingKey; 24 | private readonly IBasicProperties replyProperties; 25 | #endregion 26 | 27 | #region Constructors 28 | internal RmqRequestMessage(IModel model, IBasicProperties replyProperties, string exchange, string routingKey, bool acknowledgment, ulong deliveryTag, TRequest requestData, ref IQueueLogger logger) 29 | { 30 | #region Initialization 31 | RequestData = requestData; 32 | this.model = model; 33 | this.exchange = exchange; 34 | this.logger = logger; 35 | this.routingKey = routingKey; 36 | this.deliveryTag = deliveryTag; 37 | this.acknowledgment = acknowledgment; 38 | this.replyProperties = replyProperties; 39 | #endregion 40 | } 41 | #endregion 42 | 43 | #region RequestMessage Implementation 44 | public override void Response(TResponse response) 45 | { 46 | try 47 | { 48 | #region Sending Response 49 | // Preparing response. 50 | var responseBytes = MessageQueueCommonItems.SerializeToJsonBytes(response); 51 | 52 | // Sending response. 53 | model.BasicPublish(exchange, routingKey, replyProperties, responseBytes); 54 | 55 | // Acknowledging message. 56 | if (acknowledgment) 57 | { 58 | model.BasicAck(deliveryTag, false); 59 | } 60 | #endregion 61 | } 62 | catch (QueueException queueException) 63 | { 64 | #region Logging - Error 65 | logger.Error(queueException, queueException.Message); 66 | #endregion 67 | 68 | throw; 69 | } 70 | catch (Exception ex) 71 | { 72 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 73 | errorCode: QueueErrorCode.FailedToSendResponseMessage, 74 | message: ErrorMessages.FailedToSendResponseMessage, 75 | innerException: ex, 76 | queueContext: CommonItems.RabbitMqName, 77 | context: new Dictionary 78 | { 79 | [CommonContextKeys.ExchangeName] = exchange, 80 | [CommonContextKeys.RoutingKey] = routingKey, 81 | [ContextKeys.ReplyTo] = replyProperties.ReplyTo 82 | }, 83 | logger: logger); 84 | } 85 | } 86 | #endregion 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /MessageQueue.CofigurationProvider.AppSettings/MessageQueue.CofigurationProvider.AppSettings.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {4FAE7CE2-12FD-4434-9403-79F520B00481} 8 | Library 9 | Properties 10 | MessageQueue.CofigurationProvider.AppSettings 11 | MessageQueue.CofigurationProvider.AppSettings 12 | v4.5.2 13 | 512 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | true 21 | full 22 | false 23 | ..\_Output\bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | pdbonly 30 | true 31 | ..\_Output\bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | Properties\SharedAssemblyInfo.cs 50 | 51 | 52 | 53 | 54 | True 55 | True 56 | ErrorMessages.resx 57 | 58 | 59 | 60 | 61 | ResXFileCodeGenerator 62 | ErrorMessages.Designer.cs 63 | 64 | 65 | 66 | 67 | {e4880d7e-40ad-4936-88e7-0e6a28f5fb0a} 68 | MessageQueue.CofigurationProvider.Core 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /MessageQueue.ServiceBus/MessageQueue.ServiceBus.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DEC06ED4-DFAD-47D3-9277-FFD1F43EE8BE} 8 | Library 9 | Properties 10 | MessageQueue.ServiceBus 11 | MessageQueue.ServiceBus 12 | v4.5.2 13 | 512 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | true 21 | full 22 | false 23 | ..\_Output\bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | pdbonly 30 | true 31 | ..\_Output\bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | ..\packages\WindowsAzure.ServiceBus.4.1.2\lib\net45\Microsoft.ServiceBus.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | Properties\SharedAssemblyInfo.cs 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | {834caa3e-15aa-4d5d-82a4-884cab986aac} 69 | MessageQueue.Core 70 | 71 | 72 | {304aaf94-6055-4ad7-942d-6ee000cd3d75} 73 | MessageQueue.Log.Core 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /MessageQueue.RabbitMq/MessageQueue.RabbitMq.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {89733E22-2D91-4ACE-B4AE-646104F2591E} 8 | Library 9 | Properties 10 | MessageQueue.RabbitMq 11 | MessageQueue.RabbitMq 12 | v4.5.2 13 | 512 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | true 21 | full 22 | false 23 | ..\_Output\bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | pdbonly 30 | true 31 | ..\_Output\bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | ..\packages\RabbitMQ.Client.4.1.1\lib\net451\RabbitMQ.Client.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Properties\SharedAssemblyInfo.cs 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | {834CAA3E-15AA-4D5D-82A4-884CAB986AAC} 72 | MessageQueue.Core 73 | 74 | 75 | {304aaf94-6055-4ad7-942d-6ee000cd3d75} 76 | MessageQueue.Log.Core 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /Shared/appSettings.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /Tests/MessageQueue.Sender/MessageQueue.Sender.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {EDA7C5CB-E537-454C-976E-48AB241E4AAA} 8 | Exe 9 | MessageQueue.Sender 10 | MessageQueue.Sender 11 | v4.5.2 12 | 512 13 | true 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | AnyCPU 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | AnyCPU 31 | pdbonly 32 | true 33 | bin\Debug\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Properties\SharedAssemblyInfo.cs 51 | 52 | 53 | 54 | 55 | 56 | 57 | appSettings.config 58 | Always 59 | 60 | 61 | NLog.config 62 | Always 63 | 64 | 65 | 66 | 67 | 68 | {4FAE7CE2-12FD-4434-9403-79F520B00481} 69 | MessageQueue.CofigurationProvider.AppSettings 70 | 71 | 72 | {E4880D7E-40AD-4936-88E7-0E6A28F5FB0A} 73 | MessageQueue.CofigurationProvider.Core 74 | 75 | 76 | {834CAA3E-15AA-4D5D-82A4-884CAB986AAC} 77 | MessageQueue.Core 78 | 79 | 80 | {304aaf94-6055-4ad7-942d-6ee000cd3d75} 81 | MessageQueue.Log.Core 82 | 83 | 84 | {e2497f7e-11b5-4850-b1fd-2d3990368970} 85 | MessageQueue.Log.NLog 86 | 87 | 88 | 89 | 90 | xcopy "$(SolutionDir)_Output\bin\$(ConfigurationName)" "$(TargetDir)" /Y /D /I /E 91 | 92 | -------------------------------------------------------------------------------- /Tests/MessageQueue.Receiver/MessageQueue.Receiver.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {36A654EA-1ACC-4F00-A31D-5805D89CE035} 8 | Exe 9 | MessageQueue.Receiver 10 | MessageQueue.Receiver 11 | v4.5.2 12 | 512 13 | true 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | AnyCPU 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | AnyCPU 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Properties\SharedAssemblyInfo.cs 51 | 52 | 53 | 54 | 55 | 56 | 57 | appSettings.config 58 | Always 59 | 60 | 61 | NLog.config 62 | Always 63 | 64 | 65 | 66 | 67 | 68 | {4fae7ce2-12fd-4434-9403-79f520b00481} 69 | MessageQueue.CofigurationProvider.AppSettings 70 | 71 | 72 | {E4880D7E-40AD-4936-88E7-0E6A28F5FB0A} 73 | MessageQueue.CofigurationProvider.Core 74 | 75 | 76 | {834caa3e-15aa-4d5d-82a4-884cab986aac} 77 | MessageQueue.Core 78 | 79 | 80 | {304aaf94-6055-4ad7-942d-6ee000cd3d75} 81 | MessageQueue.Log.Core 82 | 83 | 84 | {e2497f7e-11b5-4850-b1fd-2d3990368970} 85 | MessageQueue.Log.NLog 86 | 87 | 88 | 89 | 90 | xcopy "$(SolutionDir)_Output\bin\$(ConfigurationName)" "$(TargetDir)" /Y /D /I /E 91 | 92 | -------------------------------------------------------------------------------- /Tests/MessageQueue.RaR.Client/MessageQueue.RaR.Client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B88D6D9A-7FBA-40C7-A5DB-07625BC7278B} 8 | Exe 9 | MessageQueue.RaR.Client 10 | MessageQueue.RaR.Client 11 | v4.5.2 12 | 512 13 | true 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | AnyCPU 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | AnyCPU 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Properties\SharedAssemblyInfo.cs 51 | 52 | 53 | 54 | 55 | 56 | 57 | appSettings.config 58 | Always 59 | 60 | 61 | NLog.config 62 | Always 63 | 64 | 65 | 66 | 67 | 68 | {4fae7ce2-12fd-4434-9403-79f520b00481} 69 | MessageQueue.CofigurationProvider.AppSettings 70 | 71 | 72 | {e4880d7e-40ad-4936-88e7-0e6a28f5fb0a} 73 | MessageQueue.CofigurationProvider.Core 74 | 75 | 76 | {834caa3e-15aa-4d5d-82a4-884cab986aac} 77 | MessageQueue.Core 78 | 79 | 80 | {304aaf94-6055-4ad7-942d-6ee000cd3d75} 81 | MessageQueue.Log.Core 82 | 83 | 84 | {e2497f7e-11b5-4850-b1fd-2d3990368970} 85 | MessageQueue.Log.NLog 86 | 87 | 88 | 89 | 90 | xcopy "$(SolutionDir)_Output\bin\$(ConfigurationName)" "$(TargetDir)" /Y /D /I /E 91 | 92 | -------------------------------------------------------------------------------- /Tests/MessageQueue.RaR.Server/MessageQueue.RaR.Server.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6C8F8685-8B2F-4767-B3CB-10A3EBD464FB} 8 | Exe 9 | MessageQueue.RaR.Server 10 | MessageQueue.RaR.Server 11 | v4.5.2 12 | 512 13 | true 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | AnyCPU 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | AnyCPU 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Properties\SharedAssemblyInfo.cs 51 | 52 | 53 | 54 | 55 | 56 | 57 | appSettings.config 58 | Always 59 | 60 | 61 | NLog.config 62 | Always 63 | 64 | 65 | 66 | 67 | 68 | {4fae7ce2-12fd-4434-9403-79f520b00481} 69 | MessageQueue.CofigurationProvider.AppSettings 70 | 71 | 72 | {E4880D7E-40AD-4936-88E7-0E6A28F5FB0A} 73 | MessageQueue.CofigurationProvider.Core 74 | 75 | 76 | {834caa3e-15aa-4d5d-82a4-884cab986aac} 77 | MessageQueue.Core 78 | 79 | 80 | {304aaf94-6055-4ad7-942d-6ee000cd3d75} 81 | MessageQueue.Log.Core 82 | 83 | 84 | {E2497F7E-11B5-4850-B1FD-2D3990368970} 85 | MessageQueue.Log.NLog 86 | 87 | 88 | 89 | 90 | xcopy "$(SolutionDir)_Output\bin\$(ConfigurationName)" "$(TargetDir)" /Y /D /I /E 91 | 92 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Concrete/ZmqMessageReceiveOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageQueue.Core.Helper; 3 | using MessageQueue.Core.Abstract; 4 | using MessageQueue.Core.Concrete; 5 | using MessageQueue.ZeroMq.Helper; 6 | using MessageQueue.Core.Properties; 7 | using MessageQueue.Log.Core.Abstract; 8 | 9 | namespace MessageQueue.ZeroMq.Concrete 10 | { 11 | /// 12 | /// IMessageReceiveOptions implementation for ZeroMq. 13 | /// 14 | internal sealed class ZmqMessageReceiveOptions : IMessageReceiveOptions 15 | { 16 | #region Private Data Members 17 | private IQueueLogger logger; 18 | #endregion 19 | 20 | #region Constructors 21 | public ZmqMessageReceiveOptions(ref IQueueLogger loggerObject) 22 | { 23 | #region Initialization 24 | logger = loggerObject; 25 | IsAcknowledgmentConfigured = false; // Acknowledgment is not supported yet in ZeroMq. 26 | #endregion 27 | } 28 | #endregion 29 | 30 | #region IMessageReceiveOptions Implementation 31 | // Properties 32 | public bool IsAcknowledgmentConfigured { get; } 33 | 34 | // Methods 35 | public void Acknowledge(bool ignoreError = true) 36 | { 37 | try 38 | { 39 | #region Acknowledging Message 40 | if (IsAcknowledgmentConfigured) 41 | { 42 | // Not supported feature yet. 43 | } 44 | else 45 | { 46 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 47 | errorCode: QueueErrorCode.AcknowledgmentIsNotConfiguredForQueue, 48 | message: ErrorMessages.AcknowledgmentIsNotConfiguredForQueue, 49 | innerException: null, 50 | queueContext: CommonItems.ZeroMqName, 51 | logger: logger); 52 | } 53 | #endregion 54 | } 55 | catch (QueueException) 56 | { 57 | if (ignoreError == false) 58 | { 59 | throw; 60 | } 61 | } 62 | catch (Exception ex) 63 | { 64 | var queueException = MessageQueueCommonItems.PrepareAndLogQueueException( 65 | errorCode: QueueErrorCode.FailedToAcknowledgeMessage, 66 | message: ErrorMessages.FailedToAcknowledgeMessage, 67 | innerException: ex, 68 | queueContext: CommonItems.ZeroMqName, 69 | logger: logger); 70 | 71 | if (ignoreError == false) 72 | { 73 | throw queueException; 74 | } 75 | } 76 | } 77 | 78 | public void AbandonAcknowledgment(bool ignoreError = true) 79 | { 80 | try 81 | { 82 | #region Abandoning Acknowledgment 83 | if (IsAcknowledgmentConfigured) 84 | { 85 | // Not supported feature yet. 86 | } 87 | else 88 | { 89 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 90 | errorCode: QueueErrorCode.AcknowledgmentIsNotConfiguredForQueue, 91 | message: ErrorMessages.AcknowledgmentIsNotConfiguredForQueue, 92 | innerException: null, 93 | queueContext: CommonItems.ZeroMqName, 94 | logger: logger); 95 | } 96 | #endregion 97 | } 98 | catch (QueueException) 99 | { 100 | if (ignoreError == false) 101 | { 102 | throw; 103 | } 104 | } 105 | catch (Exception ex) 106 | { 107 | var queueException = MessageQueueCommonItems.PrepareAndLogQueueException( 108 | errorCode: QueueErrorCode.FailedToAbandonMessageAcknowledgment, 109 | message: ErrorMessages.FailedToAbandonMessageAcknowledgment, 110 | innerException: ex, 111 | queueContext: CommonItems.ZeroMqName, 112 | logger: logger); 113 | 114 | if (ignoreError == false) 115 | { 116 | throw queueException; 117 | } 118 | } 119 | } 120 | #endregion 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/MessageQueue.ZeroMq.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {74BA1D1D-8536-4480-8F96-DF2621E8FBCE} 8 | Library 9 | Properties 10 | MessageQueue.ZeroMq 11 | MessageQueue.ZeroMq 12 | v4.5.2 13 | 512 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | true 21 | full 22 | false 23 | ..\_Output\bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | pdbonly 30 | true 31 | ..\_Output\bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | ..\packages\AsyncIO.0.1.26.0\lib\net40\AsyncIO.dll 39 | 40 | 41 | ..\packages\NetMQ.4.0.0.1\lib\net40\NetMQ.dll 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | Properties\SharedAssemblyInfo.cs 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | {834caa3e-15aa-4d5d-82a4-884cab986aac} 80 | MessageQueue.Core 81 | 82 | 83 | {304aaf94-6055-4ad7-942d-6ee000cd3d75} 84 | MessageQueue.Log.Core 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /MessageQueue.Core/Properties/InfoMessages.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | text/microsoft-resx 91 | 92 | 93 | 1.3 94 | 95 | 96 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 97 | 98 | 99 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 100 | 101 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Concrete/Outbound/ZmqOutboundFaF.cs: -------------------------------------------------------------------------------- 1 | using NetMQ; 2 | using System; 3 | using System.Threading.Tasks; 4 | using MessageQueue.Core.Helper; 5 | using System.Collections.Generic; 6 | using MessageQueue.Core.Concrete; 7 | using MessageQueue.ZeroMq.Helper; 8 | using MessageQueue.Core.Properties; 9 | using MessageQueue.ZeroMq.Abstract; 10 | using MessageQueue.Log.Core.Abstract; 11 | using MessageQueue.Core.Abstract.Outbound; 12 | 13 | namespace MessageQueue.ZeroMq.Concrete.Outbound 14 | { 15 | /// 16 | /// ZeroMq based implementation of IOutboundFaFMq. 17 | /// 18 | internal sealed class ZmqOutboundFaF : BaseZeroMq, IOutboundFaFMq 19 | { 20 | #region Private Methods 21 | private object lockForQueueOperation = new object(); 22 | #endregion 23 | 24 | #region Constructors 25 | public ZmqOutboundFaF(Dictionary configuration, IQueueLogger loggerObject) 26 | { 27 | try 28 | { 29 | #region Initialization 30 | base.Initialize(configuration, ZeroMqSocketType.Push, false, loggerObject); 31 | 32 | // Setting fields. 33 | Address = zmqConfiguration.Address; 34 | #endregion 35 | } 36 | catch (Exception ex) when (!(ex is QueueException)) 37 | { 38 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 39 | errorCode: QueueErrorCode.FailedToInitializeMessageQueue, 40 | message: ErrorMessages.FailedToInitializeMessageQueue, 41 | innerException: ex, 42 | queueContext: CommonItems.ZeroMqName, 43 | address: zmqConfiguration?.Address, 44 | logger: logger); 45 | } 46 | } 47 | #endregion 48 | 49 | #region IOutboundFaFMq Implementation 50 | public string Address { get; } 51 | 52 | public void SendMessage(TMessage message) 53 | { 54 | try 55 | { 56 | #region Sending Message 57 | // We need to lock as the sockets are not multi-threaded in ZeroMq. 58 | lock (lockForQueueOperation) 59 | { 60 | socket.SendFrame(MessageQueueCommonItems.SerializeToJson(message)); 61 | } 62 | #endregion 63 | } 64 | catch (QueueException queueException) 65 | { 66 | #region Logging - Error 67 | logger.Fatal(queueException, queueException.Message); 68 | #endregion 69 | 70 | throw; 71 | } 72 | catch (Exception ex) 73 | { 74 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 75 | errorCode: QueueErrorCode.FailedToSendMessage, 76 | message: ErrorMessages.FailedToSendMessage, 77 | innerException: ex, 78 | queueContext: CommonItems.ZeroMqName, 79 | address: zmqConfiguration.Address, 80 | logger: logger); 81 | } 82 | } 83 | 84 | public async Task SendMessageAsync(TMessage message) 85 | { 86 | try 87 | { 88 | #region Sending Message 89 | await Task.Run(() => SendMessage(message)); 90 | #endregion 91 | } 92 | catch (QueueException queueException) 93 | { 94 | #region Logging - Error 95 | logger.Fatal(queueException, queueException.Message); 96 | #endregion 97 | 98 | throw; 99 | } 100 | catch (Exception ex) 101 | { 102 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 103 | errorCode: QueueErrorCode.FailedToSendMessage, 104 | message: ErrorMessages.FailedToSendMessage, 105 | innerException: ex, 106 | queueContext: CommonItems.ZeroMqName, 107 | address: zmqConfiguration.Address, 108 | logger: logger); 109 | } 110 | } 111 | #endregion 112 | 113 | #region IDisposable Implementation 114 | public void Dispose() 115 | { 116 | Dispose(true); 117 | GC.SuppressFinalize(this); 118 | } 119 | 120 | private void Dispose(bool disposing) 121 | { 122 | #region Cleanup 123 | if (disposing) 124 | { 125 | lock (lockForQueueOperation) 126 | { 127 | socket?.Dispose(); 128 | } 129 | } 130 | #endregion 131 | } 132 | #endregion 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Concrete/Outbound/ZmqIpOutboundFaF.cs: -------------------------------------------------------------------------------- 1 | using NetMQ; 2 | using System; 3 | using System.Threading.Tasks; 4 | using MessageQueue.Core.Helper; 5 | using System.Collections.Generic; 6 | using MessageQueue.Core.Concrete; 7 | using MessageQueue.ZeroMq.Helper; 8 | using MessageQueue.Core.Properties; 9 | using MessageQueue.ZeroMq.Abstract; 10 | using MessageQueue.Log.Core.Abstract; 11 | using MessageQueue.Core.Abstract.Outbound; 12 | 13 | namespace MessageQueue.ZeroMq.Concrete.Outbound 14 | { 15 | /// 16 | /// ZeroMq based in-process implementation of IOutboundFaFMq. 17 | /// 18 | internal sealed class ZmqIpOutboundFaF : BaseZeroMq, IOutboundFaFMq 19 | { 20 | #region Private Methods 21 | private object lockForQueueOperation = new object(); 22 | #endregion 23 | 24 | #region Constructors 25 | public ZmqIpOutboundFaF(Dictionary configuration, IQueueLogger loggerObject) 26 | { 27 | try 28 | { 29 | #region Initialization 30 | base.Initialize(configuration, ZeroMqSocketType.Pair, false, loggerObject); 31 | 32 | // Setting fields. 33 | Address = zmqConfiguration.Address; 34 | #endregion 35 | } 36 | catch (Exception ex) when (!(ex is QueueException)) 37 | { 38 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 39 | errorCode: QueueErrorCode.FailedToInitializeMessageQueue, 40 | message: ErrorMessages.FailedToInitializeMessageQueue, 41 | innerException: ex, 42 | queueContext: CommonItems.ZeroMqName, 43 | address: zmqConfiguration?.Address, 44 | logger: logger); 45 | } 46 | } 47 | #endregion 48 | 49 | #region IOutboundFaFMq Implementation 50 | public string Address { get; } 51 | 52 | public void SendMessage(TMessage message) 53 | { 54 | try 55 | { 56 | #region Sending Message 57 | // We need to lock as the sockets are not multi-threaded in ZeroMq. 58 | lock (lockForQueueOperation) 59 | { 60 | socket.SendFrame(MessageQueueCommonItems.SerializeToJson(message)); 61 | } 62 | #endregion 63 | } 64 | catch (QueueException queueException) 65 | { 66 | #region Logging - Error 67 | logger.Fatal(queueException, queueException.Message); 68 | #endregion 69 | 70 | throw; 71 | } 72 | catch (Exception ex) 73 | { 74 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 75 | errorCode: QueueErrorCode.FailedToSendMessage, 76 | message: ErrorMessages.FailedToSendMessage, 77 | innerException: ex, 78 | queueContext: CommonItems.ZeroMqName, 79 | address: zmqConfiguration.Address, 80 | logger: logger); 81 | } 82 | } 83 | 84 | public async Task SendMessageAsync(TMessage message) 85 | { 86 | try 87 | { 88 | #region Sending Message 89 | await Task.Run(() => SendMessage(message)); 90 | #endregion 91 | } 92 | catch (QueueException queueException) 93 | { 94 | #region Logging - Error 95 | logger.Fatal(queueException, queueException.Message); 96 | #endregion 97 | 98 | throw; 99 | } 100 | catch (Exception ex) 101 | { 102 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 103 | errorCode: QueueErrorCode.FailedToSendMessage, 104 | message: ErrorMessages.FailedToSendMessage, 105 | innerException: ex, 106 | queueContext: CommonItems.ZeroMqName, 107 | address: zmqConfiguration.Address, 108 | logger: logger); 109 | } 110 | } 111 | #endregion 112 | 113 | #region IDisposable Implementation 114 | public void Dispose() 115 | { 116 | Dispose(true); 117 | GC.SuppressFinalize(this); 118 | } 119 | 120 | private void Dispose(bool disposing) 121 | { 122 | #region Cleanup 123 | if (disposing) 124 | { 125 | lock (lockForQueueOperation) 126 | { 127 | socket?.Dispose(); 128 | } 129 | } 130 | #endregion 131 | } 132 | #endregion 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /Tests/MessageQueue.RaR.Server/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using MessageQueue.Core.Abstract; 5 | using MessageQueue.Core.Services; 6 | using MessageQueue.Log.NLog.Concrete; 7 | using MessageQueue.Core.Abstract.Inbound; 8 | using MessageQueue.CofigurationProvider.AppSettings.Concrete; 9 | 10 | namespace MessageQueue.RaR.Server 11 | { 12 | class Program 13 | { 14 | #region Private Data Members 15 | private static int workTimeInMs = 0; 16 | private static IInboundRaRMq inboundMessageQueue; 17 | #endregion 18 | 19 | static void Main(string[] args) 20 | { 21 | Console.WriteLine("Please select the Message Queue (Server):" + Environment.NewLine + "1- ZeroMq" + Environment.NewLine + "2- RabbitMq"); 22 | var option = Console.ReadKey(); 23 | 24 | switch (option.Key) 25 | { 26 | case ConsoleKey.D1: 27 | case ConsoleKey.NumPad1: 28 | Test_ZeroMqRaR(); 29 | break; 30 | 31 | case ConsoleKey.D2: 32 | case ConsoleKey.NumPad2: 33 | Test_RabbitMqRaR(); 34 | break; 35 | 36 | default: 37 | Test_ZeroMqRaR(); 38 | break; 39 | } 40 | 41 | Console.ReadKey(); 42 | } 43 | 44 | #region ZeroMq 45 | public static void Test_ZeroMqRaR() 46 | { 47 | try 48 | { 49 | Console.WriteLine("ZeroMq test inbound messages (server) [work time per message {0}ms].", workTimeInMs); 50 | Console.WriteLine(nameof(Test_ZeroMqRaR)); 51 | 52 | // Creating queue object from factory. 53 | inboundMessageQueue = MessagingQueueFactory.CreateInboundRaR(new AppSettingsConfigurationProvider(), "ZeroMqRaRServer", new NQueueLogger("Default")); 54 | inboundMessageQueue.OnRequestReady += ZeroMqInboundMessageQueue_OnRequestReady; 55 | 56 | Console.WriteLine("Press any key to start receiving..."); 57 | Console.ReadKey(); 58 | 59 | inboundMessageQueue.StartReceivingRequest(); 60 | 61 | Console.WriteLine("Server is ready and listening at: {0}", inboundMessageQueue.Address); 62 | } 63 | catch (Exception ex) 64 | { 65 | Console.WriteLine(ex); 66 | } 67 | } 68 | 69 | private static void ZeroMqInboundMessageQueue_OnRequestReady(RequestMessage request) 70 | { 71 | Console.WriteLine("Request received: " + Environment.NewLine + request.RequestData); 72 | 73 | Thread.Sleep(workTimeInMs); 74 | 75 | var message = string.Format("You sent me: '{0}' (received at: {1})", request.RequestData, DateTime.Now.ToLongTimeString()); 76 | request.Response(message); 77 | Console.WriteLine("Response sent: " + Environment.NewLine + message); 78 | Console.WriteLine("------------------------------------"); 79 | } 80 | #endregion 81 | 82 | #region RabbitMq 83 | public static void Test_RabbitMqRaR() 84 | { 85 | try 86 | { 87 | Console.WriteLine(); 88 | Console.WriteLine("RabbitMq test inbound messages (server) [work time per message {0}ms].", workTimeInMs); 89 | 90 | // Creating queue object from factory. 91 | inboundMessageQueue = MessagingQueueFactory.CreateInboundRaR(new AppSettingsConfigurationProvider(), "RabbitMqRaRServer", new NQueueLogger("Default")); 92 | inboundMessageQueue.OnRequestReady += RabbitMqInboundMessageQueue_OnRequestReady; 93 | 94 | Console.WriteLine("Press any key to start receiving..."); 95 | Console.ReadKey(); 96 | 97 | inboundMessageQueue.StartReceivingRequest(); 98 | 99 | Console.WriteLine("Server is ready and listening at: {0}", inboundMessageQueue.Address); 100 | } 101 | catch (Exception ex) 102 | { 103 | Console.WriteLine(ex); 104 | } 105 | } 106 | 107 | private static void RabbitMqInboundMessageQueue_OnRequestReady(RequestMessage request) 108 | { 109 | Console.WriteLine("Request received: " + Environment.NewLine + request.RequestData); 110 | 111 | Thread.Sleep(workTimeInMs); 112 | 113 | var message = string.Format("You sent me: '{0}' (received at: {1})", request.RequestData, DateTime.Now.ToLongTimeString()); 114 | request.Response(message); 115 | Console.WriteLine("Response sent: " + Environment.NewLine + message); 116 | Console.WriteLine("------------------------------------"); 117 | } 118 | #endregion 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /MessageQueue.RabbitMq/Concrete/RmqMessageReceiveOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using RabbitMQ.Client; 3 | using MessageQueue.Core.Helper; 4 | using MessageQueue.Core.Abstract; 5 | using MessageQueue.Core.Concrete; 6 | using MessageQueue.Core.Properties; 7 | using MessageQueue.RabbitMq.Helper; 8 | using MessageQueue.Log.Core.Abstract; 9 | 10 | namespace MessageQueue.RabbitMq.Concrete 11 | { 12 | /// 13 | /// IMessageReceiveOptions implementation for RabbitMq. 14 | /// 15 | internal sealed class RmqMessageReceiveOptions : IMessageReceiveOptions 16 | { 17 | #region Private Data Members 18 | private IModel model; 19 | private IQueueLogger logger; 20 | private string queueName; 21 | private ulong deliveryTag; 22 | #endregion 23 | 24 | #region Constructors 25 | public RmqMessageReceiveOptions(IModel model, ulong deliveryTag, string queueName, bool isAcknowledgmentConfigured, ref IQueueLogger logger) 26 | { 27 | #region Initialization 28 | this.model = model; 29 | this.logger = logger; 30 | this.queueName = queueName; 31 | this.deliveryTag = deliveryTag; 32 | IsAcknowledgmentConfigured = isAcknowledgmentConfigured; 33 | #endregion 34 | } 35 | #endregion 36 | 37 | #region IMessageReceiveOptions Implementation 38 | // Properties 39 | public bool IsAcknowledgmentConfigured { get; } 40 | 41 | // Methods 42 | public void Acknowledge(bool ignoreError = true) 43 | { 44 | try 45 | { 46 | #region Acknowledging Message 47 | if (IsAcknowledgmentConfigured) 48 | { 49 | model.BasicAck(deliveryTag, false); 50 | } 51 | else 52 | { 53 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 54 | errorCode: QueueErrorCode.AcknowledgmentIsNotConfiguredForQueue, 55 | message: ErrorMessages.AcknowledgmentIsNotConfiguredForQueue, 56 | innerException: null, 57 | queueContext: CommonItems.RabbitMqName, 58 | queueName: queueName, 59 | logger: logger); 60 | } 61 | #endregion 62 | } 63 | catch (QueueException) 64 | { 65 | if (ignoreError == false) 66 | { 67 | throw; 68 | } 69 | } 70 | catch (Exception ex) 71 | { 72 | var queueException = MessageQueueCommonItems.PrepareAndLogQueueException( 73 | errorCode: QueueErrorCode.FailedToAcknowledgeMessage, 74 | message: ErrorMessages.FailedToAcknowledgeMessage, 75 | innerException: ex, 76 | queueContext: CommonItems.RabbitMqName, 77 | queueName: queueName, 78 | logger: logger); 79 | 80 | if (ignoreError == false) 81 | { 82 | throw queueException; 83 | } 84 | } 85 | } 86 | 87 | public void AbandonAcknowledgment(bool ignoreError = true) 88 | { 89 | try 90 | { 91 | #region Abandoning Acknowledgment 92 | if (IsAcknowledgmentConfigured) 93 | { 94 | model.BasicNack(deliveryTag, false, true); 95 | } 96 | else 97 | { 98 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 99 | errorCode: QueueErrorCode.AcknowledgmentIsNotConfiguredForQueue, 100 | message: ErrorMessages.AcknowledgmentIsNotConfiguredForQueue, 101 | innerException: null, 102 | queueContext: CommonItems.RabbitMqName, 103 | queueName: queueName, 104 | logger: logger); 105 | } 106 | #endregion 107 | } 108 | catch (QueueException) 109 | { 110 | if (ignoreError == false) 111 | { 112 | throw; 113 | } 114 | } 115 | catch (Exception ex) 116 | { 117 | var queueException = MessageQueueCommonItems.PrepareAndLogQueueException( 118 | errorCode: QueueErrorCode.FailedToAbandonMessageAcknowledgment, 119 | message: ErrorMessages.FailedToAbandonMessageAcknowledgment, 120 | innerException: ex, 121 | queueContext: CommonItems.RabbitMqName, 122 | queueName: queueName, 123 | logger: logger); 124 | 125 | if (ignoreError == false) 126 | { 127 | throw queueException; 128 | } 129 | } 130 | } 131 | #endregion 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /MessageQueue.ServiceBus/Concrete/SbMessageReceiveOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageQueue.Core.Helper; 3 | using MessageQueue.Core.Abstract; 4 | using MessageQueue.Core.Concrete; 5 | using MessageQueue.Core.Properties; 6 | using MessageQueue.Log.Core.Abstract; 7 | using MessageQueue.ServiceBus.Helper; 8 | using Microsoft.ServiceBus.Messaging; 9 | 10 | namespace MessageQueue.ServiceBus.Concrete 11 | { 12 | /// 13 | /// IMessageReceiveOptions implementation for ServiceBus. 14 | /// 15 | internal sealed class SbMessageReceiveOptions : IMessageReceiveOptions 16 | { 17 | #region Private Data Members 18 | private IQueueLogger logger; 19 | private string queueName; 20 | private Guid lockToken; 21 | private QueueClient queueClient; 22 | #endregion 23 | 24 | #region Constructors 25 | public SbMessageReceiveOptions(Guid lockToken, string queueName, bool isAcknowledgmentConfigured, ref QueueClient queueClient, ref IQueueLogger loggerObject) 26 | { 27 | #region Initialization 28 | this.queueName = queueName; 29 | this.logger = loggerObject; 30 | this.lockToken = lockToken; 31 | this.queueClient = queueClient; 32 | IsAcknowledgmentConfigured = isAcknowledgmentConfigured; 33 | #endregion 34 | } 35 | #endregion 36 | 37 | #region IMessageReceiveOptions Implementation 38 | // Properties 39 | public bool IsAcknowledgmentConfigured { get; } 40 | 41 | // Methods 42 | public void Acknowledge(bool ignoreError = true) 43 | { 44 | try 45 | { 46 | #region Acknowledging Message 47 | if (IsAcknowledgmentConfigured) 48 | { 49 | queueClient.Complete(lockToken); 50 | } 51 | else 52 | { 53 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 54 | errorCode: QueueErrorCode.AcknowledgmentIsNotConfiguredForQueue, 55 | message: ErrorMessages.AcknowledgmentIsNotConfiguredForQueue, 56 | innerException: null, 57 | queueContext: CommonItems.ServiceBusName, 58 | queueName: queueName, 59 | logger: logger); 60 | } 61 | 62 | #endregion 63 | } 64 | catch (QueueException) 65 | { 66 | if (ignoreError == false) 67 | { 68 | throw; 69 | } 70 | } 71 | catch (Exception ex) 72 | { 73 | var queueException = MessageQueueCommonItems.PrepareAndLogQueueException( 74 | errorCode: QueueErrorCode.FailedToAcknowledgeMessage, 75 | message: ErrorMessages.FailedToAcknowledgeMessage, 76 | innerException: ex, 77 | queueContext: CommonItems.ServiceBusName, 78 | queueName: queueName, 79 | logger: logger); 80 | 81 | if (ignoreError == false) 82 | { 83 | throw queueException; 84 | } 85 | } 86 | } 87 | 88 | public void AbandonAcknowledgment(bool ignoreError = true) 89 | { 90 | try 91 | { 92 | #region Abandoning Acknowledgment 93 | if (IsAcknowledgmentConfigured) 94 | { 95 | queueClient.Abandon(lockToken); 96 | } 97 | else 98 | { 99 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 100 | errorCode: QueueErrorCode.AcknowledgmentIsNotConfiguredForQueue, 101 | message: ErrorMessages.AcknowledgmentIsNotConfiguredForQueue, 102 | innerException: null, 103 | queueContext: CommonItems.ServiceBusName, 104 | queueName: queueName, 105 | logger: logger); 106 | } 107 | #endregion 108 | } 109 | catch (QueueException) 110 | { 111 | if (ignoreError == false) 112 | { 113 | throw; 114 | } 115 | } 116 | catch (Exception ex) 117 | { 118 | var queueException = MessageQueueCommonItems.PrepareAndLogQueueException( 119 | errorCode: QueueErrorCode.FailedToAbandonMessageAcknowledgment, 120 | message: ErrorMessages.FailedToAbandonMessageAcknowledgment, 121 | innerException: ex, 122 | queueContext: CommonItems.ServiceBusName, 123 | queueName: queueName, 124 | logger: logger); 125 | 126 | if (ignoreError == false) 127 | { 128 | throw queueException; 129 | } 130 | } 131 | } 132 | #endregion 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /MessageQueue.Core/MessageQueue.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {834CAA3E-15AA-4D5D-82A4-884CAB986AAC} 8 | Library 9 | Properties 10 | MessageQueue.Core 11 | MessageQueue.Core 12 | v4.5.2 13 | 512 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | true 21 | full 22 | false 23 | ..\_Output\bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | pdbonly 30 | true 31 | ..\_Output\bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Properties\SharedAssemblyInfo.cs 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | True 69 | True 70 | InfoMessages.resx 71 | 72 | 73 | True 74 | True 75 | ErrorMessages.resx 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | {e4880d7e-40ad-4936-88e7-0e6a28f5fb0a} 84 | MessageQueue.CofigurationProvider.Core 85 | 86 | 87 | {304aaf94-6055-4ad7-942d-6ee000cd3d75} 88 | MessageQueue.Log.Core 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | PublicResXFileCodeGenerator 97 | InfoMessages.Designer.cs 98 | 99 | 100 | PublicResXFileCodeGenerator 101 | ErrorMessages.Designer.cs 102 | Designer 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /Tests/MessageQueue.RaR.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using MessageQueue.Core.Services; 4 | using MessageQueue.Log.NLog.Concrete; 5 | using MessageQueue.CofigurationProvider.AppSettings.Concrete; 6 | 7 | namespace MessageQueue.RaR.Client 8 | { 9 | class Program 10 | { 11 | #region Private Data Members 12 | private const int messageCount = 10; 13 | private static int clientNumber; 14 | private static int gapeBetweenMessagesInMs = 0; 15 | #endregion 16 | 17 | static void Main(string[] args) 18 | { 19 | // Setting random gape time between messages. 20 | var randomeNumberGenerator = new Random(); 21 | gapeBetweenMessagesInMs = randomeNumberGenerator.Next(1, 1000) > 500 ? 100 : 200; 22 | 23 | // Setting client number. 24 | var rnd = new Random(); 25 | clientNumber = rnd.Next(1, 10000); 26 | 27 | Console.WriteLine("Please select the Message Queue (Client):" + Environment.NewLine + "1- ZeroMq" + Environment.NewLine + "2- RabbitMq"); 28 | var option = Console.ReadKey(); 29 | 30 | switch (option.Key) 31 | { 32 | case ConsoleKey.D1: 33 | case ConsoleKey.NumPad1: 34 | Test_ZeroMqRaR_Request(); 35 | break; 36 | 37 | case ConsoleKey.D2: 38 | case ConsoleKey.NumPad2: 39 | Test_RabbitMqRaR_Request(); 40 | break; 41 | 42 | default: 43 | Test_ZeroMqRaR_Request(); 44 | break; 45 | } 46 | 47 | Console.ReadKey(); 48 | } 49 | 50 | #region ZeroMq 51 | public static void Test_ZeroMqRaR_Request() 52 | { 53 | try 54 | { 55 | Console.WriteLine(); 56 | Console.WriteLine("ZeroMq test outbound messages (client)... (press any key to start sending)"); 57 | Console.ReadKey(); 58 | Console.WriteLine("Started (client Id: {0}, message count: {1}, gape between messages: {2}ms)....", clientNumber, messageCount, gapeBetweenMessagesInMs); 59 | 60 | // Creating queue object from factory. 61 | var outboundMessageQueue = MessagingQueueFactory.CreateOutboundRaR(new AppSettingsConfigurationProvider(), "ZeroMqRaRClient", new NQueueLogger("Default")); 62 | outboundMessageQueue.OnResponseReady += ZeroMqOutboundMessageQueue_OnResponseReady; 63 | 64 | for (int i = 1; i <= messageCount; i++) 65 | { 66 | var message = string.Format("RAR message number: {0} client {1} (sent at: {2})", i, 67 | clientNumber, DateTime.Now.ToLongTimeString()); 68 | 69 | Console.WriteLine("Requesting: " + Environment.NewLine + message); 70 | outboundMessageQueue.SendRequest(message); 71 | 72 | Thread.Sleep(gapeBetweenMessagesInMs); 73 | } 74 | } 75 | catch (Exception ex) 76 | { 77 | Console.WriteLine(ex); 78 | } 79 | } 80 | 81 | private static void ZeroMqOutboundMessageQueue_OnResponseReady(string responseData) 82 | { 83 | Console.WriteLine("Reply from server:" + Environment.NewLine + responseData); 84 | Console.WriteLine("------------------------------"); 85 | } 86 | #endregion 87 | 88 | #region RabbitMq 89 | public static void Test_RabbitMqRaR_Request() 90 | { 91 | try 92 | { 93 | Console.WriteLine(); 94 | Console.WriteLine("RabbitMq test outbound messages (client)... (press any key to start sending)"); 95 | Console.ReadKey(); 96 | Console.WriteLine("Started (client Id: {0}, message count: {1}, gape between messages: {2}ms)....", 97 | clientNumber, messageCount, gapeBetweenMessagesInMs); 98 | 99 | // Creating queue object from factory. 100 | var outboundMessageQueue = MessagingQueueFactory.CreateOutboundRaR(new AppSettingsConfigurationProvider(), 101 | "RabbitMqRaRClient", new NQueueLogger("Default")); 102 | outboundMessageQueue.OnResponseReady += RabbitMqOutboundMessageQueue_OnResponseReady; 103 | 104 | for (int i = 1; i <= messageCount; i++) 105 | { 106 | var message = string.Format("RAR message number: {0} client {1} (sent at: {2})", i, clientNumber, 107 | DateTime.Now.ToLongTimeString()); 108 | 109 | Console.WriteLine("Requesting: " + Environment.NewLine + message); 110 | outboundMessageQueue.SendRequest(message); 111 | 112 | Thread.Sleep(gapeBetweenMessagesInMs); 113 | } 114 | } 115 | catch (Exception ex) 116 | { 117 | Console.WriteLine(ex); 118 | } 119 | } 120 | 121 | private static void RabbitMqOutboundMessageQueue_OnResponseReady(string responseData) 122 | { 123 | Console.WriteLine("Reply from server:" + Environment.NewLine + responseData); 124 | Console.WriteLine("------------------------------"); 125 | } 126 | #endregion 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Abstract/BaseZeroMq.cs: -------------------------------------------------------------------------------- 1 | using NetMQ; 2 | using System; 3 | using NetMQ.Sockets; 4 | using MessageQueue.Core.Helper; 5 | using MessageQueue.Core.Concrete; 6 | using System.Collections.Generic; 7 | using MessageQueue.ZeroMq.Helper; 8 | using MessageQueue.Core.Properties; 9 | using MessageQueue.ZeroMq.Concrete; 10 | using MessageQueue.Log.Core.Abstract; 11 | 12 | namespace MessageQueue.ZeroMq.Abstract 13 | { 14 | /// 15 | /// Base class for all ZeroMq based implementation of interfaces. 16 | /// 17 | internal abstract class BaseZeroMq 18 | { 19 | #region Protected Properties 20 | protected IQueueLogger logger; 21 | protected NetMQPoller poller; 22 | protected NetMQSocket socket; 23 | protected ZeroMqConfiguration zmqConfiguration; 24 | #endregion 25 | 26 | #region Protected Methods 27 | /// 28 | /// Common initialization code. 29 | /// 30 | protected virtual void Initialize(Dictionary configuration, ZeroMqSocketType socketType, bool isInbound, IQueueLogger loggerObject = null) 31 | { 32 | try 33 | { 34 | #region Logger Initialization 35 | logger = loggerObject; 36 | #endregion 37 | 38 | #region Parameters Collection 39 | zmqConfiguration = CommonItems.CollectZmqConfiguration(ref configuration, isInbound, ref logger); 40 | #endregion 41 | 42 | #region Creating Socket 43 | InitializeZeroMqSocket(socketType, isInbound); 44 | #endregion 45 | } 46 | catch (Exception ex) when (!(ex is QueueException)) 47 | { 48 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 49 | errorCode: QueueErrorCode.FailedToInitializeMessageQueue, 50 | message: ErrorMessages.FailedToInitializeMessageQueue, 51 | innerException: ex, 52 | queueContext: CommonItems.ZeroMqName, 53 | address: zmqConfiguration.Address, 54 | logger: logger); 55 | } 56 | } 57 | #endregion 58 | 59 | #region Private Methods 60 | /// 61 | /// Helper method to create and initialize different types of ZeroMq sockets. 62 | /// 63 | private void InitializeZeroMqSocket(ZeroMqSocketType socketType, bool isInbound) 64 | { 65 | try 66 | { 67 | #region Initialization 68 | switch (socketType) 69 | { 70 | case ZeroMqSocketType.Pair: 71 | { 72 | socket = new PairSocket(zmqConfiguration.Address); 73 | break; 74 | } 75 | 76 | case ZeroMqSocketType.Pull: 77 | { 78 | socket = new PullSocket(zmqConfiguration.Address); 79 | break; 80 | } 81 | 82 | case ZeroMqSocketType.Push: 83 | { 84 | socket = new PushSocket(zmqConfiguration.Address); 85 | break; 86 | } 87 | 88 | case ZeroMqSocketType.Dealer: 89 | { 90 | socket = new DealerSocket(zmqConfiguration.Address); 91 | break; 92 | } 93 | 94 | case ZeroMqSocketType.Router: 95 | { 96 | socket = new RouterSocket(zmqConfiguration.Address); 97 | break; 98 | } 99 | 100 | default: 101 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 102 | errorCode: QueueErrorCode.InvalidZeroMqSocketType, 103 | message: ErrorMessages.InvalidZeroMqSocketType, 104 | innerException: null, 105 | queueContext: CommonItems.ZeroMqName, 106 | address: zmqConfiguration.Address, 107 | logger: logger); 108 | } 109 | 110 | // Setting options. 111 | socket.Options.Linger = Defaults.ZeroMqLinger; 112 | 113 | if (isInbound) 114 | { 115 | socket.Options.ReceiveHighWatermark = Defaults.ZeroMqReceiveHighWatermark; 116 | } 117 | else 118 | { 119 | socket.Options.SendHighWatermark = Defaults.ZeroMqSendHighWatermark; 120 | } 121 | #endregion 122 | } 123 | catch (Exception ex) when (!(ex is QueueException)) 124 | { 125 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 126 | errorCode: QueueErrorCode.FailedToCreateZeroMqSocket, 127 | message: ErrorMessages.FailedToCreateZeroMqSocket, 128 | innerException: ex, 129 | queueContext: CommonItems.ZeroMqName, 130 | address: zmqConfiguration?.Address, 131 | logger: logger); 132 | } 133 | } 134 | #endregion 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /MessageQueue.ServiceBus/Concrete/Outbound/SbOutboundFaF.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | using MessageQueue.Core.Helper; 5 | using MessageQueue.Core.Concrete; 6 | using System.Collections.Generic; 7 | using MessageQueue.Core.Properties; 8 | using MessageQueue.ServiceBus.Helper; 9 | using MessageQueue.Log.Core.Abstract; 10 | using Microsoft.ServiceBus.Messaging; 11 | using MessageQueue.ServiceBus.Abstract; 12 | using MessageQueue.Core.Abstract.Outbound; 13 | 14 | namespace MessageQueue.ServiceBus.Concrete.Outbound 15 | { 16 | /// 17 | /// Azure ServiceBus based implementation of IOutboundFaFMq. 18 | /// 19 | internal sealed class SbOutboundFaF : BaseServiceBus, IOutboundFaFMq 20 | { 21 | #region Constructors 22 | public SbOutboundFaF(Dictionary configuration, IQueueLogger loggerObject) 23 | { 24 | try 25 | { 26 | #region Initialization 27 | base.Initialize(configuration, false, loggerObject); 28 | 29 | // Setting other fields. 30 | Address = sbConfiguration.Address; 31 | #endregion 32 | } 33 | catch (Exception ex) when (!(ex is QueueException)) 34 | { 35 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 36 | errorCode: QueueErrorCode.FailedToInitializeMessageQueue, 37 | message: ErrorMessages.FailedToInitializeMessageQueue, 38 | innerException: ex, 39 | queueContext: CommonItems.ServiceBusName, 40 | queueName: sbConfiguration.QueueName, 41 | address: sbConfiguration.Address, 42 | logger: logger); 43 | } 44 | } 45 | #endregion 46 | 47 | #region IOutboundFaFMq Implementation 48 | public string Address { get; private set; } 49 | 50 | public void SendMessage(TMessage message) 51 | { 52 | try 53 | { 54 | #region Sending Message 55 | CheckConnection(); 56 | 57 | queueClient.Send(new BrokeredMessage(new MemoryStream(MessageQueueCommonItems.SerializeToJsonBytes(message)))); 58 | #endregion 59 | } 60 | catch (QueueException queueException) 61 | { 62 | #region Logging - Error 63 | logger.Fatal(queueException, queueException.Message); 64 | #endregion 65 | 66 | throw; 67 | } 68 | catch (Exception ex) 69 | { 70 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 71 | errorCode: QueueErrorCode.FailedToSendMessage, 72 | message: ErrorMessages.FailedToSendMessage, 73 | innerException: ex, 74 | queueContext: CommonItems.ServiceBusName, 75 | queueName: sbConfiguration.QueueName, 76 | address: sbConfiguration.Address, 77 | logger: logger); 78 | } 79 | } 80 | 81 | public async Task SendMessageAsync(TMessage message) 82 | { 83 | try 84 | { 85 | #region Sending Message 86 | CheckConnection(); 87 | 88 | await queueClient.SendAsync(new BrokeredMessage(new MemoryStream(MessageQueueCommonItems.SerializeToJsonBytes(message)))); 89 | #endregion 90 | } 91 | catch (QueueException queueException) 92 | { 93 | #region Logging - Error 94 | logger.Fatal(queueException, queueException.Message); 95 | #endregion 96 | 97 | throw; 98 | } 99 | catch (Exception ex) 100 | { 101 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 102 | errorCode: QueueErrorCode.FailedToSendMessage, 103 | message: ErrorMessages.FailedToSendMessage, 104 | innerException: ex, 105 | queueContext: CommonItems.ServiceBusName, 106 | queueName: sbConfiguration.QueueName, 107 | address: sbConfiguration.Address, 108 | logger: logger); 109 | } 110 | } 111 | #endregion 112 | 113 | #region IDisposable Implementation 114 | public void Dispose() 115 | { 116 | Dispose(true); 117 | GC.SuppressFinalize(this); 118 | } 119 | 120 | private void Dispose(bool disposing) 121 | { 122 | #region Cleanup 123 | if (disposing) 124 | { 125 | queueClient.Close(); 126 | } 127 | #endregion 128 | } 129 | #endregion 130 | 131 | #region Private Methods 132 | /// 133 | /// Helper method to check connection before sending message. 134 | /// 135 | private void CheckConnection() 136 | { 137 | #region Connection Check 138 | // If connection is closed, then re-create the client. 139 | if (queueClient.IsClosed) 140 | { 141 | lock (queueClient) 142 | { 143 | // This is to avoid if multiple re-creation when threads are waiting for the lock to be released. 144 | if (queueClient.IsClosed) 145 | { 146 | queueClient = queueClient.MessagingFactory.CreateQueueClient(sbConfiguration.QueueName); 147 | } 148 | } 149 | } 150 | #endregion 151 | } 152 | #endregion 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Concrete/Outbound/ZmqOutboundRaR.cs: -------------------------------------------------------------------------------- 1 | using NetMQ; 2 | using System; 3 | using System.Text; 4 | using MessageQueue.Core.Helper; 5 | using System.Collections.Generic; 6 | using MessageQueue.Core.Concrete; 7 | using MessageQueue.ZeroMq.Helper; 8 | using MessageQueue.Core.Properties; 9 | using MessageQueue.ZeroMq.Abstract; 10 | using MessageQueue.Log.Core.Abstract; 11 | using MessageQueue.Core.Abstract.Outbound; 12 | 13 | namespace MessageQueue.ZeroMq.Concrete.Outbound 14 | { 15 | /// 16 | /// ZeroMq based implementation of IOutboundRaRMq. 17 | /// 18 | internal sealed class ZmqOutboundRaR : BaseZeroMq, IOutboundRaRMq 19 | { 20 | #region Private Data Members 21 | private readonly string socketIdentity; 22 | #endregion 23 | 24 | #region Constructors 25 | public ZmqOutboundRaR(Dictionary configuration, IQueueLogger loggerObject) 26 | { 27 | try 28 | { 29 | #region Initialization 30 | base.Initialize(configuration, ZeroMqSocketType.Dealer, false, loggerObject); 31 | 32 | // Setting fields. 33 | Address = zmqConfiguration.Address; 34 | 35 | // Need to set some unique identifier for connection identity (ZeroMq requirement). 36 | socketIdentity = Guid.NewGuid().ToString("N"); 37 | socket.Options.Identity = Encoding.Unicode.GetBytes(socketIdentity); 38 | 39 | // Binding on receive event. 40 | socket.ReceiveReady += ResponseReady; 41 | 42 | // Initializing poller and starting it. 43 | poller = new NetMQPoller { socket }; 44 | poller.RunAsync(); 45 | #endregion 46 | } 47 | catch (Exception ex) when (!(ex is QueueException)) 48 | { 49 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 50 | errorCode: QueueErrorCode.FailedToInitializeMessageQueue, 51 | message: ErrorMessages.FailedToInitializeMessageQueue, 52 | innerException: ex, 53 | queueContext: CommonItems.ZeroMqName, 54 | address: zmqConfiguration?.Address, 55 | logger: logger); 56 | } 57 | } 58 | #endregion 59 | 60 | #region IOutboundRaRMq Implementation 61 | public string Address { get; } 62 | 63 | public event Action OnResponseReady; 64 | 65 | public void SendRequest(TRequest message) 66 | { 67 | #region Sending Message 68 | try 69 | { 70 | // Preparing message. 71 | var messageToServer = new NetMQMessage(); 72 | messageToServer.AppendEmptyFrame(); 73 | messageToServer.Append(MessageQueueCommonItems.SerializeToJson(message)); 74 | 75 | // Sending message. 76 | socket.SendMultipartMessage(messageToServer); 77 | } 78 | catch (QueueException queueException) 79 | { 80 | #region Logging - Error 81 | logger.Fatal(queueException, queueException.Message); 82 | #endregion 83 | 84 | throw; 85 | } 86 | catch (Exception ex) 87 | { 88 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 89 | errorCode: QueueErrorCode.FailedToSendMessage, 90 | message: ErrorMessages.FailedToSendMessage, 91 | innerException: ex, 92 | queueContext: CommonItems.ZeroMqName, 93 | address: zmqConfiguration.Address, 94 | logger: logger); 95 | } 96 | #endregion 97 | } 98 | #endregion 99 | 100 | #region IDisposable Implementation 101 | public void Dispose() 102 | { 103 | Dispose(true); 104 | GC.SuppressFinalize(this); 105 | } 106 | 107 | private void Dispose(bool disposing) 108 | { 109 | #region Cleanup 110 | if (disposing) 111 | { 112 | socket?.Dispose(); 113 | poller?.Dispose(); 114 | } 115 | #endregion 116 | } 117 | #endregion 118 | 119 | #region Private Methods 120 | /// 121 | /// Helper event handler. 122 | /// 123 | private void ResponseReady(object sender, NetMQSocketEventArgs e) 124 | { 125 | try 126 | { 127 | // Receiving message. 128 | // Server will send empty frame followed by actual data frame so we need to skip the first frame. 129 | var receivedMessage = e.Socket.ReceiveMultipartStrings(); 130 | 131 | if (receivedMessage.Count > 1) 132 | { 133 | // Converting from Json. 134 | var convertedMessage = MessageQueueCommonItems.DeserializeFromJson(receivedMessage[1]); 135 | 136 | // Calling handler. 137 | OnResponseReady?.Invoke(convertedMessage); 138 | } 139 | } 140 | catch (QueueException queueException) 141 | { 142 | #region Logging - Error 143 | logger.Fatal(queueException, queueException.Message); 144 | #endregion 145 | } 146 | catch (Exception ex) 147 | { 148 | MessageQueueCommonItems.PrepareAndLogQueueException( 149 | errorCode: QueueErrorCode.FailedToReceiveResponseMessage, 150 | message: ErrorMessages.FailedToReceiveResponseMessage, 151 | innerException: ex, 152 | queueContext: CommonItems.ZeroMqName, 153 | address: zmqConfiguration.Address, 154 | logger: logger); 155 | } 156 | } 157 | #endregion 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /Tests/MessageQueue.Sender/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using MessageQueue.Core.Services; 4 | using MessageQueue.Log.NLog.Concrete; 5 | using MessageQueue.CofigurationProvider.AppSettings.Concrete; 6 | 7 | namespace MessageQueue.Sender 8 | { 9 | class Program 10 | { 11 | #region Private Data Members 12 | private const ushort messageCount = 25; 13 | private const ushort delayBetweenMessagesInMs = 200; 14 | #endregion 15 | 16 | static void Main(string[] args) 17 | { 18 | Console.WriteLine("Please select the Message Queue (Sender):" + Environment.NewLine + "1- ZeroMq" + Environment.NewLine + "2- RabbitMq" + Environment.NewLine + "3- ServiceBus"); 19 | var option = Console.ReadKey(); 20 | 21 | switch (option.Key) 22 | { 23 | case ConsoleKey.D1: 24 | case ConsoleKey.NumPad1: 25 | Test_ZeroMqFaF_Send(); 26 | break; 27 | 28 | case ConsoleKey.D2: 29 | case ConsoleKey.NumPad2: 30 | Test_RabbitMqFaF_Send(); 31 | break; 32 | 33 | case ConsoleKey.D3: 34 | case ConsoleKey.NumPad3: 35 | Test_ServiceBusFaF_Send(); 36 | break; 37 | 38 | default: 39 | Test_ZeroMqFaF_Send(); 40 | break; 41 | } 42 | 43 | Console.ReadKey(); 44 | } 45 | 46 | #region ZeroMq 47 | public static async void Test_ZeroMqFaF_Send() 48 | { 49 | try 50 | { 51 | Console.WriteLine(); 52 | Console.WriteLine("ZeroMq test outbound messages... (press any key to start sending)"); 53 | Console.ReadKey(); 54 | Console.WriteLine("Started (message count: {0})....", messageCount); 55 | 56 | using (var outboundMessageQueue = MessagingQueueFactory.CreateOutboundFaF(new AppSettingsConfigurationProvider(), "ZeroMqFaFOutbound", new NQueueLogger("Default"))) 57 | { 58 | for (int i = 0; i < messageCount; i++) 59 | { 60 | var message = $"This is FAF message number: {i} (sent at: {DateTime.Now.ToLongTimeString()})"; 61 | 62 | Console.WriteLine("Pushing: " + Environment.NewLine + message); 63 | 64 | outboundMessageQueue.SendMessage(message); 65 | //await outboundMessageQueue.SendMessageAsync(message); 66 | 67 | Console.WriteLine("Pushed successfully..." + Environment.NewLine); 68 | 69 | // Adding delay. 70 | Thread.Sleep(delayBetweenMessagesInMs); 71 | } 72 | } 73 | } 74 | catch (Exception ex) 75 | { 76 | Console.WriteLine(ex); 77 | } 78 | } 79 | #endregion 80 | 81 | #region RabbitMq 82 | public static async void Test_RabbitMqFaF_Send() 83 | { 84 | try 85 | { 86 | Console.WriteLine(); 87 | Console.WriteLine("RabbitMq test outbound messages (press any key to start sending)..."); 88 | Console.ReadKey(); 89 | Console.WriteLine("Started (message count: {0})....", messageCount); 90 | 91 | // Creating queue object from factory. 92 | using (var outboundMessageQueue = MessagingQueueFactory.CreateOutboundFaF(new AppSettingsConfigurationProvider(), "RabbitMqFaFOutbound", new NQueueLogger("Default"))) 93 | { 94 | for (int i = 0; i < messageCount; i++) 95 | { 96 | var message = $"This is FAF message number: {i} (sent at: {DateTime.Now.ToLongTimeString()})"; 97 | 98 | Console.WriteLine("Pushing: " + Environment.NewLine + message); 99 | 100 | outboundMessageQueue.SendMessage(message); 101 | //await outboundMessageQueue.SendMessageAsync(message); 102 | 103 | Console.WriteLine("Pushed successfully..." + Environment.NewLine); 104 | 105 | Thread.Sleep(delayBetweenMessagesInMs); 106 | } 107 | } 108 | } 109 | catch (Exception ex) 110 | { 111 | Console.WriteLine(ex); 112 | } 113 | } 114 | #endregion 115 | 116 | #region ServiceBus 117 | public static async void Test_ServiceBusFaF_Send() 118 | { 119 | try 120 | { 121 | Console.WriteLine(); 122 | Console.WriteLine("ServiceBus test outbound messages (press any key to start sending)..."); 123 | Console.ReadKey(); 124 | Console.WriteLine("Started (message count: {0})....", messageCount); 125 | 126 | // Creating queue object from factory. 127 | using (var outboundMessageQueue = MessagingQueueFactory.CreateOutboundFaF(new AppSettingsConfigurationProvider(), "ServiceBusFaFOutbound", new NQueueLogger("Default"))) 128 | { 129 | for (int i = 0; i < messageCount; i++) 130 | { 131 | var message = $"This is FAF message number: {i} (sent at: {DateTime.Now.ToLongTimeString()})"; 132 | 133 | Console.WriteLine("Pushing: " + Environment.NewLine + message); 134 | 135 | outboundMessageQueue.SendMessage(message); 136 | //await outboundMessageQueue.SendMessageAsync(message); 137 | 138 | Console.WriteLine("Pushed successfully..." + Environment.NewLine); 139 | 140 | Thread.Sleep(delayBetweenMessagesInMs); 141 | } 142 | } 143 | } 144 | catch (Exception ex) 145 | { 146 | Console.WriteLine(ex); 147 | } 148 | } 149 | #endregion 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /MessageQueue.CofigurationProvider.AppSettings/Properties/ErrorMessages.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Failed to retrieve configuration (identifier: {0}) from cofiguration file. 122 | 123 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Concrete/Inbound/ZmqInboundRaR.cs: -------------------------------------------------------------------------------- 1 | using NetMQ; 2 | using System; 3 | using MessageQueue.Core.Helper; 4 | using System.Collections.Generic; 5 | using MessageQueue.Core.Abstract; 6 | using MessageQueue.Core.Concrete; 7 | using MessageQueue.ZeroMq.Helper; 8 | using MessageQueue.Core.Properties; 9 | using MessageQueue.ZeroMq.Abstract; 10 | using MessageQueue.Log.Core.Abstract; 11 | using MessageQueue.Core.Abstract.Inbound; 12 | 13 | namespace MessageQueue.ZeroMq.Concrete.Inbound 14 | { 15 | /// 16 | /// ZeroMq based implementation of IInboundRaRMq. 17 | /// 18 | internal sealed class ZmqInboundRaR : BaseZeroMq, IInboundRaRMq 19 | { 20 | #region Private Methods 21 | private volatile bool isReceivingMessages; 22 | #endregion 23 | 24 | #region Constructors 25 | public ZmqInboundRaR(Dictionary configuration, IQueueLogger loggerObject) 26 | { 27 | try 28 | { 29 | #region Initialization 30 | base.Initialize(configuration, ZeroMqSocketType.Router, true, loggerObject); 31 | 32 | // Setting fields. 33 | Address = zmqConfiguration.Address; 34 | 35 | // Binding on receive event. 36 | base.socket.ReceiveReady += ReceiveReady; 37 | 38 | // Initializing poller. 39 | poller = new NetMQPoller(); 40 | poller.RunAsync(); 41 | #endregion 42 | } 43 | catch (Exception ex) when (!(ex is QueueException)) 44 | { 45 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 46 | errorCode: QueueErrorCode.FailedToInitializeMessageQueue, 47 | message: ErrorMessages.FailedToInitializeMessageQueue, 48 | innerException: ex, 49 | queueContext: CommonItems.ZeroMqName, 50 | address: zmqConfiguration?.Address, 51 | logger: logger); 52 | } 53 | } 54 | #endregion 55 | 56 | #region IInboundRaRMq Implementation 57 | public string Address { get; } 58 | 59 | public event Action> OnRequestReady; 60 | 61 | public bool HasMessage() 62 | { 63 | try 64 | { 65 | return socket.HasIn; 66 | } 67 | catch (Exception ex) 68 | { 69 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 70 | errorCode: QueueErrorCode.FailedToCheckQueueHasMessage, 71 | message: ErrorMessages.FailedToCheckQueueHasMessage, 72 | innerException: ex, 73 | queueContext: CommonItems.ZeroMqName, 74 | address: zmqConfiguration.Address, 75 | logger: logger); 76 | } 77 | } 78 | 79 | public void StartReceivingRequest() 80 | { 81 | try 82 | { 83 | lock (poller) 84 | { 85 | if (!isReceivingMessages) 86 | { 87 | poller.Add(socket); 88 | 89 | // Updating flag. 90 | isReceivingMessages = true; 91 | } 92 | } 93 | } 94 | catch (Exception ex) 95 | { 96 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 97 | errorCode: QueueErrorCode.FailedToStartReceivingRequest, 98 | message: ErrorMessages.FailedToStartReceivingRequest, 99 | innerException: ex, 100 | queueContext: CommonItems.ZeroMqName, 101 | address: zmqConfiguration.Address, 102 | logger: logger); 103 | } 104 | } 105 | 106 | public void StopReceivingRequest() 107 | { 108 | try 109 | { 110 | lock (poller) 111 | { 112 | if (isReceivingMessages) 113 | { 114 | poller.Remove(socket); 115 | 116 | // Updating flag. 117 | isReceivingMessages = false; 118 | } 119 | } 120 | } 121 | catch (Exception ex) 122 | { 123 | MessageQueueCommonItems.PrepareAndLogQueueException( 124 | errorCode: QueueErrorCode.FailedToStopReceivingRequest, 125 | message: ErrorMessages.FailedToStopReceivingRequest, 126 | innerException: ex, 127 | queueContext: CommonItems.ZeroMqName, 128 | address: zmqConfiguration.Address, 129 | logger: logger); 130 | } 131 | } 132 | #endregion 133 | 134 | #region IDisposable Implementation 135 | public void Dispose() 136 | { 137 | Dispose(true); 138 | GC.SuppressFinalize(this); 139 | } 140 | 141 | private void Dispose(bool disposing) 142 | { 143 | #region Cleanup 144 | if (disposing) 145 | { 146 | socket?.Dispose(); 147 | poller?.Dispose(); 148 | } 149 | #endregion 150 | } 151 | #endregion 152 | 153 | #region Private Methods 154 | /// 155 | /// Helper event handler. 156 | /// 157 | private void ReceiveReady(object sender, NetMQSocketEventArgs e) 158 | { 159 | try 160 | { 161 | // Receiving client message. 162 | var clientRequest = e.Socket.ReceiveMultipartMessage(); 163 | 164 | // Parsing client message. 165 | var clientAddress = clientRequest[0]; 166 | var clientRequestData = MessageQueueCommonItems.DeserializeFromJson(clientRequest[2].ConvertToString()); 167 | 168 | // Calling handler. 169 | OnRequestReady?.Invoke(new ZmqRequestMessage(clientAddress, e.Socket, clientRequestData, ref logger)); 170 | } 171 | catch (QueueException queueException) 172 | { 173 | #region Logging - Error 174 | logger.Fatal(queueException, queueException.Message); 175 | #endregion 176 | } 177 | catch (Exception ex) 178 | { 179 | MessageQueueCommonItems.PrepareAndLogQueueException( 180 | errorCode: QueueErrorCode.FailedToReceiveRequestMessage, 181 | message: ErrorMessages.FailedToReceiveRequestMessage, 182 | innerException: ex, 183 | queueContext: CommonItems.ZeroMqName, 184 | address: zmqConfiguration.Address, 185 | logger: logger); 186 | } 187 | } 188 | #endregion 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /MessageQueue.RabbitMq/Concrete/Outbound/RmqOutboundFaF.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using RabbitMQ.Client; 3 | using System.Threading.Tasks; 4 | using MessageQueue.Core.Helper; 5 | using MessageQueue.Core.Concrete; 6 | using System.Collections.Generic; 7 | using MessageQueue.RabbitMq.Helper; 8 | using MessageQueue.Core.Properties; 9 | using MessageQueue.Log.Core.Abstract; 10 | using MessageQueue.RabbitMq.Abstract; 11 | using MessageQueue.Core.Abstract.Outbound; 12 | 13 | namespace MessageQueue.RabbitMq.Concrete.Outbound 14 | { 15 | /// 16 | /// RabbitMq based implementation of IOutboundFaFMq. 17 | /// 18 | internal sealed class RmqOutboundFaF : BaseRabbitMq, IOutboundFaFMq 19 | { 20 | #region Private Data Members 21 | private string exchangeName, routingKey; 22 | private object lockForQueueOperation = new object(); 23 | #endregion 24 | 25 | #region Constructors 26 | public RmqOutboundFaF(Dictionary configuration, IQueueLogger loggerObject) 27 | { 28 | try 29 | { 30 | #region Initialization 31 | base.Initialize(configuration, AmqpExchangeType.Direct, false, loggerObject); 32 | 33 | // Setting other fields. 34 | Address = rabbitMqConfiguration.Address; 35 | exchangeName = rabbitMqConfiguration.ExchangeName ?? string.Empty; 36 | routingKey = rabbitMqConfiguration.RoutingKey ?? rabbitMqConfiguration.QueueName; 37 | #endregion 38 | } 39 | catch (Exception ex) when (!(ex is QueueException)) 40 | { 41 | #region Adding Context Data 42 | var context = new Dictionary(); 43 | 44 | if (!string.IsNullOrEmpty(rabbitMqConfiguration?.ExchangeName)) 45 | { 46 | context.Add(CommonContextKeys.ExchangeName, rabbitMqConfiguration?.ExchangeName); 47 | } 48 | 49 | if (!string.IsNullOrEmpty(rabbitMqConfiguration?.RoutingKey)) 50 | { 51 | context.Add(CommonContextKeys.RoutingKey, rabbitMqConfiguration?.RoutingKey); 52 | } 53 | #endregion 54 | 55 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 56 | errorCode: QueueErrorCode.FailedToInitializeMessageQueue, 57 | message: ErrorMessages.FailedToInitializeMessageQueue, 58 | innerException: ex, 59 | queueContext: CommonItems.RabbitMqName, 60 | queueName: rabbitMqConfiguration?.QueueName, 61 | address: rabbitMqConfiguration?.Address, 62 | context: context, 63 | logger: logger); 64 | } 65 | } 66 | #endregion 67 | 68 | #region IOutboundFaFMq Implementation 69 | public string Address { get; private set; } 70 | 71 | public void SendMessage(TMessage message) 72 | { 73 | try 74 | { 75 | #region Sending Message 76 | lock (lockForQueueOperation) 77 | { 78 | model.BasicPublish(exchangeName, routingKey, modelProperties, MessageQueueCommonItems.SerializeToJsonBytes(message)); 79 | } 80 | #endregion 81 | } 82 | catch (QueueException queueException) 83 | { 84 | #region Logging - Error 85 | logger.Fatal(queueException, queueException.Message); 86 | #endregion 87 | 88 | throw; 89 | } 90 | catch (Exception ex) 91 | { 92 | #region Adding Context Data 93 | var context = new Dictionary(); 94 | 95 | if (!string.IsNullOrEmpty(rabbitMqConfiguration.ExchangeName)) 96 | { 97 | context.Add(CommonContextKeys.ExchangeName, rabbitMqConfiguration.ExchangeName); 98 | } 99 | 100 | if (!string.IsNullOrEmpty(routingKey)) 101 | { 102 | context.Add(CommonContextKeys.RoutingKey, routingKey); 103 | } 104 | #endregion 105 | 106 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 107 | errorCode: QueueErrorCode.FailedToSendMessage, 108 | message: ErrorMessages.FailedToSendMessage, 109 | innerException: ex, 110 | queueContext: CommonItems.RabbitMqName, 111 | queueName: rabbitMqConfiguration.QueueName, 112 | address: rabbitMqConfiguration.Address, 113 | context: context, 114 | logger: logger); 115 | } 116 | } 117 | 118 | public async Task SendMessageAsync(TMessage message) 119 | { 120 | try 121 | { 122 | #region Sending Message 123 | await Task.Run(() => SendMessage(message)); 124 | #endregion 125 | } 126 | catch (QueueException queueException) 127 | { 128 | #region Logging - Error 129 | logger.Fatal(queueException, queueException.Message); 130 | #endregion 131 | 132 | throw; 133 | } 134 | catch (Exception ex) 135 | { 136 | #region Adding Context Data 137 | var context = new Dictionary(); 138 | 139 | if (!string.IsNullOrEmpty(rabbitMqConfiguration.ExchangeName)) 140 | { 141 | context.Add(CommonContextKeys.ExchangeName, rabbitMqConfiguration.ExchangeName); 142 | } 143 | 144 | if (!string.IsNullOrEmpty(routingKey)) 145 | { 146 | context.Add(CommonContextKeys.RoutingKey, routingKey); 147 | } 148 | #endregion 149 | 150 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 151 | errorCode: QueueErrorCode.FailedToSendMessage, 152 | message: ErrorMessages.FailedToSendMessage, 153 | innerException: ex, 154 | queueContext: CommonItems.RabbitMqName, 155 | queueName: rabbitMqConfiguration.QueueName, 156 | address: rabbitMqConfiguration.Address, 157 | context: context, 158 | logger: logger); 159 | } 160 | } 161 | #endregion 162 | 163 | #region IDisposable Implementation 164 | public void Dispose() 165 | { 166 | Dispose(true); 167 | GC.SuppressFinalize(this); 168 | } 169 | 170 | private void Dispose(bool disposing) 171 | { 172 | #region Cleanup 173 | if (disposing) 174 | { 175 | connection?.Dispose(); 176 | model?.Dispose(); 177 | } 178 | #endregion 179 | } 180 | #endregion 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /MessageQueue.ZeroMq/Concrete/Inbound/ZmqInboundFaF.cs: -------------------------------------------------------------------------------- 1 | using NetMQ; 2 | using System; 3 | using System.Threading.Tasks; 4 | using MessageQueue.Core.Helper; 5 | using System.Collections.Generic; 6 | using MessageQueue.Core.Abstract; 7 | using MessageQueue.Core.Concrete; 8 | using MessageQueue.ZeroMq.Helper; 9 | using MessageQueue.Core.Properties; 10 | using MessageQueue.ZeroMq.Abstract; 11 | using MessageQueue.Log.Core.Abstract; 12 | using MessageQueue.Core.Abstract.Inbound; 13 | 14 | namespace MessageQueue.ZeroMq.Concrete.Inbound 15 | { 16 | /// 17 | /// ZeroMq based implementation of IInboundFaFMq. 18 | /// 19 | internal sealed class ZmqInboundFaF : BaseZeroMq, IInboundFaFMq 20 | { 21 | #region Private Methods 22 | private volatile bool isReceivingMessages; 23 | private object lockForQueueOperation = new object(); 24 | #endregion 25 | 26 | #region Constructors 27 | public ZmqInboundFaF(Dictionary configuration, IQueueLogger loggerObject) 28 | { 29 | try 30 | { 31 | #region Initialization 32 | base.Initialize(configuration, ZeroMqSocketType.Pull, true, loggerObject); 33 | 34 | // Setting fields. 35 | Address = zmqConfiguration.Address; 36 | 37 | // Binding on receive event. 38 | socket.ReceiveReady += ReceiveReady; 39 | 40 | // Initializing poller. 41 | poller = new NetMQPoller(); 42 | poller.RunAsync(); 43 | #endregion 44 | } 45 | catch (Exception ex) when (!(ex is QueueException)) 46 | { 47 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 48 | errorCode: QueueErrorCode.FailedToInitializeMessageQueue, 49 | message: ErrorMessages.FailedToInitializeMessageQueue, 50 | innerException: ex, 51 | queueContext: CommonItems.ZeroMqName, 52 | address: zmqConfiguration?.Address, 53 | logger: logger); 54 | } 55 | } 56 | #endregion 57 | 58 | #region IInboundFaFMq Implementation 59 | public string Address { get; } 60 | 61 | public event Action OnMessageReady; 62 | public event Func OnMessageReadyAsync; 63 | 64 | public bool HasMessage() 65 | { 66 | try 67 | { 68 | return socket.HasIn; 69 | } 70 | catch (Exception ex) 71 | { 72 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 73 | errorCode: QueueErrorCode.FailedToCheckQueueHasMessage, 74 | message: ErrorMessages.FailedToCheckQueueHasMessage, 75 | innerException: ex, 76 | queueContext: CommonItems.ZeroMqName, 77 | address: zmqConfiguration.Address, 78 | logger: logger); 79 | } 80 | } 81 | 82 | public void StartReceivingMessage() 83 | { 84 | try 85 | { 86 | lock (poller) 87 | { 88 | if (!isReceivingMessages) 89 | { 90 | poller.Add(socket); 91 | 92 | // Updating flag. 93 | isReceivingMessages = true; 94 | } 95 | } 96 | } 97 | catch (Exception ex) 98 | { 99 | throw MessageQueueCommonItems.PrepareAndLogQueueException( 100 | errorCode: QueueErrorCode.FailedToStartReceivingMessage, 101 | message: ErrorMessages.FailedToStartReceivingMessage, 102 | innerException: ex, 103 | queueContext: CommonItems.ZeroMqName, 104 | address: zmqConfiguration.Address, 105 | logger: logger); 106 | } 107 | } 108 | 109 | public void StopReceivingMessage() 110 | { 111 | try 112 | { 113 | lock (poller) 114 | { 115 | if (isReceivingMessages) 116 | { 117 | poller.Remove(socket); 118 | 119 | // Updating flag. 120 | isReceivingMessages = false; 121 | } 122 | } 123 | } 124 | catch (Exception ex) 125 | { 126 | MessageQueueCommonItems.PrepareAndLogQueueException( 127 | errorCode: QueueErrorCode.FailedToStopReceivingMessage, 128 | message: ErrorMessages.FailedToStopReceivingMessage, 129 | innerException: ex, 130 | queueContext: CommonItems.ZeroMqName, 131 | address: zmqConfiguration.Address, 132 | logger: logger); 133 | } 134 | } 135 | #endregion 136 | 137 | #region IDisposable Implementation 138 | public void Dispose() 139 | { 140 | Dispose(true); 141 | GC.SuppressFinalize(this); 142 | } 143 | 144 | private void Dispose(bool disposing) 145 | { 146 | #region Cleanup 147 | if (disposing) 148 | { 149 | socket?.Dispose(); 150 | poller?.Dispose(); 151 | } 152 | #endregion 153 | } 154 | #endregion 155 | 156 | #region Private Methods 157 | /// 158 | /// Helper event handler. 159 | /// 160 | private async void ReceiveReady(object sender, NetMQSocketEventArgs e) 161 | { 162 | try 163 | { 164 | string receivedMessage; 165 | 166 | // We need to lock as the sockets are not multi-threaded in ZeroMq. 167 | lock (lockForQueueOperation) 168 | { 169 | // Receiving message. 170 | receivedMessage = e.Socket.ReceiveFrameString(); 171 | } 172 | 173 | // Converting from Json. 174 | var convertedMessage = MessageQueueCommonItems.DeserializeFromJson(receivedMessage); 175 | var messageReceiveOptions = new ZmqMessageReceiveOptions(ref logger); 176 | 177 | // Calling handler (async is preferred over sync). 178 | if (OnMessageReadyAsync != null) 179 | { 180 | await OnMessageReadyAsync.Invoke(convertedMessage, messageReceiveOptions); 181 | } 182 | else 183 | { 184 | OnMessageReady?.Invoke(convertedMessage, messageReceiveOptions); 185 | } 186 | } 187 | catch (QueueException queueException) 188 | { 189 | #region Logging - Error 190 | logger.Fatal(queueException, queueException.Message); 191 | #endregion 192 | } 193 | catch (Exception ex) 194 | { 195 | MessageQueueCommonItems.PrepareAndLogQueueException( 196 | errorCode: QueueErrorCode.FailedToReceiveMessage, 197 | message: ErrorMessages.FailedToReceiveMessage, 198 | innerException: ex, 199 | queueContext: CommonItems.ZeroMqName, 200 | address: zmqConfiguration.Address, 201 | logger: logger); 202 | } 203 | } 204 | #endregion 205 | } 206 | } 207 | --------------------------------------------------------------------------------