├── .gitignore ├── .travis.yml ├── Docs └── ConnectionString.md ├── LICENSE ├── MessageBus.Binding.RabbitMQ.nuspec ├── MessageBus.Protobuf.nuspec ├── MessageBus.Proxy.nuspec ├── MessageBus.SignalR.nuspec ├── MessageBus.nuspec ├── README.md ├── Sources ├── .nuget │ └── NuGet.Config ├── Binding │ ├── RabbitMQ.IntegrationTests │ │ ├── ContractsAndServices │ │ │ ├── Data.cs │ │ │ ├── DuplexService.cs │ │ │ ├── IDuplexService.cs │ │ │ ├── IOneWayService.cs │ │ │ └── OneWayService.cs │ │ ├── LargeBinaryTransferTest.cs │ │ ├── MandatoryTest.cs │ │ ├── MessageFormatsTest.cs │ │ ├── NonTransactionalDuplexWithPredefinedCallbackQueueDeliveryTest.cs │ │ ├── NonTransactionalOneWayDeliveryTest.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── RabbitMQ.IntegrationTests.csproj │ │ ├── TransactionalOneWayTest.cs │ │ └── packages.config │ ├── RabbitMQ.UnitTests │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── RabbitMQ.UnitTests.csproj │ │ ├── RabbitMQBindingConfigurationElementTest.cs │ │ └── packages.config │ ├── RabbitMQ │ │ ├── Clent.Extensions │ │ │ ├── ConsumptionEnslistment.cs │ │ │ ├── IMessageReceiver.cs │ │ │ ├── NoAckMessageReceiver.cs │ │ │ ├── QueueingBasicConsumer.cs │ │ │ ├── QueueingBasicConsumerBase.cs │ │ │ ├── SharedQueue.cs │ │ │ ├── TransactionalMessageReceiver.cs │ │ │ └── TransactionalQueueConsumer.cs │ │ ├── CommunicationOperation.cs │ │ ├── ConnectionManager.cs │ │ ├── CurrentVersion.cs │ │ ├── DebugHelper.cs │ │ ├── IFaultMessageProcessor.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── RabbitMQ.csproj │ │ ├── RabbitMQBinding.cs │ │ ├── RabbitMQBindingConfigurationElement.cs │ │ ├── RabbitMQBindingSection.cs │ │ ├── RabbitMQChannelBase.cs │ │ ├── RabbitMQChannelListenerBase.cs │ │ ├── RabbitMQInputChannelBase.cs │ │ ├── RabbitMQOutputChannelBase.cs │ │ ├── RabbitMQTransportBindingElement.cs │ │ ├── RabbitMQTransportChannelFactory.cs │ │ ├── RabbitMQTransportChannelListener.cs │ │ ├── RabbitMQTransportElement.cs │ │ ├── RabbitMQTransportInputChannel.cs │ │ ├── RabbitMQTransportOutputChannel.cs │ │ ├── RabbitMQUri.cs │ │ ├── ReplyToBehavior.cs │ │ ├── TransactionalDispatchingEnslistment.cs │ │ └── packages.config │ ├── ZeroMQ.IntegrationTests │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── PubSubMessagingTest.cs │ │ ├── PushPullMessagingTest.cs │ │ ├── ServiceInterfaces │ │ │ ├── IPublicationService.cs │ │ │ └── IRequestReplyMessaging.cs │ │ ├── ZeroMQ.IntegrationTests.csproj │ │ ├── libzmq.dll │ │ └── packages.config │ └── ZeroMQ │ │ ├── DebugHelper.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── SocketMode.cs │ │ ├── ZMQBinding.cs │ │ ├── ZMQChannelBase.cs │ │ ├── ZMQChannelFactory.cs │ │ ├── ZMQChannelListener.cs │ │ ├── ZMQDuplexChannel.cs │ │ ├── ZMQInprocessBinding.cs │ │ ├── ZMQInputChannel.cs │ │ ├── ZMQOutputChannel.cs │ │ ├── ZMQReceivingChannelBase.cs │ │ ├── ZMQReplyChannel.cs │ │ ├── ZMQRequestChannel.cs │ │ ├── ZMQRequestContext.cs │ │ ├── ZMQTcpBinding.cs │ │ ├── ZMQTransportBindingElement.cs │ │ ├── ZeroMQ.csproj │ │ ├── libzmq.dll │ │ └── packages.config ├── Core.API │ ├── BusHeaderBase.cs │ ├── BusMessage.cs │ ├── Core.API.csproj │ ├── CreateQueueSettings.cs │ ├── DataContractKey.cs │ ├── HeaderFilterAttribute.cs │ ├── IAsyncSubscriber.cs │ ├── IBlockWatcher.cs │ ├── IBus.cs │ ├── IBusConfigurator.cs │ ├── IConfirmPublisher.cs │ ├── IErrorSubscriber.cs │ ├── IExceptionFilter.cs │ ├── IPublisher.cs │ ├── IPublisherConfigurator.cs │ ├── IPublishingErrorHandler.cs │ ├── IReceiver.cs │ ├── IRouteManager.cs │ ├── IRpcAsyncPublisher.cs │ ├── IRpcPublisher.cs │ ├── IRpcPublisherConfigurator.cs │ ├── ISerializer.cs │ ├── ISubscriber.cs │ ├── ISubscriberConfigurator.cs │ ├── ISubscription.cs │ ├── ITrace.cs │ ├── ITransactionalPublisher.cs │ ├── MessageSubscribtionAttribute.cs │ ├── NoIncomingConnectionAcceptedException.cs │ ├── RejectMessageException.cs │ ├── RpcCallException.cs │ ├── SubscribtionAttribute.cs │ ├── SubscribtionClosedException.cs │ ├── SubscriptionClosedException.cs │ └── XDeadHeader.cs ├── Core.IntegrationTest │ ├── AsyncSubscriberTest.cs │ ├── BlobTransferTest.cs │ ├── BusAnnotatedSubscriptionTests.cs │ ├── BusAnotatedSubscriptionTests.cs │ ├── BusAsyncRpcCommunicationTest.cs │ ├── BusBufferManagerTests.cs │ ├── BusDurableTests.cs │ ├── BusFailedDeliveryTest.cs │ ├── BusFullCycleTests.cs │ ├── BusMessageFormatTest.cs │ ├── BusMessageTests.cs │ ├── BusMonitorTests.cs │ ├── BusPerformanceTests.cs │ ├── BusPublisherTest.cs │ ├── BusReceiverTests.cs │ ├── BusRoutingKeyTest.cs │ ├── BusRpcCommunicationTest.cs │ ├── BusSubscriberTests.cs │ ├── BusTransactionalDelivery.cs │ ├── Contract.cs │ ├── Core.IntegrationTests.csproj │ ├── Data.cs │ ├── ErrorSubscriberTest.cs │ ├── GenericMessageTypeTests.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ProtobufSerializerTests.cs │ ├── QueueNonDurableTests.cs │ ├── app.config │ ├── contract.proto │ ├── libzmq.dll │ └── protoc.exe ├── Core.Protobuf │ ├── ConfiguratorExtensions.cs │ ├── Core.Protobuf.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ProtobufSerializer.cs │ └── packages.config ├── Core.Proxy.IntegrationTests │ ├── Core.Proxy.IntegrationTests.csproj │ ├── FullLoopTest.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── Core.Proxy │ ├── ChannelFactory.cs │ ├── ContractHelper.cs │ ├── Core.Proxy.csproj │ ├── DefaultHeadersProvider.cs │ ├── IChannelFactory.cs │ ├── IHeadersProvider.cs │ ├── IMessageFactory.cs │ ├── ISubscriptionFactory.cs │ ├── ISubscriptionSelector.cs │ ├── MessageFactory.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── PublishInterceptor.cs │ ├── SubscriptionFactory.cs │ ├── SubscriptionSelector.cs │ ├── app.config │ └── packages.config ├── Core.STandard │ ├── API │ │ ├── BusHeaderBase.cs │ │ ├── BusMessage.cs │ │ ├── CreateQueueSettings.cs │ │ ├── DataContractKey.cs │ │ ├── HeaderFilterAttribute.cs │ │ ├── IAsyncSubscriber.cs │ │ ├── IBlockWatcher.cs │ │ ├── IBus.cs │ │ ├── IBusConfigurator.cs │ │ ├── IConfirmPublisher.cs │ │ ├── IErrorSubscriber.cs │ │ ├── IExceptionFilter.cs │ │ ├── IPublisher.cs │ │ ├── IPublisherConfigurator.cs │ │ ├── IPublishingErrorHandler.cs │ │ ├── IReceiver.cs │ │ ├── IRouteManager.cs │ │ ├── IRpcAsyncPublisher.cs │ │ ├── IRpcPublisher.cs │ │ ├── IRpcPublisherConfigurator.cs │ │ ├── ISerializer.cs │ │ ├── ISubscriber.cs │ │ ├── ISubscriberConfigurator.cs │ │ ├── ISubscription.cs │ │ ├── ITrace.cs │ │ ├── ITransactionalPublisher.cs │ │ ├── MessageSubscribtionAttribute.cs │ │ ├── NoIncomingConnectionAcceptedException.cs │ │ ├── RejectMessageException.cs │ │ ├── RpcCallException.cs │ │ ├── SubscribtionAttribute.cs │ │ ├── SubscribtionClosedException.cs │ │ ├── SubscriptionClosedException.cs │ │ └── XDeadHeader.cs │ ├── AsyncActionHandler.cs │ ├── AsyncBusMessageCallHandler.cs │ ├── AsyncFunctionHandler.cs │ ├── AsyncRawHandler.cs │ ├── AsyncSubscriber.cs │ ├── BusConfigurator.cs │ ├── BusMessageProcedureHandler.cs │ ├── ConfirmPublisher.cs │ ├── Core.Standard.csproj │ ├── HelperExtensions.cs │ ├── ICallHandler.cs │ ├── IMessageConsumer.cs │ ├── IMessageHelper.cs │ ├── IMessageRegistry.cs │ ├── IRpcConsumer.cs │ ├── ISendHelper.cs │ ├── ISubscriptionHelper.cs │ ├── JsonSerializer.cs │ ├── LimitedConcurrencyLevelTaskScheduler.cs │ ├── MessageConsumer.cs │ ├── MessageFilterInfo.cs │ ├── MessageHelper.cs │ ├── MessageMonitor.cs │ ├── MessageMonitorConsumer.cs │ ├── MessagingConstants.cs │ ├── NullBlockWatcher.cs │ ├── NullCallHandler.cs │ ├── NullErrorSubscriber.cs │ ├── NullExceptionFilter.cs │ ├── NullPublishingErrorHandler.cs │ ├── NullTrace.cs │ ├── Publisher.cs │ ├── PublisherBase.cs │ ├── PublisherConfigurator.cs │ ├── RabbitMQBus.cs │ ├── RabbitMQConnectionString.cs │ ├── Receiver.cs │ ├── RouteManager.cs │ ├── RpcAsyncPublisher.cs │ ├── RpcConsumer.cs │ ├── RpcPublisherBase.cs │ ├── RpcPublisherConfigurator.cs │ ├── RpcSyncPublisher.cs │ ├── SendHelper.cs │ ├── Subscriber.cs │ ├── SubscriberBase.cs │ ├── SubscriberConfigurator.cs │ ├── Subscription.cs │ ├── SubscriptionHelper.cs │ ├── SubscriptionInfo.cs │ ├── SyncTaskScheduler.cs │ ├── TransactionalMessageConsumer.cs │ ├── TransactionalMessageMonitorConsumer.cs │ ├── TransactionalPublisher.cs │ └── XmlSerializer.cs ├── Core.SignalR.IntegrationTests │ ├── Core.SignalR.IntegrationTests.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── SignalRBackplaneTest.cs │ ├── app.config │ └── packages.config ├── Core.SignalR │ ├── Core.SignalR.csproj │ ├── DependencyResolverExtensions.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── RabbitMessageBus.cs │ ├── RabbitScaleoutConfiguration.cs │ ├── ScaleoutMessageSerializer.cs │ ├── Scripts │ │ ├── jquery-1.6.4-vsdoc.js │ │ ├── jquery-1.6.4.js │ │ ├── jquery-1.6.4.min.js │ │ ├── jquery.signalR-2.2.0.js │ │ └── jquery.signalR-2.2.0.min.js │ ├── app.config │ └── packages.config ├── Core.UnitTests │ ├── App.config │ ├── Core.UnitTests.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── RabbitMQBusConfigurationTests.cs │ ├── RabbitMQConnectionStringTest.cs │ └── packages.config ├── Core.ZeroMQ │ ├── Core.ZeroMQ.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── ZeroMQBus.cs ├── Core │ ├── API │ │ ├── ICallHandler.cs │ │ ├── IDispatcher.cs │ │ ├── IKnownContractCollector.cs │ │ ├── IMessageFilter.cs │ │ └── MessageFilterInfo.cs │ ├── ActionHandler.cs │ ├── Bus.cs │ ├── BusMessageHandler.cs │ ├── CallBackDispatcher.cs │ ├── Core.csproj │ ├── DataContract.cs │ ├── DataContractKey.cs │ ├── DispatcherBase.cs │ ├── FaultMessageProcessor.cs │ ├── KnownContractCollector.cs │ ├── MessagePumpSubscriptionBase.cs │ ├── MessageSubscribtionInfo.cs │ ├── MessagingConstancts.cs │ ├── MessagingConstants.cs │ ├── NullCallHandler.cs │ ├── NullErrorSubscriber.cs │ ├── NullMessageFilter.cs │ ├── NullPublishingErrorHandler.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Publisher.cs │ ├── PublisherConfigurator.cs │ ├── RabbitMQBus.cs │ ├── RabbitMQBusConfigSectionHandler.cs │ ├── RabbitMQMessageFilter.cs │ ├── RawBusMessageReader.cs │ ├── RawHandler.cs │ ├── Receiver.cs │ ├── Subscriber.cs │ ├── SubscriberConfigurator.cs │ ├── SubscriptionBase.cs │ ├── SubscriptionDispatcher.cs │ ├── TypeSubscription.cs │ └── packages.config ├── Core2 │ ├── AsyncActionHandler.cs │ ├── AsyncBusMessageCallHandler.cs │ ├── AsyncFunctionHandler.cs │ ├── AsyncRawHandler.cs │ ├── AsyncSubscriber.cs │ ├── BusConfigurator.cs │ ├── BusMessageProcedureHandler.cs │ ├── ConfirmPublisher.cs │ ├── Core2.csproj │ ├── HelperExtensions.cs │ ├── ICallHandler.cs │ ├── IMessageConsumer.cs │ ├── IMessageHelper.cs │ ├── IMessageRegistry.cs │ ├── IRpcConsumer.cs │ ├── ISendHelper.cs │ ├── ISubscriptionHelper.cs │ ├── JsonSerializer.cs │ ├── LimitedConcurrencyLevelTaskScheduler.cs │ ├── MessageConsumer.cs │ ├── MessageFilterInfo.cs │ ├── MessageHelper.cs │ ├── MessageMonitor.cs │ ├── MessageMonitorConsumer.cs │ ├── MessagingConstants.cs │ ├── NullBlockWatcher.cs │ ├── NullCallHandler.cs │ ├── NullErrorSubscriber.cs │ ├── NullExceptionFilter.cs │ ├── NullPublishingErrorHandler.cs │ ├── NullTrace.cs │ ├── Publisher.cs │ ├── PublisherBase.cs │ ├── PublisherConfigurator.cs │ ├── RabbitMQBus.cs │ ├── RabbitMQConnectionString.cs │ ├── Receiver.cs │ ├── RouteManager.cs │ ├── RpcAsyncPublisher.cs │ ├── RpcConsumer.cs │ ├── RpcPublisherBase.cs │ ├── RpcPublisherConfigurator.cs │ ├── RpcSyncPublisher.cs │ ├── SendHelper.cs │ ├── Subscriber.cs │ ├── SubscriberBase.cs │ ├── SubscriberConfigurator.cs │ ├── Subscription.cs │ ├── SubscriptionHelper.cs │ ├── SubscriptionInfo.cs │ ├── SyncTaskScheduler.cs │ ├── TransactionalMessageConsumer.cs │ ├── TransactionalMessageMonitorConsumer.cs │ ├── TransactionalPublisher.cs │ ├── XmlSerializer.cs │ └── app.config ├── Local.testsettings ├── MessageBus.sln ├── MessageBus.vsmdi └── TraceAndTestImpact.testsettings └── icon.png /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | solution: Sources/MessageBus.sln 3 | services: 4 | - rabbitmq 5 | install: 6 | - nuget restore Sources/MessageBus.sln 7 | - nuget install NUnit.Runners -Version 2.6.4 -OutputDirectory testrunner 8 | script: 9 | - xbuild /p:Configuration=Debug Sources/MessageBus.sln 10 | - mono ./testrunner/NUnit.Runners.2.6.4/tools/nunit-console.exe ./Sources/Core.IntegrationTest/bin/Debug/Core.IntegrationTest.dll 11 | - mono ./testrunner/NUnit.Runners.2.6.4/tools/nunit-console.exe ./Sources/Core.UnitTests/bin/Debug/Core.UnitTests.dll -------------------------------------------------------------------------------- /Docs/ConnectionString.md: -------------------------------------------------------------------------------- 1 | Connection Strings 2 | ========== 3 | 4 | ## AMQP 5 | 6 | ##### URL schema 7 | 8 | ``` 9 | amqp://username:password@localhost:5672/virtualhost/exchange?routingKey=value 10 | \_/ \_______________/ \_______/ \__/ \_________/ \_____________/ \_______/ 11 | | | | | | | | 12 | | | broker hostname | | | Specifies routing key value (optional) 13 | | | | | | 14 | | | | virtual host (optional) 15 | | | | | 16 | | | | | 17 | | | node port, if absent 5672 is used | 18 | | | | 19 | | rabbit mq user info, if absent guest:guest is used | 20 | | | 21 | schema name exchange name used for dispatching messages (optional) 22 | ``` 23 | 24 | ##### Optional values 25 | 26 | * Virtual host and exchange are both optional, however if only one specified it is considered to be exchange name, rather then virtual host name 27 | 28 | * Routing key will be used to publish and subscribe for messages, however by default amq.headers exchange is being used, which is routing key agnostic 29 | 30 | ##### Examples 31 | 32 | Local host with default port 33 | ``` 34 | amqp://localhost 35 | ``` 36 | 37 | Broker IP 10.0.0.1, default port, custom user name and password 38 | ``` 39 | amqp://user:12345@10.0.0.1 40 | ``` 41 | 42 | Broker IP 10.0.0.1, custom port 5000, virtual host name "v1", exchange name "customExchamge" 43 | ``` 44 | amqp://10.0.0.1:5000/v1/customExchange 45 | ``` -------------------------------------------------------------------------------- /MessageBus.Binding.RabbitMQ.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | MessageBus.Binding.RabbitMQ 5 | 2.2.0 6 | Michael Parshin 7 | false 8 | Message Bus RabbitMQ WCF Binding 9 | https://github.com/parshim/MessageBus 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /MessageBus.Protobuf.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | RabbitMQ.MessageBus.Protobuf 5 | $version$ 6 | Michael Parshin 7 | Michael Parshin 8 | false 9 | Message Bus infrastructure based on RabbitMQ message broker 10 | https://github.com/parshim/MessageBus 11 | https://raw.githubusercontent.com/parshim/MessageBus/master/icon.png 12 | RabbitMQ AMQP MessageBus Protobuf 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /MessageBus.Proxy.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | RabbitMQ.MessageBus.Proxy 5 | $version$ 6 | Michael Parshin 7 | false 8 | Message Bus infrastructure based on RabbitMQ message broker 9 | https://github.com/parshim/MessageBus 10 | https://raw.githubusercontent.com/parshim/MessageBus/master/icon.png 11 | RabbitMQ AMQP MessageBus 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /MessageBus.SignalR.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | RabbitMQ.MessageBus.SignalR 5 | $version$ 6 | Michael Parshin 7 | false 8 | Message Bus infrastructure based on RabbitMQ message broker 9 | https://github.com/parshim/MessageBus 10 | https://raw.githubusercontent.com/parshim/MessageBus/master/icon.png 11 | RabbitMQ AMQP MessageBus SignalR 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /MessageBus.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | RabbitMQ.MessageBus 5 | $version$ 6 | Michael Parshin 7 | Michael Parshin 8 | https://github.com/parshim/MessageBus 9 | https://raw.githubusercontent.com/parshim/MessageBus/master/icon.png 10 | false 11 | Message Bus infrastructure based on RabbitMQ message broker 12 | RabbitMQ AMQP MessageBus 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Sources/.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ.IntegrationTests/ContractsAndServices/Data.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace RabbitMQ.IntegrationTests.ContractsAndServices 4 | { 5 | [DataContract] 6 | [KnownType(typeof(ExtraData))] 7 | public class Data 8 | { 9 | [DataMember] 10 | public int Id { get; set; } 11 | 12 | [DataMember] 13 | public string Name { get; set; } 14 | } 15 | 16 | [DataContract] 17 | public class ExtraData : Data 18 | { 19 | [DataMember] 20 | public int Age { get; set; } 21 | } 22 | 23 | [DataContract] 24 | public class Blob 25 | { 26 | [DataMember] 27 | public int Id { get; set; } 28 | 29 | [DataMember] 30 | public byte[] Data { get; set; } 31 | } 32 | } -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ.IntegrationTests/ContractsAndServices/DuplexService.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel; 2 | 3 | namespace RabbitMQ.IntegrationTests.ContractsAndServices 4 | { 5 | [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)] 6 | public class DuplexService : IDuplexService 7 | { 8 | private readonly IDuplexService _process; 9 | private readonly Data _replyData; 10 | 11 | public DuplexService(IDuplexService process, Data replyData) 12 | { 13 | _process = process; 14 | _replyData = replyData; 15 | } 16 | 17 | public void Say(Data data) 18 | { 19 | _process.Say(data); 20 | 21 | IDuplexService callbackChannel = OperationContext.Current.GetCallbackChannel(); 22 | 23 | callbackChannel.Say(_replyData); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ.IntegrationTests/ContractsAndServices/IDuplexService.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel; 2 | 3 | namespace RabbitMQ.IntegrationTests.ContractsAndServices 4 | { 5 | [ServiceContract(CallbackContract = typeof(IDuplexService))] 6 | public interface IDuplexService 7 | { 8 | [OperationContract(IsOneWay = true)] 9 | void Say(Data data); 10 | } 11 | } -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ.IntegrationTests/ContractsAndServices/IOneWayService.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel; 2 | 3 | namespace RabbitMQ.IntegrationTests.ContractsAndServices 4 | { 5 | [ServiceContract] 6 | public interface IOneWayService 7 | { 8 | [OperationContract(IsOneWay = true, Action = "Say")] 9 | void Say(Data data); 10 | 11 | [OperationContract(IsOneWay = true, Action = "LargeData")] 12 | void LargeData(Blob data); 13 | } 14 | [ServiceContract] 15 | public interface IOneWayService2 16 | { 17 | [OperationContract(IsOneWay = true)] 18 | void Say2(Data data); 19 | } 20 | } -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ.IntegrationTests/ContractsAndServices/OneWayService.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel; 2 | 3 | namespace RabbitMQ.IntegrationTests.ContractsAndServices 4 | { 5 | [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)] 6 | public class OneWayService : IOneWayService, IOneWayService2 7 | { 8 | private readonly IOneWayService _processor; 9 | private readonly IOneWayService _errorProcessor; 10 | 11 | public OneWayService(IOneWayService processor, IOneWayService errorProcessor) 12 | { 13 | _processor = processor; 14 | _errorProcessor = errorProcessor; 15 | } 16 | 17 | [OperationBehavior(TransactionScopeRequired = true)] 18 | public void Say(Data data) 19 | { 20 | _errorProcessor.Say(data); 21 | _processor.Say(data); 22 | } 23 | 24 | public void LargeData(Blob data) 25 | { 26 | _errorProcessor.LargeData(data); 27 | _processor.LargeData(data); 28 | } 29 | 30 | public void Say2(Data data) 31 | { 32 | _errorProcessor.Say(data); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ.IntegrationTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("RabbitMQ.IntegrationTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("RabbitMQ.IntegrationTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("4af8dfd5-7932-4d7e-918c-ade1d7fdefa9")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ.IntegrationTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ.UnitTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("RabbitMQ.UnitTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("RabbitMQ.UnitTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c944638a-b761-4b11-bbe8-b9316cdc55bc")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ.UnitTests/RabbitMQBindingConfigurationElementTest.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Binding.RabbitMQ; 2 | using FluentAssertions; 3 | using NUnit.Framework; 4 | 5 | namespace RabbitMQ.UnitTests 6 | { 7 | [TestFixture] 8 | public class ConfigurationElementTest 9 | { 10 | [Test] 11 | public void RabbitMQBinding_ConfigurationElement_CreateInstance() 12 | { 13 | RabbitMQBindingConfigurationElement element = new RabbitMQBindingConfigurationElement("Binding0"); 14 | 15 | element.ExactlyOnce.Should().BeFalse(); 16 | element.PersistentDelivery.Should().BeFalse(); 17 | element.OneWayOnly.Should().BeTrue(); 18 | element.TTL.Should().BeNull(); 19 | element.ReplyToExchange.Should().BeNull(); 20 | element.ReplyToQueue.Should().BeNull(); 21 | element.AutoBindExchange.Should().BeNull(); 22 | element.ApplicationId.Should().BeNull(); 23 | element.HeaderNamespace.Should().BeNull(); 24 | element.MessageFormat.Should().Be(MessageFormat.Text); 25 | element.ProtocolVersion.Should().Be("DefaultProtocol"); 26 | element.ReaderQuotas.Should().NotBeNull(); 27 | element.Mandatory.Should().BeFalse(); 28 | element.Immediate.Should().BeFalse(); 29 | } 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ.UnitTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/Clent.Extensions/ConsumptionEnslistment.cs: -------------------------------------------------------------------------------- 1 | using System.Transactions; 2 | using RabbitMQ.Client; 3 | 4 | namespace MessageBus.Binding.RabbitMQ.Clent.Extensions 5 | { 6 | public class ConsumptionEnslistment : IEnlistmentNotification 7 | { 8 | private readonly ulong _deliveryTag; 9 | private readonly IModel _model; 10 | 11 | public ConsumptionEnslistment(ulong deliveryTag, IModel model) 12 | { 13 | _deliveryTag = deliveryTag; 14 | _model = model; 15 | } 16 | 17 | public void Prepare(PreparingEnlistment preparingEnlistment) 18 | { 19 | preparingEnlistment.Prepared(); 20 | } 21 | 22 | public void Commit(Enlistment enlistment) 23 | { 24 | if (_model.IsOpen) 25 | { 26 | _model.BasicAck(_deliveryTag, false); 27 | } 28 | 29 | enlistment.Done(); 30 | } 31 | 32 | public void Rollback(Enlistment enlistment) 33 | { 34 | if (_model.IsOpen) 35 | { 36 | _model.BasicNack(_deliveryTag, false, true); 37 | } 38 | 39 | enlistment.Done(); 40 | } 41 | 42 | public void InDoubt(Enlistment enlistment) 43 | { 44 | enlistment.Done(); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/Clent.Extensions/IMessageReceiver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using RabbitMQ.Client; 3 | 4 | namespace MessageBus.Binding.RabbitMQ.Clent.Extensions 5 | { 6 | interface IMessageReceiver 7 | { 8 | /// 9 | /// Returns next message in queue 10 | /// 11 | /// Maximum wait time 12 | /// 13 | BasicGetResult Receive(TimeSpan timeout); 14 | 15 | /// 16 | /// Waits till queue will receive any message. Blocks calling thread till queue have at least one message or till timeout. 17 | /// 18 | /// Maximum wait time 19 | /// True if queue have at least one message at method call or till timeout any message enquired 20 | bool WaitForMessage(TimeSpan timeout); 21 | 22 | /// 23 | /// Ensure that message with suplied delivery tag will not be redelivered 24 | /// 25 | /// 26 | void DropMessage(ulong deliveryTag); 27 | 28 | /// 29 | /// Message is accepted for processing 30 | /// 31 | /// 32 | void AcceptMessage(ulong deliveryTag); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/Clent.Extensions/NoAckMessageReceiver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using RabbitMQ.Client; 4 | 5 | namespace MessageBus.Binding.RabbitMQ.Clent.Extensions 6 | { 7 | public class NoAckMessageReceiver : IMessageReceiver 8 | { 9 | private readonly IModel _model; 10 | private readonly string _queue; 11 | 12 | private const int MinimalThreadSleepTickTime = 1; 13 | 14 | public NoAckMessageReceiver(IModel model, string queue) 15 | { 16 | _model = model; 17 | _queue = queue; 18 | } 19 | 20 | public BasicGetResult Receive(TimeSpan timeout) 21 | { 22 | DateTime startTime = DateTime.Now; 23 | TimeSpan remainingTime; 24 | 25 | do 26 | { 27 | BasicGetResult result = _model.BasicGet(_queue, true); 28 | 29 | if (result != null) 30 | { 31 | return result; 32 | } 33 | 34 | Thread.Sleep(MinimalThreadSleepTickTime); 35 | 36 | TimeSpan elapsedTime = DateTime.Now - startTime; 37 | remainingTime = timeout.Subtract(elapsedTime); 38 | 39 | } while (remainingTime > TimeSpan.Zero); 40 | 41 | return null; 42 | } 43 | 44 | public bool WaitForMessage(TimeSpan timeout) 45 | { 46 | return true; 47 | } 48 | 49 | public void DropMessage(ulong deliveryTag) 50 | { 51 | 52 | } 53 | 54 | public void AcceptMessage(ulong deliveryTag) 55 | { 56 | 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/Clent.Extensions/QueueingBasicConsumer.cs: -------------------------------------------------------------------------------- 1 | using RabbitMQ.Client; 2 | using RabbitMQ.Client.Events; 3 | 4 | namespace MessageBus.Binding.RabbitMQ.Clent.Extensions 5 | { 6 | /// 7 | /// Basic queue consumer implementation, message acknowledge is user responsibility 8 | /// 9 | public class QueueingNoAckBasicConsumer : QueueingBasicConsumerBase 10 | { 11 | public QueueingNoAckBasicConsumer() 12 | { 13 | } 14 | 15 | public QueueingNoAckBasicConsumer(IModel model) : base(model) 16 | { 17 | } 18 | 19 | public QueueingNoAckBasicConsumer(IModel model, SharedQueue queue) 20 | : base(model, queue) 21 | { 22 | } 23 | 24 | public override void DropMessage(ulong deliveryTag) 25 | { 26 | 27 | } 28 | 29 | public override void AcceptMessage(ulong deliveryTag) 30 | { 31 | 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/Clent.Extensions/TransactionalMessageReceiver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Transactions; 3 | using RabbitMQ.Client; 4 | 5 | namespace MessageBus.Binding.RabbitMQ.Clent.Extensions 6 | { 7 | public class TransactionalMessageReceiver : IMessageReceiver 8 | { 9 | private readonly IModel _model; 10 | private readonly string _queue; 11 | 12 | public TransactionalMessageReceiver(IModel model, string queue) 13 | { 14 | _model = model; 15 | _queue = queue; 16 | } 17 | 18 | public BasicGetResult Receive(TimeSpan timeout) 19 | { 20 | return _model.BasicGet(_queue, false); 21 | } 22 | 23 | public bool WaitForMessage(TimeSpan timeout) 24 | { 25 | return true; 26 | } 27 | 28 | public void DropMessage(ulong deliveryTag) 29 | { 30 | _model.BasicAck(deliveryTag, false); 31 | } 32 | 33 | public void AcceptMessage(ulong deliveryTag) 34 | { 35 | if (Transaction.Current != null) 36 | { 37 | Transaction.Current.EnlistVolatile(new ConsumptionEnslistment(deliveryTag, _model), EnlistmentOptions.None); 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/Clent.Extensions/TransactionalQueueConsumer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Transactions; 3 | using RabbitMQ.Client; 4 | using RabbitMQ.Client.Events; 5 | 6 | namespace MessageBus.Binding.RabbitMQ.Clent.Extensions 7 | { 8 | /// 9 | /// Queue consumer with transaction support 10 | /// 11 | public class TransactionalQueueConsumer : QueueingBasicConsumerBase 12 | { 13 | public TransactionalQueueConsumer() 14 | { 15 | } 16 | 17 | public TransactionalQueueConsumer(IModel model) : base(model) 18 | { 19 | } 20 | 21 | public TransactionalQueueConsumer(IModel model, SharedQueue queue) 22 | : base(model, queue) 23 | { 24 | } 25 | 26 | public override void DropMessage(ulong deliveryTag) 27 | { 28 | Model.BasicAck(deliveryTag, false); 29 | } 30 | 31 | public override void AcceptMessage(ulong deliveryTag) 32 | { 33 | if (Transaction.Current != null) 34 | { 35 | Transaction.Current.EnlistVolatile(new ConsumptionEnslistment(deliveryTag, Model), EnlistmentOptions.None); 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/CommunicationOperation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ServiceModel.Channels; 3 | 4 | namespace MessageBus.Binding.RabbitMQ 5 | { 6 | internal delegate void CommunicationOperation(TimeSpan timeout); 7 | internal delegate TResult CommunicationOperation(TimeSpan timeout); 8 | internal delegate TResult CommunicationOperation(TimeSpan timeout, out TArg arg0); 9 | internal delegate void SendOperation(Message message, TimeSpan timeout); 10 | } -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/CurrentVersion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using RabbitMQ.Client.Framing; 4 | 5 | namespace MessageBus.Binding.RabbitMQ 6 | { 7 | /// 8 | /// Properties of the current RabbitMQ Service Model Version 9 | /// 10 | public static class CurrentVersion 11 | { 12 | internal const String Scheme = "amqp"; 13 | 14 | internal static Encoding DefaultEncoding { get { return Encoding.UTF8; } } 15 | 16 | internal static class StatusCodes 17 | { 18 | public const int Ok = Constants.ReplySuccess; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/DebugHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace MessageBus.Binding.RabbitMQ 5 | { 6 | internal class DebugHelper 7 | { 8 | [ThreadStatic] 9 | private static Stopwatch _sw; 10 | 11 | public static void Start() 12 | { 13 | _sw = Stopwatch.StartNew(); 14 | } 15 | 16 | public static void Stop(string message, params object[] args) 17 | { 18 | _sw.Stop(); 19 | 20 | object[] copy = new object[args.Length + 1]; 21 | 22 | copy[0] = _sw.ElapsedMilliseconds; 23 | 24 | Array.Copy(args, 0, copy, 1, args.Length); 25 | 26 | Debug.Print(message, copy); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/IFaultMessageProcessor.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel.Channels; 2 | 3 | namespace MessageBus.Binding.RabbitMQ 4 | { 5 | public interface IFaultMessageProcessor 6 | { 7 | void Process(int code, string text, Message message); 8 | } 9 | } -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("RabbitMQ")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("RabbitMQ")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("1b6e2242-87cd-4231-8057-a0dab74d724b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | 38 | [assembly: InternalsVisibleTo("MessageBus.Core")] 39 | [assembly: InternalsVisibleTo("RabbitMQ.IntegrationTests")] 40 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/RabbitMQBindingSection.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel.Configuration; 2 | 3 | namespace MessageBus.Binding.RabbitMQ 4 | { 5 | /// 6 | /// Allows the RabbitMQBinding to be declarativley configured 7 | /// 8 | public sealed class RabbitMQBindingSection : StandardBindingCollectionElement 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/RabbitMQOutputChannelBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ServiceModel; 3 | using System.ServiceModel.Channels; 4 | 5 | namespace MessageBus.Binding.RabbitMQ 6 | { 7 | internal abstract class RabbitMQOutputChannelBase : RabbitMQChannelBase, IOutputChannel 8 | { 9 | private readonly SendOperation _sendMethod; 10 | private readonly EndpointAddress _address; 11 | private readonly Uri _via; 12 | 13 | protected RabbitMQOutputChannelBase(BindingContext context, EndpointAddress address, Uri via) 14 | : base(context) 15 | { 16 | _address = address; 17 | _via = via; 18 | _sendMethod = Send; 19 | } 20 | 21 | #region Async Methods 22 | 23 | public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state) 24 | { 25 | return _sendMethod.BeginInvoke(message, timeout, callback, state); 26 | } 27 | 28 | public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state) 29 | { 30 | return _sendMethod.BeginInvoke(message, Context.Binding.SendTimeout, callback, state); 31 | } 32 | 33 | public void EndSend(IAsyncResult result) 34 | { 35 | _sendMethod.EndInvoke(result); 36 | } 37 | 38 | #endregion 39 | 40 | public abstract void Send(Message message, TimeSpan timeout); 41 | 42 | public virtual void Send(Message message) 43 | { 44 | Send(message, Context.Binding.SendTimeout); 45 | } 46 | 47 | public EndpointAddress RemoteAddress 48 | { 49 | get { return _address; } 50 | } 51 | 52 | public Uri Via 53 | { 54 | get { return _via; } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/RabbitMQTransportChannelFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ServiceModel; 3 | using System.ServiceModel.Channels; 4 | 5 | namespace MessageBus.Binding.RabbitMQ 6 | { 7 | internal sealed class RabbitMQTransportChannelFactory : ChannelFactoryBase 8 | { 9 | private readonly BindingContext _context; 10 | private readonly CommunicationOperation _openMethod; 11 | 12 | public RabbitMQTransportChannelFactory(BindingContext context) 13 | { 14 | _context = context; 15 | _openMethod = Open; 16 | } 17 | 18 | protected override T OnCreateChannel(EndpointAddress address, Uri via) 19 | { 20 | IChannel channel; 21 | 22 | if (typeof (T) == typeof (IOutputChannel)) 23 | { 24 | channel = new RabbitMQTransportOutputChannel(_context, address, via); 25 | } 26 | else 27 | { 28 | return default(T); 29 | } 30 | 31 | return (T) channel; 32 | } 33 | 34 | protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) 35 | { 36 | return _openMethod.BeginInvoke(timeout, callback, state); 37 | } 38 | 39 | protected override void OnEndOpen(IAsyncResult result) 40 | { 41 | _openMethod.EndInvoke(result); 42 | } 43 | 44 | protected override void OnOpen(TimeSpan timeout) 45 | { 46 | 47 | } 48 | 49 | protected override void OnClose(TimeSpan timeout) 50 | { 51 | 52 | } 53 | 54 | protected override void OnAbort() 55 | { 56 | base.OnAbort(); 57 | OnClose(_context.Binding.CloseTimeout); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/ReplyToBehavior.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel.Description; 2 | using System.ServiceModel.Dispatcher; 3 | using System.ServiceModel; 4 | using System.ServiceModel.Channels; 5 | 6 | namespace MessageBus.Binding.RabbitMQ 7 | { 8 | public class ReplyToBehavior : IEndpointBehavior 9 | { 10 | public class ReplyToInspector : IDispatchMessageInspector 11 | { 12 | public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 13 | { 14 | var reply = request.Headers.ReplyTo; 15 | OperationContext.Current.OutgoingMessageHeaders.To = reply.Uri; 16 | OperationContext.Current.OutgoingMessageHeaders.RelatesTo = request.Headers.MessageId; 17 | return null; 18 | } 19 | 20 | public void BeforeSendReply(ref Message reply, object correlationState) 21 | { 22 | } 23 | } 24 | 25 | public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 26 | { 27 | } 28 | 29 | public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) 30 | { 31 | } 32 | 33 | public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 34 | { 35 | endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new ReplyToInspector()); 36 | } 37 | 38 | public void Validate(ServiceEndpoint endpoint) 39 | { 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/TransactionalDispatchingEnslistment.cs: -------------------------------------------------------------------------------- 1 | using System.Transactions; 2 | using RabbitMQ.Client; 3 | 4 | namespace MessageBus.Binding.RabbitMQ 5 | { 6 | internal class TransactionalDispatchingEnslistment : IEnlistmentNotification 7 | { 8 | private readonly IModel _model; 9 | 10 | public TransactionalDispatchingEnslistment(IModel model) 11 | { 12 | _model = model; 13 | } 14 | 15 | public void Prepare(PreparingEnlistment preparingEnlistment) 16 | { 17 | preparingEnlistment.Prepared(); 18 | } 19 | 20 | public void Commit(Enlistment enlistment) 21 | { 22 | if (_model.IsOpen) 23 | { 24 | _model.TxCommit(); 25 | } 26 | 27 | enlistment.Done(); 28 | } 29 | 30 | public void Rollback(Enlistment enlistment) 31 | { 32 | if (_model.IsOpen) 33 | { 34 | _model.TxRollback(); 35 | } 36 | 37 | enlistment.Done(); 38 | } 39 | 40 | public void InDoubt(Enlistment enlistment) 41 | { 42 | enlistment.Done(); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Sources/Binding/RabbitMQ/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ.IntegrationTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ZeroMQ.IntegrationTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ZeroMQ.IntegrationTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("85488638-47a3-4a58-ba51-6299e773e5f2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ.IntegrationTests/ServiceInterfaces/IPublicationService.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using System.ServiceModel; 3 | 4 | namespace ZeroMQ.IntegrationTests.ServiceInterfaces 5 | { 6 | [ServiceContract] 7 | public interface IPublicationService 8 | { 9 | [OperationContract(IsOneWay = true)] 10 | void Notify(Data data); 11 | } 12 | 13 | 14 | [DataContract] 15 | public class Data 16 | { 17 | [DataMember] 18 | public int Number { get; set; } 19 | 20 | [DataMember] 21 | public string Name { get; set; } 22 | } 23 | 24 | [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 25 | public class PublicationService : IPublicationService 26 | { 27 | private readonly IPublicationService _wrapped; 28 | 29 | public PublicationService(IPublicationService wrapped) 30 | { 31 | _wrapped = wrapped; 32 | } 33 | 34 | public void Notify(Data data) 35 | { 36 | _wrapped.Notify(data); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ.IntegrationTests/ServiceInterfaces/IRequestReplyMessaging.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using System.ServiceModel; 3 | 4 | namespace ZeroMQ.IntegrationTests.ServiceInterfaces 5 | { 6 | [ServiceContract] 7 | public interface IRequestReplyMessaging 8 | { 9 | [OperationContract] 10 | Result Operation(Request data); 11 | } 12 | 13 | [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 14 | public class RequestReplyMessaging : IRequestReplyMessaging 15 | { 16 | private readonly IRequestReplyMessaging _wrapped; 17 | 18 | public RequestReplyMessaging(IRequestReplyMessaging wrapped) 19 | { 20 | _wrapped = wrapped; 21 | } 22 | 23 | public Result Operation(Request data) 24 | { 25 | return _wrapped.Operation(data); 26 | } 27 | } 28 | 29 | [DataContract] 30 | public class Request 31 | { 32 | [DataMember] 33 | public int Number { get; set; } 34 | 35 | [DataMember] 36 | public string Name { get; set; } 37 | } 38 | 39 | [DataContract] 40 | public class Result 41 | { 42 | [DataMember] 43 | public int Number { get; set; } 44 | 45 | [DataMember] 46 | public string Name { get; set; } 47 | } 48 | } -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ.IntegrationTests/libzmq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parshim/MessageBus/0f7bbc3f7a0688555743f8983d224bb9553ae270/Sources/Binding/ZeroMQ.IntegrationTests/libzmq.dll -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ.IntegrationTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ/DebugHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace MessageBus.Binding.ZeroMQ 5 | { 6 | internal class DebugHelper 7 | { 8 | [ThreadStatic] 9 | private static Stopwatch _sw; 10 | 11 | public static void Start() 12 | { 13 | _sw = Stopwatch.StartNew(); 14 | } 15 | 16 | public static void Stop(string message, params object[] args) 17 | { 18 | _sw.Stop(); 19 | 20 | object[] copy = new object[args.Length + 1]; 21 | 22 | copy[0] = _sw.ElapsedMilliseconds; 23 | 24 | Array.Copy(args, 0, copy, 1, args.Length); 25 | 26 | Debug.Print(message, copy); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ZeroMQ")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ZeroMQ")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("53335792-bc87-49f4-a1eb-f374cac51c67")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ/SocketMode.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Binding.ZeroMQ 2 | { 3 | public enum SocketMode 4 | { 5 | PubSub, 6 | PushPull 7 | } 8 | } -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ/ZMQBinding.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel.Channels; 2 | using System.Xml; 3 | 4 | namespace MessageBus.Binding.ZeroMQ 5 | { 6 | public abstract class ZMQBinding : System.ServiceModel.Channels.Binding 7 | { 8 | protected ZMQBinding(string name, SocketMode socketMode) 9 | { 10 | Name = name; 11 | SocketMode = socketMode; 12 | } 13 | 14 | public override BindingElementCollection CreateBindingElements() 15 | { 16 | BinaryMessageEncodingBindingElement encoding = new BinaryMessageEncodingBindingElement(); 17 | 18 | ZMQTransportBindingElement transport = new ZMQTransportBindingElement(Scheme, SocketMode); 19 | 20 | if (ReaderQuotas != null) 21 | { 22 | ReaderQuotas.CopyTo(encoding.ReaderQuotas); 23 | } 24 | 25 | BindingElementCollection collection = new BindingElementCollection 26 | { 27 | encoding, 28 | transport 29 | }; 30 | 31 | return collection; 32 | } 33 | 34 | /// 35 | /// ZMQ Socket Mode 36 | /// 37 | public SocketMode SocketMode { get; set; } 38 | 39 | /// 40 | /// Serializer quotas 41 | /// 42 | public XmlDictionaryReaderQuotas ReaderQuotas { get; set; } 43 | } 44 | } -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ/ZMQInprocessBinding.cs: -------------------------------------------------------------------------------- 1 | using ZMQ; 2 | 3 | namespace MessageBus.Binding.ZeroMQ 4 | { 5 | public sealed class ZMQInprocessBinding : ZMQBinding 6 | { 7 | public ZMQInprocessBinding() 8 | : base("ZMQInprocessBinding", SocketMode.PubSub) 9 | { 10 | } 11 | 12 | public override string Scheme 13 | { 14 | get { return "inproc"; } 15 | } 16 | 17 | } 18 | } -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ/ZMQInputChannel.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel; 2 | using System.ServiceModel.Channels; 3 | using ZMQ; 4 | 5 | namespace MessageBus.Binding.ZeroMQ 6 | { 7 | public class ZMQInputChannel : ZMQReceivingChannelBase, IInputChannel 8 | { 9 | private readonly EndpointAddress _address; 10 | 11 | public ZMQInputChannel(ChannelManagerBase channelManager, BindingContext bindingContext, Context context, Socket socket, EndpointAddress address, SocketMode socketMode) 12 | : base(channelManager, bindingContext, context, socket, socketMode) 13 | { 14 | _address = address; 15 | } 16 | 17 | public override EndpointAddress LocalAddress { get { return _address; } } 18 | 19 | } 20 | } -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ/ZMQOutputChannel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ServiceModel; 3 | using System.ServiceModel.Channels; 4 | using ZMQ; 5 | 6 | namespace MessageBus.Binding.ZeroMQ 7 | { 8 | public class ZMQOutputChannel : ZMQChannelBase, IOutputChannel 9 | { 10 | private readonly EndpointAddress _remoteAddress; 11 | private readonly Uri _via; 12 | 13 | public ZMQOutputChannel(ChannelManagerBase channelManager, BindingContext context, Socket socket, SocketMode socketMode, EndpointAddress remoteAddress, Uri via) 14 | : base(channelManager, context, socket, socketMode) 15 | { 16 | _via = via; 17 | _remoteAddress = remoteAddress; 18 | } 19 | 20 | public EndpointAddress RemoteAddress { get { return _remoteAddress; } } 21 | 22 | public Uri Via { get { return _via; } } 23 | 24 | protected override void OnOpen(TimeSpan timeout) 25 | { 26 | string addr = _remoteAddress.Uri.ToString().TrimEnd('/'); 27 | 28 | _socket.Connect(addr); 29 | } 30 | 31 | protected override void OnClose(TimeSpan timeout) 32 | { 33 | _socket.Dispose(); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ/ZMQRequestContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ServiceModel.Channels; 3 | using System.Threading.Tasks; 4 | 5 | namespace MessageBus.Binding.ZeroMQ 6 | { 7 | public class ZMQRequestContext : RequestContext 8 | { 9 | private readonly Message _requestMessage; 10 | private readonly ZMQChannelBase _channel; 11 | 12 | public ZMQRequestContext(Message requestMessage, ZMQChannelBase channel) 13 | { 14 | _requestMessage = requestMessage; 15 | _channel = channel; 16 | } 17 | 18 | public override void Abort() 19 | { 20 | Close(); 21 | } 22 | 23 | public override void Close() 24 | { 25 | _requestMessage.Close(); 26 | } 27 | 28 | public override void Close(TimeSpan timeout) 29 | { 30 | Close(); 31 | } 32 | 33 | public override void Reply(Message message) 34 | { 35 | _channel.Send(message); 36 | } 37 | 38 | public override void Reply(Message message, TimeSpan timeout) 39 | { 40 | _channel.Send(message); 41 | } 42 | 43 | public override IAsyncResult BeginReply(Message message, AsyncCallback callback, object state) 44 | { 45 | return BeginReply(message, TimeSpan.MaxValue, callback, state); 46 | } 47 | 48 | public override IAsyncResult BeginReply(Message message, TimeSpan timeout, AsyncCallback callback, object state) 49 | { 50 | return Task.Factory.StartNew(s => Reply(message, timeout), state).ContinueWith(task => callback(task)); 51 | } 52 | 53 | public override void EndReply(IAsyncResult result) 54 | { 55 | Task.Factory.FromAsync(result, asyncResult => { }).Wait(); 56 | } 57 | 58 | public override Message RequestMessage 59 | { 60 | get { return _requestMessage; } 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ/ZMQTcpBinding.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Binding.ZeroMQ 2 | { 3 | public sealed class ZMQTcpBinding : ZMQBinding 4 | { 5 | public ZMQTcpBinding() 6 | : base("ZMQTcpBinding", SocketMode.PubSub) 7 | { 8 | } 9 | 10 | public override string Scheme 11 | { 12 | get { return "tcp"; } 13 | } 14 | } 15 | 16 | public sealed class ZMQIpcBinding : ZMQBinding 17 | { 18 | public ZMQIpcBinding() 19 | : base("ZMQIpcBinding", SocketMode.PubSub) 20 | { 21 | } 22 | 23 | public override string Scheme 24 | { 25 | get { return "ipc"; } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ/ZMQTransportBindingElement.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel.Channels; 2 | 3 | namespace MessageBus.Binding.ZeroMQ 4 | { 5 | public class ZMQTransportBindingElement : TransportBindingElement 6 | { 7 | private readonly string _scheme; 8 | private SocketMode _socketMode; 9 | 10 | public ZMQTransportBindingElement(string scheme, SocketMode socketMode) 11 | { 12 | _scheme = scheme; 13 | _socketMode = socketMode; 14 | } 15 | 16 | public override bool CanBuildChannelFactory(BindingContext context) 17 | { 18 | return typeof(TChannel) == typeof(IOutputChannel); 19 | } 20 | 21 | public override bool CanBuildChannelListener(BindingContext context) 22 | { 23 | return typeof(TChannel) == typeof(IInputChannel); 24 | } 25 | 26 | public override IChannelFactory BuildChannelFactory(BindingContext context) 27 | { 28 | return new ZMQChannelFactory(context, _socketMode); 29 | } 30 | 31 | public override IChannelListener BuildChannelListener(BindingContext context) 32 | { 33 | return new ZMQChannelListener(context, _socketMode); 34 | } 35 | 36 | public override BindingElement Clone() 37 | { 38 | return new ZMQTransportBindingElement(_scheme, _socketMode); 39 | } 40 | 41 | public override string Scheme 42 | { 43 | get { return _scheme; } 44 | } 45 | 46 | public SocketMode SocketMode 47 | { 48 | get { return _socketMode; } 49 | set { _socketMode = value; } 50 | } 51 | 52 | public override T GetProperty(BindingContext context) 53 | { 54 | return context.GetInnerProperty(); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ/libzmq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parshim/MessageBus/0f7bbc3f7a0688555743f8983d224bb9553ae270/Sources/Binding/ZeroMQ/libzmq.dll -------------------------------------------------------------------------------- /Sources/Binding/ZeroMQ/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Sources/Core.API/BusHeaderBase.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | public abstract class BusHeaderBase 4 | { 5 | /// 6 | /// Header name 7 | /// 8 | public string Name { get; set; } 9 | 10 | public abstract object GetValue(); 11 | } 12 | } -------------------------------------------------------------------------------- /Sources/Core.API/Core.API.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | ..\..\Binaries\ 6 | MessageBus.Core.API 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Sources/Core.API/DataContractKey.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | public class DataContractKey 4 | { 5 | private readonly string _name; 6 | private readonly string _namespace; 7 | 8 | public static readonly DataContractKey BinaryBlob = new DataContractKey("base64Binary", "http://schemas.microsoft.com/2003/10/Serialization/"); 9 | public static readonly DataContractKey Void = new DataContractKey("", ""); 10 | 11 | public DataContractKey(string name, string ns) 12 | { 13 | _name = name; 14 | _namespace = ns; 15 | } 16 | 17 | public string Name 18 | { 19 | get { return _name; } 20 | } 21 | 22 | public string Ns 23 | { 24 | get { return _namespace; } 25 | } 26 | 27 | public bool Equals(DataContractKey other) 28 | { 29 | return string.Equals(_name, other._name) && string.Equals(_namespace, other._namespace); 30 | } 31 | 32 | public override bool Equals(object obj) 33 | { 34 | if (ReferenceEquals(null, obj)) return false; 35 | if (ReferenceEquals(this, obj)) return true; 36 | if (obj.GetType() != this.GetType()) return false; 37 | return Equals((DataContractKey) obj); 38 | } 39 | 40 | public override int GetHashCode() 41 | { 42 | unchecked 43 | { 44 | return ((_name != null ? _name.GetHashCode() : 0)*397) ^ (_namespace != null ? _namespace.GetHashCode() : 0); 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Sources/Core.API/HeaderFilterAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)] 6 | public class HeaderFilterAttribute : Attribute 7 | { 8 | public HeaderFilterAttribute(string name, string value) 9 | { 10 | Name = name; 11 | Value = value; 12 | } 13 | 14 | /// 15 | /// Header name to filter on 16 | /// 17 | public string Name { get; private set; } 18 | 19 | /// 20 | /// Acceptable header value 21 | /// 22 | public string Value { get; private set; } 23 | } 24 | } -------------------------------------------------------------------------------- /Sources/Core.API/IBlockWatcher.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | /// 4 | /// Connection block whatcher 5 | /// 6 | public interface IBlockWatcher 7 | { 8 | /// 9 | /// Notifies upon connection blocking. Messages cannont be published via blocked connections 10 | /// 11 | /// Block reason 12 | void ConnectionBlocked(string reason); 13 | 14 | /// 15 | /// Notifies upon connection unblocking. 16 | /// 17 | void ConnectionUnblocked(); 18 | } 19 | } -------------------------------------------------------------------------------- /Sources/Core.API/IConfirmPublisher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public interface IConfirmPublisher : IPublisher 6 | { 7 | /// 8 | /// Waits for confirms of all messages published till method call 9 | /// 10 | /// 11 | /// 12 | bool WaitForConfirms(TimeSpan timeOut); 13 | } 14 | } -------------------------------------------------------------------------------- /Sources/Core.API/IErrorSubscriber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | /// 6 | /// Logger provider for subsriber exceptional cases 7 | /// 8 | public interface IErrorSubscriber 9 | { 10 | /// 11 | /// General unhendled exception 12 | /// 13 | /// 14 | void UnhandledException(Exception exception); 15 | 16 | /// 17 | /// Message serialization failed 18 | /// 19 | /// 20 | /// 21 | void MessageDeserializeException(RawBusMessage busMessage, Exception exception); 22 | 23 | /// 24 | /// Message handler throws exception 25 | /// 26 | /// 27 | /// 28 | void MessageDispatchException(RawBusMessage busMessage, Exception exception); 29 | 30 | /// 31 | /// Message filtered 32 | /// 33 | /// 34 | void MessageFilteredOut(RawBusMessage busMessage); 35 | 36 | /// 37 | /// Unregistered message arrived 38 | /// 39 | /// 40 | void UnregisteredMessageArrived(RawBusMessage busMessage); 41 | } 42 | } -------------------------------------------------------------------------------- /Sources/Core.API/IExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | /// 6 | /// Defines which exception should reject messages and which should requeue 7 | /// 8 | public interface IExceptionFilter 9 | { 10 | bool Filter(Exception exception, RawBusMessage message, bool redelivered, ulong deliveryTag); 11 | } 12 | } -------------------------------------------------------------------------------- /Sources/Core.API/IPublishingErrorHandler.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | /// 4 | /// 5 | /// 6 | public interface IPublishingErrorHandler 7 | { 8 | /// 9 | /// 10 | /// 11 | /// 12 | /// 13 | /// 14 | void DeliveryFailed(int errorCode, string text, RawBusMessage message); 15 | } 16 | } -------------------------------------------------------------------------------- /Sources/Core.API/IReceiver.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | /// 6 | /// Receive messages from the bus on demand, without handling message pump 7 | /// 8 | public interface IReceiver : ISubscription 9 | { 10 | /// 11 | /// Subscribe for message type. 12 | /// 13 | /// Message data contract type. 14 | /// Look for derived types and automaticaly register them for the same callback. 15 | /// Subscribe to message which sent only with specified headers. 16 | /// True if sucessfuly subscribed, otherwise false. 17 | /// 18 | bool Subscribe(bool hierarchy = false, IEnumerable filter = null); 19 | 20 | /// 21 | /// Receives next message in queue 22 | /// 23 | /// Message data contract type. 24 | /// Null if there is no messages queued 25 | TData Receive(); 26 | 27 | /// 28 | /// Receives next message in queue 29 | /// 30 | /// Message data contract type. 31 | /// Null if there is no messages queued 32 | BusMessage ReceiveBusMessage(); 33 | } 34 | } -------------------------------------------------------------------------------- /Sources/Core.API/IRpcPublisherConfigurator.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | public interface IRpcPublisherConfigurator : IPublisherConfigurator 4 | { 5 | /// 6 | /// Disable fast reply mechanism introduced in RabbitMQ. Publisher will create dedicated auto-delete queue to consume reply messages. 7 | /// If replyExchange parameter is different from default exchange (empty string) use IPublisherConfigurator.SetReplyTo method to specify routing key to bind queue to reply exchange. 8 | /// 9 | /// 10 | IRpcPublisherConfigurator DisableFastReply(); 11 | 12 | /// 13 | /// Set exchange name for reply messages. It can be used if fast reply is disabled and reply queue should be bounded to specified exchange. 14 | /// By default reply queue will get messages from default exchange. 15 | /// 16 | /// 17 | /// 18 | IRpcPublisherConfigurator SetReplyExchange(string replyExchange); 19 | 20 | /// 21 | /// Specify consumer tag. 22 | /// 23 | IRpcPublisherConfigurator SetConsumerTag(string consumerTag); 24 | } 25 | } -------------------------------------------------------------------------------- /Sources/Core.API/ISerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public interface ISerializer 6 | { 7 | string ContentType { get; } 8 | 9 | byte[] Serialize(RawBusMessage data); 10 | 11 | object Deserialize(Type dataType, byte[] body); 12 | } 13 | } -------------------------------------------------------------------------------- /Sources/Core.API/ISubscription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | /// 6 | /// Subscription interface provides basic interface to control receive messages 7 | /// 8 | public interface ISubscription : IDisposable 9 | { 10 | /// 11 | /// Start process subscribed message types. 12 | /// 13 | void Open(); 14 | 15 | /// 16 | /// Stop process messages 17 | /// 18 | void Close(); 19 | } 20 | } -------------------------------------------------------------------------------- /Sources/Core.API/ITrace.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | /// 4 | /// Trace all incoming and outgoing messages 5 | /// 6 | public interface ITrace 7 | { 8 | /// 9 | /// Message arrived 10 | /// 11 | /// 12 | /// 13 | /// 14 | void MessageArrived(string busId, RawBusMessage busMessage, string consumerTag); 15 | 16 | /// 17 | /// Message sent 18 | /// 19 | /// 20 | /// 21 | void MessageSent(string busId, RawBusMessage busMessage); 22 | } 23 | } -------------------------------------------------------------------------------- /Sources/Core.API/ITransactionalPublisher.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | public interface ITransactionalPublisher : IPublisher 4 | { 5 | 6 | /// 7 | /// Commits message delivery 8 | /// 9 | void Commit(); 10 | 11 | /// 12 | /// Rallback message delivery 13 | /// 14 | void Rollback(); 15 | } 16 | } -------------------------------------------------------------------------------- /Sources/Core.API/MessageSubscribtionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 6 | public class MessageSubscriptionAttribute : Attribute 7 | { 8 | /// 9 | /// Looking for derived types and automatically register them for the same callback 10 | /// 11 | public bool RegisterHierarchy { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /Sources/Core.API/NoIncomingConnectionAcceptedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public class NoIncomingConnectionAcceptedException : Exception 6 | { 7 | public NoIncomingConnectionAcceptedException() : base("Unable to open subscriber cause any input connection was accepted") 8 | { 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Sources/Core.API/RejectMessageException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public class RejectMessageException : Exception 6 | { 7 | public object ReplyData { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Sources/Core.API/RpcCallException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public enum RpcFailureReason 6 | { 7 | TimeOut, 8 | HandlerError, 9 | Reject, 10 | SerializationError, 11 | NotRouted 12 | } 13 | 14 | public class RpcCallException : Exception 15 | { 16 | public RpcCallException(RpcFailureReason reason) 17 | { 18 | Reason = reason; 19 | } 20 | 21 | public RpcCallException(RpcFailureReason reason, object replyData) 22 | { 23 | Reason = reason; 24 | ReplyData = replyData; 25 | } 26 | 27 | public RpcCallException(RpcFailureReason reason, string message) :base(message) 28 | { 29 | Reason = reason; 30 | } 31 | 32 | public RpcCallException(RpcFailureReason reason, Exception innerException):base("", innerException) 33 | { 34 | Reason = reason; 35 | } 36 | 37 | public RpcFailureReason Reason { get; private set; } 38 | 39 | public object ReplyData { get; private set; } 40 | } 41 | } -------------------------------------------------------------------------------- /Sources/Core.API/SubscribtionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] 6 | public class SubscribtionAttribute : Attribute 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Sources/Core.API/SubscribtionClosedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public class SubscribtionClosedException : Exception 6 | { 7 | public SubscribtionClosedException() 8 | : base("Unable to subscribe to message types after subscriber start to process messages") 9 | { 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Sources/Core.API/SubscriptionClosedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | /// 6 | /// 7 | /// 8 | public class SubscriptionClosedException : Exception 9 | { 10 | public SubscriptionClosedException() 11 | : base("Unable to subscribe to message types after subscriber start to process messages") 12 | { 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Sources/Core.IntegrationTest/BlobTransferTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using FluentAssertions; 4 | using MessageBus.Core.API; 5 | using NUnit.Framework; 6 | 7 | namespace Core.IntegrationTest 8 | { 9 | [TestFixture] 10 | public class BlobTransferTest 11 | { 12 | [Test] 13 | public void Bus_TransferBlob() 14 | { 15 | byte[] blob = new byte[10*1024*1024]; 16 | byte[] received = null; 17 | 18 | int counter = 0; 19 | 20 | ManualResetEvent ev = new ManualResetEvent(false); 21 | 22 | using (IBus bus = new MessageBus.Core.RabbitMQBus(c => c.SetConnectionRetries(50))) 23 | { 24 | using (ISubscriber subscriber = bus.CreateSubscriber(c => c.SetReceiveSelfPublish())) 25 | { 26 | subscriber.Subscribe((byte[] bytes) => 27 | { 28 | received = bytes; 29 | counter++; 30 | }); 31 | 32 | subscriber.Subscribe(new Action(ok => ev.Set())); 33 | 34 | subscriber.Open(); 35 | 36 | const int expected = 5; 37 | 38 | using (IPublisher publisher = bus.CreatePublisher()) 39 | { 40 | for (int i = 0; i < expected; i++) 41 | { 42 | publisher.Send(blob); 43 | } 44 | 45 | publisher.Send(new OK()); 46 | } 47 | 48 | bool waitOne = ev.WaitOne(TimeSpan.FromSeconds(60)); 49 | 50 | waitOne.Should().BeTrue(); 51 | 52 | counter.Should().Be(expected); 53 | } 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /Sources/Core.IntegrationTest/BusPublisherTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core; 3 | using MessageBus.Core.API; 4 | using NUnit.Framework; 5 | 6 | namespace Core.IntegrationTest 7 | { 8 | [TestFixture] 9 | public class BusPublisherTest 10 | { 11 | [Test] 12 | public void WaitForConfirm_ConfirmShouldArrive() 13 | { 14 | using (IBus bus = new RabbitMQBus()) 15 | { 16 | using (IConfirmPublisher publisher = bus.CreateConfirmPublisher()) 17 | { 18 | publisher.Send(new Person 19 | { 20 | Id = 5 21 | }); 22 | 23 | var waitForConfirms = publisher.WaitForConfirms(TimeSpan.FromSeconds(10)); 24 | 25 | Assert.IsTrue(waitForConfirms); 26 | } 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/Core.IntegrationTest/BusRoutingKeyTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using FluentAssertions; 4 | using MessageBus.Core; 5 | using MessageBus.Core.API; 6 | using NUnit.Framework; 7 | 8 | namespace Core.IntegrationTest 9 | { 10 | [TestFixture] 11 | public class BusRoutingKeyTest 12 | { 13 | [Test] 14 | public void SendAndReciveMessageFromFanoutExchangeWithRoutingKey() 15 | { 16 | using (IBus busA = new RabbitMQBus(), busB = new RabbitMQBus()) 17 | { 18 | Person expected = new Person 19 | { 20 | Id = 5 21 | }; 22 | 23 | Person actual = null; 24 | 25 | ManualResetEvent ev = new ManualResetEvent(false); 26 | 27 | using (var subscriber = busB.CreateSubscriber(c => c.SetExchange("amq.fanout").SetRoutingKey("MyKey"))) 28 | { 29 | subscriber.Subscribe((Person p) => 30 | { 31 | actual = p; 32 | 33 | ev.Set(); 34 | }); 35 | 36 | subscriber.Open(); 37 | 38 | using (var publisher = busA.CreatePublisher(c => c.SetExchange("amq.fanout").SetRoutingKey("MyKey"))) 39 | { 40 | publisher.Send(expected); 41 | } 42 | 43 | bool waitOne = ev.WaitOne(TimeSpan.FromSeconds(20)); 44 | 45 | waitOne.Should().BeTrue("Message not received"); 46 | 47 | actual.ShouldBeEquivalentTo(expected); 48 | } 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Sources/Core.IntegrationTest/Data.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Core.IntegrationTest 5 | { 6 | [DataContract] 7 | public class InternalHierarchy 8 | { 9 | [DataMember] 10 | public List Data { get; set; } 11 | } 12 | 13 | [DataContract] 14 | [KnownType(typeof(Person))] 15 | [KnownType(typeof(Car))] 16 | public class Data 17 | { 18 | 19 | } 20 | 21 | [DataContract] 22 | public class Person : Data 23 | { 24 | [DataMember] 25 | public int Id { get; set; } 26 | 27 | protected bool Equals(Person other) 28 | { 29 | return Id == other.Id; 30 | } 31 | 32 | public override bool Equals(object obj) 33 | { 34 | if (ReferenceEquals(null, obj)) return false; 35 | if (ReferenceEquals(this, obj)) return true; 36 | if (obj.GetType() != GetType()) return false; 37 | return Equals((Person)obj); 38 | } 39 | 40 | public override int GetHashCode() 41 | { 42 | return Id; 43 | } 44 | } 45 | 46 | [DataContract] 47 | public class Car : Data 48 | { 49 | [DataMember] 50 | public string Number { get; set; } 51 | 52 | protected bool Equals(Car other) 53 | { 54 | return string.Equals(Number, other.Number); 55 | } 56 | 57 | public override bool Equals(object obj) 58 | { 59 | if (ReferenceEquals(null, obj)) return false; 60 | if (ReferenceEquals(this, obj)) return true; 61 | if (obj.GetType() != GetType()) return false; 62 | return Equals((Car)obj); 63 | } 64 | 65 | public override int GetHashCode() 66 | { 67 | return (Number != null ? Number.GetHashCode() : 0); 68 | } 69 | } 70 | 71 | [DataContract(Namespace = "bus.test.org")] 72 | public class OK 73 | { 74 | } 75 | } -------------------------------------------------------------------------------- /Sources/Core.IntegrationTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Core.IntegrationTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Core.IntegrationTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("63489bdc-56ce-4de1-96b6-e81fd1ac9763")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Sources/Core.IntegrationTest/ProtobufSerializerTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using FluentAssertions; 4 | using MessageBus.Core; 5 | using MessageBus.Core.Protobuf; 6 | using NUnit.Framework; 7 | 8 | namespace Core.IntegrationTest 9 | { 10 | [TestFixture] 11 | public class ProtobufSerializerTests 12 | { 13 | [Test] 14 | public void Protobuf_Serialize_Deserialize_Test() 15 | { 16 | var person = new Google.Protobuf.Examples.AddressBook.Person 17 | { 18 | Name = "Michael", 19 | Email = "parshim@gmail.com" 20 | }; 21 | 22 | using (var bus = new RabbitMQBus()) 23 | { 24 | using (var subscriber = bus.CreateSubscriber(c => c.AddProtobufSerializer().SetReceiveSelfPublish())) 25 | { 26 | Google.Protobuf.Examples.AddressBook.Person actual = null; 27 | 28 | ManualResetEvent ev = new ManualResetEvent(false); 29 | 30 | subscriber.Subscribe(p => 31 | { 32 | actual = p; 33 | 34 | ev.Set(); 35 | }); 36 | 37 | subscriber.Open(); 38 | 39 | using (var publisher = bus.CreatePublisher(c => c.UseProtobufSerializer())) 40 | { 41 | publisher.Send(person); 42 | } 43 | 44 | var res = ev.WaitOne(TimeSpan.FromSeconds(10)); 45 | 46 | Assert.True(res); 47 | Assert.NotNull(actual); 48 | 49 | Assert.True(actual.Equals(person)); 50 | } 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Sources/Core.IntegrationTest/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Sources/Core.IntegrationTest/contract.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tutorial; 3 | 4 | option csharp_namespace = "Google.Protobuf.Examples.AddressBook"; 5 | 6 | message Person { 7 | string name = 1; 8 | int32 id = 2; // Unique ID number for this person. 9 | string email = 3; 10 | 11 | enum PhoneType { 12 | MOBILE = 0; 13 | HOME = 1; 14 | WORK = 2; 15 | } 16 | 17 | message PhoneNumber { 18 | string number = 1; 19 | PhoneType type = 2; 20 | } 21 | 22 | repeated PhoneNumber phones = 4; 23 | } -------------------------------------------------------------------------------- /Sources/Core.IntegrationTest/libzmq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parshim/MessageBus/0f7bbc3f7a0688555743f8983d224bb9553ae270/Sources/Core.IntegrationTest/libzmq.dll -------------------------------------------------------------------------------- /Sources/Core.IntegrationTest/protoc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parshim/MessageBus/0f7bbc3f7a0688555743f8983d224bb9553ae270/Sources/Core.IntegrationTest/protoc.exe -------------------------------------------------------------------------------- /Sources/Core.Protobuf/ConfiguratorExtensions.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core.API; 2 | 3 | namespace MessageBus.Core.Protobuf 4 | { 5 | public static class ConfiguratorExtensions 6 | { 7 | public static IPublisherConfigurator UseProtobufSerializer(this IPublisherConfigurator configurator) 8 | { 9 | return configurator.UseCustomSerializer(new ProtobufSerializer()); 10 | } 11 | 12 | public static ISubscriberConfigurator AddProtobufSerializer(this ISubscriberConfigurator configurator) 13 | { 14 | return configurator.AddCustomSerializer(new ProtobufSerializer()); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Sources/Core.Protobuf/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Core.Protobuf")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Core.Protobuf")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("1db77659-2a64-492b-8109-d52d7c7be3d8")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Sources/Core.Protobuf/ProtobufSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Google.Protobuf; 4 | using MessageBus.Core.API; 5 | 6 | namespace MessageBus.Core.Protobuf 7 | { 8 | public class ProtobufSerializer : ISerializer 9 | { 10 | public byte[] Serialize(RawBusMessage data) 11 | { 12 | IMessage message = (IMessage)data.Data; 13 | 14 | using (MemoryStream stream = new MemoryStream()) 15 | { 16 | message.WriteTo(stream); 17 | 18 | return stream.ToArray(); 19 | } 20 | } 21 | 22 | public object Deserialize(Type dataType, byte[] body) 23 | { 24 | IMessage message = (IMessage) Activator.CreateInstance(dataType); 25 | 26 | message.MergeFrom(body); 27 | 28 | return message; 29 | } 30 | 31 | public string ContentType { get; } = "application/protobuf"; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Sources/Core.Protobuf/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Sources/Core.Proxy.IntegrationTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Core.Proxy.IntegrationTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Core.Proxy.IntegrationTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8ce0d7f0-adfe-45e5-9b0c-1780054b093f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Sources/Core.Proxy.IntegrationTests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Sources/Core.Proxy.IntegrationTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Sources/Core.Proxy/ChannelFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Castle.DynamicProxy; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core.Proxy 6 | { 7 | public class ChannelFactory : IChannelFactory where T : class 8 | { 9 | private readonly ProxyGenerator _generator = new ProxyGenerator(); 10 | private readonly IMessageFactory _messageFactory; 11 | 12 | private readonly IPublisher _publisher; 13 | 14 | public ChannelFactory(IBus bus, Action configurator = null) 15 | { 16 | string ns = typeof(T).GetMessageNamespace(); 17 | 18 | _messageFactory = new MessageFactory(ns); 19 | 20 | _publisher = bus.CreatePublisher(configurator); 21 | } 22 | 23 | public T CreateChannel(params BusHeader[] headers) 24 | { 25 | return CreateChannel(new DefaultHeadersProvider(headers)); 26 | } 27 | 28 | public T CreateChannel(IHeadersProvider headersProvider) 29 | { 30 | return _generator.CreateInterfaceProxyWithoutTarget(new PublishInterceptor(_messageFactory, _publisher, headersProvider)); 31 | } 32 | 33 | public void Dispose() 34 | { 35 | _publisher.Dispose(); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Sources/Core.Proxy/ContractHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.ServiceModel; 4 | 5 | namespace MessageBus.Core.Proxy 6 | { 7 | internal static class ContractHelper 8 | { 9 | public static string GetMessageName(this MethodInfo info) 10 | { 11 | OperationContractAttribute attribute = info.GetCustomAttribute(); 12 | 13 | if (attribute == null || string.IsNullOrEmpty(attribute.Name)) 14 | { 15 | return info.Name; 16 | } 17 | 18 | return attribute.Name; 19 | } 20 | 21 | public static string GetMessageNamespace(this Type type) 22 | { 23 | ServiceContractAttribute attribute = type.GetCustomAttribute(); 24 | 25 | string name; 26 | 27 | if (attribute == null || string.IsNullOrEmpty(attribute.Name)) 28 | { 29 | // Support generic types 30 | name = type.ToString(); 31 | if (name.IndexOf(type.Namespace ?? string.Empty, 0, StringComparison.Ordinal) == 0) 32 | { 33 | name = name.Substring((type.Namespace?.Length ?? -1) + 1); 34 | } 35 | } 36 | else 37 | { 38 | name = attribute.Name; 39 | } 40 | 41 | string ns = type.Namespace; 42 | 43 | return ns + "." + name; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Sources/Core.Proxy/DefaultHeadersProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core.Proxy 5 | { 6 | public class DefaultHeadersProvider : IHeadersProvider 7 | { 8 | private readonly BusHeader[] _headers; 9 | 10 | public DefaultHeadersProvider(BusHeader[] headers) 11 | { 12 | _headers = headers; 13 | } 14 | 15 | public IEnumerable GetMessageHeaders() 16 | { 17 | return _headers; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Sources/Core.Proxy/IChannelFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core.Proxy 5 | { 6 | public interface IChannelFactory : IDisposable where T : class 7 | { 8 | T CreateChannel(params BusHeader[] headers); 9 | 10 | T CreateChannel(IHeadersProvider headersProvider); 11 | } 12 | } -------------------------------------------------------------------------------- /Sources/Core.Proxy/IHeadersProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core.Proxy 5 | { 6 | public interface IHeadersProvider 7 | { 8 | IEnumerable GetMessageHeaders(); 9 | } 10 | } -------------------------------------------------------------------------------- /Sources/Core.Proxy/IMessageFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace MessageBus.Core.Proxy 5 | { 6 | public interface IMessageFactory 7 | { 8 | object CreateMessage(MethodInfo methodInfo, object[] values); 9 | 10 | Type GetMessageType(MethodInfo methodInfo); 11 | 12 | FieldInfo GetMessageFieldInfo(MethodInfo methodInfo, string fieldName); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Sources/Core.Proxy/ISubscriptionFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core.Proxy 5 | { 6 | public interface ISubscriptionFactory where T : class 7 | { 8 | ISubscriptionSelector Subscribe(Action configurator = null); 9 | } 10 | } -------------------------------------------------------------------------------- /Sources/Core.Proxy/ISubscriptionSelector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using MessageBus.Core.API; 5 | 6 | namespace MessageBus.Core.Proxy 7 | { 8 | public interface ISubscriptionSelector : IDisposable 9 | { 10 | void Subscribe(Expression>> methodSelector, Action notificationCallback, bool hierarchy = false, params BusHeader[] filterHeaders); 11 | 12 | void Subscribe(Expression> methodSelector, Action notificationCallback, bool hierarchy = false, params BusHeader[] filterHeaders); 13 | 14 | void Subscribe(Expression>> methodSelector, Action> notificationCallback, bool hierarchy = false, params BusHeader[] filterHeaders); 15 | 16 | void Subscribe(Expression> methodSelector, Action> notificationCallback, bool hierarchy = false, params BusHeader[] filterHeaders); 17 | } 18 | } -------------------------------------------------------------------------------- /Sources/Core.Proxy/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Core.Proxy")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Core.Proxy")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3dae6b08-8128-4bd6-8200-aa6d94be429f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Sources/Core.Proxy/PublishInterceptor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Castle.DynamicProxy; 3 | 4 | using MessageBus.Core.API; 5 | 6 | namespace MessageBus.Core.Proxy 7 | { 8 | public class PublishInterceptor : IInterceptor 9 | { 10 | private readonly IMessageFactory _messageFactory; 11 | 12 | private readonly IPublisher _publisher; 13 | 14 | private readonly IHeadersProvider _headersProvider; 15 | 16 | public PublishInterceptor(IMessageFactory messageFactory, IPublisher publisher, IHeadersProvider headersProvider) 17 | { 18 | _messageFactory = messageFactory; 19 | _publisher = publisher; 20 | _headersProvider = headersProvider; 21 | } 22 | 23 | public void Intercept(IInvocation invocation) 24 | { 25 | object data = _messageFactory.CreateMessage(invocation.Method, invocation.Arguments); 26 | 27 | RawBusMessage message = new RawBusMessage 28 | { 29 | Data = data, 30 | }; 31 | 32 | IEnumerable headers = _headersProvider.GetMessageHeaders(); 33 | 34 | foreach (BusHeader header in headers) 35 | { 36 | message.Headers.Add(header); 37 | } 38 | 39 | _publisher.Send(message); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Sources/Core.Proxy/SubscriptionFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core.Proxy 5 | { 6 | public class SubscriptionFactory : ISubscriptionFactory where T : class 7 | { 8 | private readonly IBus _bus; 9 | private readonly IMessageFactory _messageFactory; 10 | 11 | public SubscriptionFactory(IBus bus) 12 | { 13 | _bus = bus; 14 | 15 | string ns = typeof(T).GetMessageNamespace(); 16 | 17 | _messageFactory = new MessageFactory(ns); 18 | } 19 | 20 | public ISubscriptionSelector Subscribe(Action configurator) 21 | { 22 | ISubscriber subscriber = _bus.CreateSubscriber(configurator); 23 | 24 | subscriber.Open(); 25 | 26 | return new SubscriptionSelector(subscriber, _messageFactory); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Sources/Core.Proxy/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sources/Core.Proxy/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sources/Core.STandard/API/BusHeaderBase.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | public abstract class BusHeaderBase 4 | { 5 | /// 6 | /// Header name 7 | /// 8 | public string Name { get; set; } 9 | 10 | public abstract object GetValue(); 11 | } 12 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/DataContractKey.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | public class DataContractKey 4 | { 5 | private readonly string _name; 6 | private readonly string _namespace; 7 | 8 | public static readonly DataContractKey BinaryBlob = new DataContractKey("base64Binary", "http://schemas.microsoft.com/2003/10/Serialization/"); 9 | public static readonly DataContractKey Void = new DataContractKey("", ""); 10 | 11 | public DataContractKey(string name, string ns) 12 | { 13 | _name = name; 14 | _namespace = ns; 15 | } 16 | 17 | public string Name 18 | { 19 | get { return _name; } 20 | } 21 | 22 | public string Ns 23 | { 24 | get { return _namespace; } 25 | } 26 | 27 | public bool Equals(DataContractKey other) 28 | { 29 | return string.Equals(_name, other._name) && string.Equals(_namespace, other._namespace); 30 | } 31 | 32 | public override bool Equals(object obj) 33 | { 34 | if (ReferenceEquals(null, obj)) return false; 35 | if (ReferenceEquals(this, obj)) return true; 36 | if (obj.GetType() != this.GetType()) return false; 37 | return Equals((DataContractKey) obj); 38 | } 39 | 40 | public override int GetHashCode() 41 | { 42 | unchecked 43 | { 44 | return ((_name != null ? _name.GetHashCode() : 0)*397) ^ (_namespace != null ? _namespace.GetHashCode() : 0); 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/HeaderFilterAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)] 6 | public class HeaderFilterAttribute : Attribute 7 | { 8 | public HeaderFilterAttribute(string name, string value) 9 | { 10 | Name = name; 11 | Value = value; 12 | } 13 | 14 | /// 15 | /// Header name to filter on 16 | /// 17 | public string Name { get; private set; } 18 | 19 | /// 20 | /// Acceptable header value 21 | /// 22 | public string Value { get; private set; } 23 | } 24 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/IBlockWatcher.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | /// 4 | /// Connection block whatcher 5 | /// 6 | public interface IBlockWatcher 7 | { 8 | /// 9 | /// Notifies upon connection blocking. Messages cannont be published via blocked connections 10 | /// 11 | /// Block reason 12 | void ConnectionBlocked(string reason); 13 | 14 | /// 15 | /// Notifies upon connection unblocking. 16 | /// 17 | void ConnectionUnblocked(); 18 | } 19 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/IConfirmPublisher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public interface IConfirmPublisher : IPublisher 6 | { 7 | /// 8 | /// Waits for confirms of all messages published till method call 9 | /// 10 | /// 11 | /// 12 | bool WaitForConfirms(TimeSpan timeOut); 13 | } 14 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/IErrorSubscriber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | /// 6 | /// Logger provider for subsriber exceptional cases 7 | /// 8 | public interface IErrorSubscriber 9 | { 10 | /// 11 | /// General unhendled exception 12 | /// 13 | /// 14 | void UnhandledException(Exception exception); 15 | 16 | /// 17 | /// Message serialization failed 18 | /// 19 | /// 20 | /// 21 | void MessageDeserializeException(RawBusMessage busMessage, Exception exception); 22 | 23 | /// 24 | /// Message handler throws exception 25 | /// 26 | /// 27 | /// 28 | void MessageDispatchException(RawBusMessage busMessage, Exception exception); 29 | 30 | /// 31 | /// Message filtered 32 | /// 33 | /// 34 | void MessageFilteredOut(RawBusMessage busMessage); 35 | 36 | /// 37 | /// Unregistered message arrived 38 | /// 39 | /// 40 | void UnregisteredMessageArrived(RawBusMessage busMessage); 41 | } 42 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/IExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | /// 6 | /// Defines which exception should reject messages and which should requeue 7 | /// 8 | public interface IExceptionFilter 9 | { 10 | bool Filter(Exception exception, RawBusMessage message, bool redelivered, ulong deliveryTag); 11 | } 12 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/IPublishingErrorHandler.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | /// 4 | /// 5 | /// 6 | public interface IPublishingErrorHandler 7 | { 8 | /// 9 | /// 10 | /// 11 | /// 12 | /// 13 | /// 14 | void DeliveryFailed(int errorCode, string text, RawBusMessage message); 15 | } 16 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/IReceiver.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | /// 6 | /// Receive messages from the bus on demand, without handling message pump 7 | /// 8 | public interface IReceiver : ISubscription 9 | { 10 | /// 11 | /// Subscribe for message type. 12 | /// 13 | /// Message data contract type. 14 | /// Look for derived types and automaticaly register them for the same callback. 15 | /// Subscribe to message which sent only with specified headers. 16 | /// True if sucessfuly subscribed, otherwise false. 17 | /// 18 | bool Subscribe(bool hierarchy = false, IEnumerable filter = null); 19 | 20 | /// 21 | /// Receives next message in queue 22 | /// 23 | /// Message data contract type. 24 | /// Null if there is no messages queued 25 | TData Receive(); 26 | 27 | /// 28 | /// Receives next message in queue 29 | /// 30 | /// Message data contract type. 31 | /// Null if there is no messages queued 32 | BusMessage ReceiveBusMessage(); 33 | } 34 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/IRpcPublisherConfigurator.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | public interface IRpcPublisherConfigurator : IPublisherConfigurator 4 | { 5 | /// 6 | /// Disable fast reply mechanism introduced in RabbitMQ. Publisher will create dedicated auto-delete queue to consume reply messages. 7 | /// If replyExchange parameter is different from default exchange (empty string) use IPublisherConfigurator.SetReplyTo method to specify routing key to bind queue to reply exchange. 8 | /// 9 | /// 10 | IRpcPublisherConfigurator DisableFastReply(); 11 | 12 | /// 13 | /// Set exchange name for reply messages. It can be used if fast reply is disabled and reply queue should be bounded to specified exchange. 14 | /// By default reply queue will get messages from default exchange. 15 | /// 16 | /// 17 | /// 18 | IRpcPublisherConfigurator SetReplyExchange(string replyExchange); 19 | 20 | /// 21 | /// Specify consumer tag. 22 | /// 23 | IRpcPublisherConfigurator SetConsumerTag(string consumerTag); 24 | } 25 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/ISerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public interface ISerializer 6 | { 7 | string ContentType { get; } 8 | 9 | byte[] Serialize(RawBusMessage data); 10 | 11 | object Deserialize(Type dataType, byte[] body); 12 | } 13 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/ISubscription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | /// 6 | /// Subscription interface provides basic interface to control receive messages 7 | /// 8 | public interface ISubscription : IDisposable 9 | { 10 | /// 11 | /// Start process subscribed message types. 12 | /// 13 | void Open(); 14 | 15 | /// 16 | /// Stop process messages 17 | /// 18 | void Close(); 19 | } 20 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/ITrace.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | /// 4 | /// Trace all incoming and outgoing messages 5 | /// 6 | public interface ITrace 7 | { 8 | /// 9 | /// Message arrived 10 | /// 11 | /// 12 | /// 13 | /// 14 | void MessageArrived(string busId, RawBusMessage busMessage, string consumerTag); 15 | 16 | /// 17 | /// Message sent 18 | /// 19 | /// 20 | /// 21 | void MessageSent(string busId, RawBusMessage busMessage); 22 | } 23 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/ITransactionalPublisher.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | public interface ITransactionalPublisher : IPublisher 4 | { 5 | 6 | /// 7 | /// Commits message delivery 8 | /// 9 | void Commit(); 10 | 11 | /// 12 | /// Rallback message delivery 13 | /// 14 | void Rollback(); 15 | } 16 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/MessageSubscribtionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 6 | public class MessageSubscriptionAttribute : Attribute 7 | { 8 | /// 9 | /// Looking for derived types and automatically register them for the same callback 10 | /// 11 | public bool RegisterHierarchy { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/NoIncomingConnectionAcceptedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public class NoIncomingConnectionAcceptedException : Exception 6 | { 7 | public NoIncomingConnectionAcceptedException() : base("Unable to open subscriber cause any input connection was accepted") 8 | { 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Sources/Core.STandard/API/RejectMessageException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public class RejectMessageException : Exception 6 | { 7 | public object ReplyData { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Sources/Core.STandard/API/RpcCallException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public enum RpcFailureReason 6 | { 7 | TimeOut, 8 | HandlerError, 9 | Reject, 10 | SerializationError, 11 | NotRouted 12 | } 13 | 14 | public class RpcCallException : Exception 15 | { 16 | public RpcCallException(RpcFailureReason reason) 17 | { 18 | Reason = reason; 19 | } 20 | 21 | public RpcCallException(RpcFailureReason reason, object replyData) 22 | { 23 | Reason = reason; 24 | ReplyData = replyData; 25 | } 26 | 27 | public RpcCallException(RpcFailureReason reason, string message) :base(message) 28 | { 29 | Reason = reason; 30 | } 31 | 32 | public RpcCallException(RpcFailureReason reason, Exception innerException):base("", innerException) 33 | { 34 | Reason = reason; 35 | } 36 | 37 | public RpcFailureReason Reason { get; private set; } 38 | 39 | public object ReplyData { get; private set; } 40 | } 41 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/SubscribtionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] 6 | public class SubscribtionAttribute : Attribute 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Sources/Core.STandard/API/SubscribtionClosedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public class SubscribtionClosedException : Exception 6 | { 7 | public SubscribtionClosedException() 8 | : base("Unable to subscribe to message types after subscriber start to process messages") 9 | { 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/API/SubscriptionClosedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | /// 6 | /// 7 | /// 8 | public class SubscriptionClosedException : Exception 9 | { 10 | public SubscriptionClosedException() 11 | : base("Unable to subscribe to message types after subscriber start to process messages") 12 | { 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/AsyncActionHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public class AsyncActionHandler : ICallHandler 8 | { 9 | private readonly Func _action; 10 | 11 | public AsyncActionHandler(Func action) 12 | { 13 | _action = action; 14 | } 15 | 16 | public async Task Dispatch(RawBusMessage message) 17 | { 18 | await _action((TData)message.Data); 19 | 20 | return new RawBusMessage(); 21 | } 22 | } 23 | 24 | public class ActionHandler : ICallHandler 25 | { 26 | private readonly Action _action; 27 | 28 | public ActionHandler(Action action) 29 | { 30 | _action = action; 31 | } 32 | 33 | public Task Dispatch(RawBusMessage message) 34 | { 35 | _action((TData)message.Data); 36 | 37 | return Task.FromResult(new RawBusMessage()); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/Core.STandard/AsyncBusMessageCallHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public class AsyncBusMessageCallHandler : ICallHandler 8 | { 9 | private readonly Func, Task> _action; 10 | 11 | public AsyncBusMessageCallHandler(Func, Task> action) 12 | { 13 | _action = action; 14 | } 15 | 16 | public async Task Dispatch(RawBusMessage message) 17 | { 18 | BusMessage busMessage = new BusMessage 19 | { 20 | BusId = message.BusId, 21 | Sent = message.Sent, 22 | Data = (TData)message.Data 23 | }; 24 | 25 | foreach (var header in message.Headers) 26 | { 27 | busMessage.Headers.Add(header); 28 | } 29 | 30 | await _action(busMessage); 31 | 32 | return new RawBusMessage(); 33 | } 34 | } 35 | 36 | public class BusMessageCallHandler : ICallHandler 37 | { 38 | private readonly Action> _action; 39 | 40 | public BusMessageCallHandler(Action> action) 41 | { 42 | _action = action; 43 | } 44 | 45 | public Task Dispatch(RawBusMessage message) 46 | { 47 | BusMessage busMessage = new BusMessage 48 | { 49 | BusId = message.BusId, 50 | Sent = message.Sent, 51 | Data = (TData)message.Data 52 | }; 53 | 54 | foreach (var header in message.Headers) 55 | { 56 | busMessage.Headers.Add(header); 57 | } 58 | 59 | _action(busMessage); 60 | 61 | return Task.FromResult(new RawBusMessage()); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/AsyncFunctionHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public class AsyncFunctionHandler : ICallHandler 8 | { 9 | private readonly Func> _handler; 10 | 11 | public AsyncFunctionHandler(Func> handler) 12 | { 13 | _handler = handler; 14 | } 15 | 16 | public async Task Dispatch(RawBusMessage message) 17 | { 18 | TOut result = await _handler((TIn) message.Data); 19 | 20 | return new RawBusMessage {Data = result}; 21 | } 22 | } 23 | 24 | public class FunctionHandler : ICallHandler 25 | { 26 | private readonly Func _handler; 27 | 28 | public FunctionHandler(Func handler) 29 | { 30 | _handler = handler; 31 | } 32 | 33 | public Task Dispatch(RawBusMessage message) 34 | { 35 | TOut result = _handler((TIn) message.Data); 36 | 37 | return Task.FromResult(new RawBusMessage {Data = result}); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/AsyncRawHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public class AsyncRawHandler : ICallHandler 8 | { 9 | private readonly Func _action; 10 | 11 | public AsyncRawHandler(Func action) 12 | { 13 | _action = action; 14 | } 15 | 16 | public async Task Dispatch(RawBusMessage message) 17 | { 18 | await _action(message); 19 | 20 | return new RawBusMessage(); 21 | } 22 | } 23 | public class RawHandler : ICallHandler 24 | { 25 | private readonly Action _action; 26 | 27 | public RawHandler(Action action) 28 | { 29 | _action = action; 30 | } 31 | 32 | public Task Dispatch(RawBusMessage message) 33 | { 34 | _action(message); 35 | 36 | return Task.FromResult(new RawBusMessage()); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/ConfirmPublisher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | using RabbitMQ.Client; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public class ConfirmPublisher : Publisher, IConfirmPublisher 8 | { 9 | public ConfirmPublisher(IModel model, string busId, PublisherConfigurator configuration, IMessageHelper messageHelper, ISendHelper sendHelper) 10 | : base(model, busId, configuration, messageHelper, sendHelper) 11 | { 12 | _model.ConfirmSelect(); 13 | } 14 | 15 | public bool WaitForConfirms(TimeSpan timeOut) 16 | { 17 | return _model.WaitForConfirms(timeOut); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/Core.Standard.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.1 5 | MessageBus.Core 6 | MessageBus.Core 7 | 8 | 9 | 10 | ..\..\Binaries\Release\ 11 | 12 | 13 | 14 | ..\..\Binaries\Debug\ 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Sources/Core.STandard/ICallHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public interface ICallHandler 7 | { 8 | Task Dispatch(RawBusMessage message); 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/IMessageConsumer.cs: -------------------------------------------------------------------------------- 1 | using RabbitMQ.Client; 2 | 3 | namespace MessageBus.Core 4 | { 5 | public interface IMessageConsumer : IBasicConsumer, IMessageRegistry 6 | { 7 | 8 | } 9 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/IMessageHelper.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core; 2 | using MessageBus.Core.API; 3 | using RabbitMQ.Client; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public interface IMessageHelper 8 | { 9 | SerializedBusMessage ConstructMessage(DataContractKey dataContractKey, IBasicProperties properties, byte[] data); 10 | 11 | RawBusMessage ConstructMessage(DataContractKey dataContractKey, IBasicProperties properties, object data); 12 | 13 | BusMessage ConstructMessage(DataContractKey dataContractKey, IBasicProperties properties, T data); 14 | } 15 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/IMessageRegistry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public interface IMessageRegistry 7 | { 8 | bool Register(Type type, MessageFilterInfo filterInfo, ICallHandler handler); 9 | } 10 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/IRpcConsumer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using MessageBus.Core.API; 4 | using RabbitMQ.Client; 5 | 6 | namespace MessageBus.Core 7 | { 8 | 9 | public interface IRpcConsumer : IBasicConsumer 10 | { 11 | WaitHandle RegisterCallback(string correlationId, Type replyType, Action callback); 12 | 13 | void RemoveCallback(string correlationId); 14 | 15 | void HandleBasicReturn(string correlationId, int replyCode, string replyText); 16 | } 17 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/ISendHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | using RabbitMQ.Client; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public interface ISendHelper 8 | { 9 | void Send(SerializedBusMessage message, SendParams sendParams); 10 | 11 | void Send(RawBusMessage message, ISerializer serializer, SendParams sendParams); 12 | 13 | Type GetDataType(DataContractKey dataContractKey); 14 | } 15 | 16 | public class SendParams 17 | { 18 | public IModel Model { get; set; } 19 | 20 | public string RoutingKey { get; set; } 21 | 22 | public string Exchange { get; set; } 23 | 24 | public string CorrelationId { get; set; } 25 | 26 | public string BusId { get; set; } 27 | 28 | public bool MandatoryDelivery { get; set; } 29 | 30 | public bool PersistentDelivery { get; set; } 31 | 32 | public string ReplyTo { get; set; } 33 | 34 | public byte? Priority { get; set; } 35 | } 36 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/ISubscriptionHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public interface ISubscriptionHelper 8 | { 9 | bool Subscribe(Type dataType, ICallHandler handler, bool hierarchy, IEnumerable filter); 10 | bool Subscribe(Type dataType, ICallHandler handler, IEnumerable filter); 11 | bool SubscribeHierarchy(Type baseType, ICallHandler handler, IEnumerable filter); 12 | void RegisterSubscription(object instance); 13 | } 14 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/JsonSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | using MessageBus.Core.API; 5 | using Newtonsoft.Json; 6 | 7 | namespace MessageBus.Core 8 | { 9 | public class JsonSerializer : ISerializer 10 | { 11 | private readonly Encoding _encoding = Encoding.UTF8; 12 | 13 | private readonly JsonSerializerSettings _settings; 14 | 15 | public JsonSerializer(JsonSerializerSettings settings) 16 | { 17 | _settings = settings; 18 | } 19 | 20 | public string ContentType => "application/json"; 21 | 22 | public byte[] Serialize(RawBusMessage busMessage) 23 | { 24 | object data = busMessage.Data; 25 | 26 | string body = JsonConvert.SerializeObject(data, _settings); 27 | 28 | return _encoding.GetBytes(body); 29 | } 30 | 31 | public object Deserialize(Type dataType, byte[] body) 32 | { 33 | string sBody = _encoding.GetString(body); 34 | 35 | return JsonConvert.DeserializeObject(sBody, dataType, _settings); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/MessageFilterInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class MessageFilterInfo 7 | { 8 | private readonly DataContractKey _contractKey; 9 | private readonly List _filterHeaders; 10 | 11 | public MessageFilterInfo(DataContractKey contractKey, IEnumerable filterHeaders) 12 | { 13 | _contractKey = contractKey; 14 | _filterHeaders = new List(filterHeaders); 15 | } 16 | 17 | public DataContractKey ContractKey 18 | { 19 | get { return _contractKey; } 20 | } 21 | 22 | public IEnumerable FilterHeaders 23 | { 24 | get { return _filterHeaders; } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/MessageMonitor.cs: -------------------------------------------------------------------------------- 1 | using RabbitMQ.Client; 2 | 3 | namespace MessageBus.Core 4 | { 5 | public class MessageMonitor : SubscriberBase 6 | { 7 | public MessageMonitor(IModel model, string queue, IBasicConsumer consumer, SubscriberConfigurator configurator) : base(model, queue, consumer, configurator) 8 | { 9 | } 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/MessagingConstants.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core 2 | { 3 | public class MessagingConstants 4 | { 5 | public class HeaderNames 6 | { 7 | public const string BusId = "BusId"; 8 | public const string SentTime = "SentTime"; 9 | public const string Name = "Name"; 10 | public const string NameSpace = "Namespace"; 11 | } 12 | public class Actor 13 | { 14 | public const string User = "User"; 15 | public const string Bus = "Bus"; 16 | } 17 | 18 | public class MessageAction 19 | { 20 | public const string Regular = "Message"; 21 | } 22 | public class Namespace 23 | { 24 | public const string MessageBus = "www.messagebus.org"; 25 | } 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/Core.STandard/NullBlockWatcher.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core.API; 2 | 3 | namespace MessageBus.Core 4 | { 5 | public class NullBlockWatcher : IBlockWatcher 6 | { 7 | public void ConnectionBlocked(string reason) 8 | { 9 | 10 | } 11 | 12 | public void ConnectionUnblocked() 13 | { 14 | 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/NullCallHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | internal class NullCallHandler : ICallHandler 7 | { 8 | public Task Dispatch(RawBusMessage message) 9 | { 10 | return Task.FromResult(new RawBusMessage()); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/NullErrorSubscriber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class NullErrorSubscriber : IErrorSubscriber 7 | { 8 | public void UnhandledException(Exception exception) 9 | { 10 | 11 | } 12 | 13 | public void MessageDeserializeException(RawBusMessage busMessage, Exception exception) 14 | { 15 | } 16 | 17 | public void MessageDispatchException(RawBusMessage busMessage, Exception exception) 18 | { 19 | } 20 | 21 | public void MessageFilteredOut(RawBusMessage busMessage) 22 | { 23 | } 24 | 25 | public void UnregisteredMessageArrived(RawBusMessage busMessage) 26 | { 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/NullExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | internal class NullExceptionFilter : IExceptionFilter 7 | { 8 | public bool Filter(Exception exception, RawBusMessage message, bool redelivered, ulong deliveryTag) 9 | { 10 | return true; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/NullPublishingErrorHandler.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core.API; 2 | 3 | namespace MessageBus.Core 4 | { 5 | internal class NullPublishingErrorHandler : IPublishingErrorHandler 6 | { 7 | public void DeliveryFailed(int errorCode, string text, RawBusMessage message) 8 | { 9 | 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/NullTrace.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core.API; 2 | 3 | namespace MessageBus.Core 4 | { 5 | public class NullTrace : ITrace 6 | { 7 | public void MessageArrived(string busId, RawBusMessage busMessage, string consumerTag) 8 | { 9 | } 10 | 11 | public void MessageSent(string busId, RawBusMessage busMessage) 12 | { 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/RpcPublisherConfigurator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class RpcPublisherConfigurator : PublisherConfigurator, IRpcPublisherConfigurator 7 | { 8 | private bool _useFastReply; 9 | private string _replyExchange; 10 | private string _consumerTag = ""; 11 | 12 | public RpcPublisherConfigurator(string exchange, bool useFastReply, string replyExchange, IPublishingErrorHandler errorHandler, ITrace trace, Func blocked) 13 | : base(exchange, errorHandler, trace, blocked) 14 | { 15 | _useFastReply = useFastReply; 16 | _replyExchange = replyExchange; 17 | } 18 | 19 | public bool UseFastReply 20 | { 21 | get { return _useFastReply; } 22 | } 23 | 24 | public string ReplyExchange 25 | { 26 | get { return _replyExchange; } 27 | } 28 | public string ConsumerTag 29 | { 30 | get { return _consumerTag; } 31 | } 32 | 33 | public IRpcPublisherConfigurator DisableFastReply() 34 | { 35 | _useFastReply = false; 36 | 37 | return this; 38 | } 39 | 40 | 41 | public IRpcPublisherConfigurator SetReplyExchange(string replyExchange) 42 | { 43 | _replyExchange = replyExchange; 44 | 45 | return this; 46 | } 47 | 48 | public IRpcPublisherConfigurator SetConsumerTag(string consumerTag) 49 | { 50 | _consumerTag = consumerTag; 51 | 52 | return this; 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/SubscriberBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using MessageBus.Core.API; 4 | using RabbitMQ.Client; 5 | 6 | namespace MessageBus.Core 7 | { 8 | public class SubscriberBase : ISubscription 9 | { 10 | private readonly IModel _model; 11 | private readonly string _queue; 12 | private readonly IBasicConsumer _consumer; 13 | private readonly SubscriberConfigurator _configurator; 14 | 15 | private string _consumerTag; 16 | 17 | public SubscriberBase(IModel model, string queue, IBasicConsumer consumer, SubscriberConfigurator configurator) 18 | { 19 | _model = model; 20 | 21 | _queue = queue; 22 | 23 | _consumer = consumer; 24 | _configurator = configurator; 25 | } 26 | 27 | ~SubscriberBase() 28 | { 29 | Dispose(true); 30 | } 31 | 32 | private void Dispose(bool finializing) 33 | { 34 | if (finializing && _configurator.Blocked) return; 35 | 36 | _model.Abort(); 37 | } 38 | 39 | public void Dispose() 40 | { 41 | Dispose(false); 42 | 43 | GC.SuppressFinalize(this); 44 | } 45 | 46 | public void Open() 47 | { 48 | if (_configurator.Prefetch > 0) 49 | { 50 | _model.BasicQos(0, _configurator.Prefetch, false); 51 | } 52 | 53 | _consumerTag = _model.BasicConsume(_queue, !_configurator.TransactionalDelivery, _configurator.ConsumerTag, !_configurator.ReceiveSelfPublish, false, new Dictionary(), _consumer); 54 | } 55 | 56 | public void Close() 57 | { 58 | _model.BasicCancel(_consumerTag); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/Subscription.cs: -------------------------------------------------------------------------------- 1 | using RabbitMQ.Client; 2 | 3 | namespace MessageBus.Core 4 | { 5 | public class Subscription : SubscriberBase 6 | { 7 | public Subscription(IModel model, string queue, IMessageConsumer consumer, object instance, SubscriberConfigurator configurator, ISubscriptionHelper helper) 8 | : base(model, queue, consumer, configurator) 9 | { 10 | helper.RegisterSubscription(instance); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/SubscriptionInfo.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core 2 | { 3 | public class SubscriptionInfo 4 | { 5 | public ICallHandler Handler { get; set; } 6 | 7 | public MessageFilterInfo FilterInfo { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/SyncTaskScheduler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | 5 | namespace MessageBus.Core 6 | { 7 | /// 8 | /// Default task scheduler which executes all tasks in current thread 9 | /// 10 | public class SyncTaskScheduler : TaskScheduler 11 | { 12 | protected override void QueueTask(Task task) 13 | { 14 | TryExecuteTask(task); 15 | } 16 | 17 | protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) 18 | { 19 | return TryExecuteTask(task); 20 | } 21 | 22 | protected override IEnumerable GetScheduledTasks() 23 | { 24 | return Enumerable.Empty(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Sources/Core.STandard/TransactionalPublisher.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core.API; 2 | using RabbitMQ.Client; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class TransactionalPublisher : Publisher, ITransactionalPublisher 7 | { 8 | public TransactionalPublisher(IModel model, string busId, PublisherConfigurator configuration, IMessageHelper messageHelper, ISendHelper sendHelper) 9 | : base(model, busId, configuration, messageHelper, sendHelper) 10 | { 11 | _model.TxSelect(); 12 | } 13 | 14 | public void Commit() 15 | { 16 | _model.TxCommit(); 17 | } 18 | 19 | public void Rollback() 20 | { 21 | _model.TxRollback(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Sources/Core.SignalR.IntegrationTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Core.SignalR.IntegrationTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Core.SignalR.IntegrationTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("495ed1bb-e581-4a9a-a860-2c71acef6eeb")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Sources/Core.SignalR.IntegrationTests/SignalRBackplaneTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.SignalR; 2 | using NUnit.Framework; 3 | 4 | namespace Core.SignalR.IntegrationTests 5 | { 6 | [TestFixture] 7 | public class SignalRBackplaneTest 8 | { 9 | [Test] 10 | public void ConectToSignalR_Send_ReceiveMessage() 11 | { 12 | GlobalHost.DependencyResolver.UseRabbit(new RabbitScaleoutConfiguration 13 | { 14 | ConnectionString = "amqp://localhost" 15 | }); 16 | 17 | GlobalHost.ConnectionManager.GetHubContext().Clients.All.updateData("Hello, World!"); 18 | 19 | GlobalHost.ConnectionManager.GetHubContext().Clients.Group("G").updateData("Hello, World!"); 20 | } 21 | } 22 | 23 | public class TestHub : Hub 24 | { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/Core.SignalR.IntegrationTests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Sources/Core.SignalR.IntegrationTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Sources/Core.SignalR/DependencyResolverExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Microsoft.AspNet.SignalR; 4 | using Microsoft.AspNet.SignalR.Messaging; 5 | 6 | namespace Core.SignalR 7 | { 8 | public static class DependencyResolverExtensions 9 | { 10 | /// 11 | /// Use RabbitMQ as the messaging backplane for scaling out of ASP.NET SignalR applications in a web farm. 12 | /// 13 | /// The dependency resolver 14 | /// The RabbitMQ scale-out configuration options. 15 | /// The dependency resolver. 16 | public static IDependencyResolver UseRabbit(this IDependencyResolver resolver, RabbitScaleoutConfiguration configuration) 17 | { 18 | var bus = new Lazy(() => new RabbitMessageBus(resolver, configuration)); 19 | resolver.Register(typeof(IMessageBus), () => bus.Value); 20 | 21 | return resolver; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/Core.SignalR/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Core.SignalR")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Core.SignalR")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("523aa27d-c91b-4205-9f65-7a693b1ba5c6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Sources/Core.SignalR/RabbitScaleoutConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using MessageBus.Core.API; 3 | using Microsoft.AspNet.SignalR.Messaging; 4 | 5 | namespace Core.SignalR 6 | { 7 | public class RabbitScaleoutConfiguration : ScaleoutConfiguration 8 | { 9 | public string ConnectionString { get; set; } 10 | 11 | public List FilterHeaders { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Sources/Core.SignalR/ScaleoutMessageSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | using Microsoft.AspNet.SignalR.Messaging; 4 | 5 | namespace Core.SignalR 6 | { 7 | public class ScaleoutMessageSerializer : ISerializer 8 | { 9 | public string ContentType { get { return "application/octet-stream"; } } 10 | 11 | public byte[] Serialize(RawBusMessage data) 12 | { 13 | return ((ScaleoutMessage)data.Data).ToBytes(); 14 | } 15 | 16 | public object Deserialize(Type dataType, byte[] body) 17 | { 18 | return ScaleoutMessage.FromBytes(body); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Sources/Core.SignalR/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Sources/Core.SignalR/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sources/Core.UnitTests/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sources/Core.UnitTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Core.UnitTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Core.UnitTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("beaa6209-26af-400c-a5b8-5288ce350f6a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Sources/Core.UnitTests/RabbitMQBusConfigurationTests.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core; 2 | using MessageBus.Core.API; 3 | using NUnit.Framework; 4 | 5 | namespace Core.UnitTests 6 | { 7 | [TestFixture] 8 | public class RabbitMqBusConfigurationTests 9 | { 10 | [Test] 11 | public void RabbitMQBus_SetConnectionName_RabbitMQBusConnectionNameWasSet() 12 | { 13 | var expectedName = "test name"; 14 | using (IBus bus = new RabbitMQBus(c => c.SetConnectionProvidedName(expectedName))) 15 | { 16 | Assert.AreEqual(expectedName, bus.BusConnectionName); 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sources/Core.UnitTests/RabbitMQConnectionStringTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core; 3 | using NUnit.Framework; 4 | 5 | namespace Core.UnitTests 6 | { 7 | [TestFixture] 8 | public class RabbitMQConnectionStringTest 9 | { 10 | [Test] 11 | public void FullUrl_AllValuesExtracted() 12 | { 13 | var cs = new RabbitMQConnectionString(new Uri("amqp://u:p@2.2.2.2:2020/vHost/exch?routingKey=key")); 14 | 15 | Assert.AreEqual("2.2.2.2", cs.Host); 16 | Assert.AreEqual(2020, cs.Port); 17 | Assert.AreEqual("vHost", cs.VirtualHost); 18 | Assert.AreEqual("exch", cs.Endpoint); 19 | Assert.AreEqual("u", cs.Username); 20 | Assert.AreEqual("p", cs.Password); 21 | Assert.AreEqual("key", cs.RoutingKey); 22 | } 23 | 24 | [Test] 25 | public void OnlyHostAndPort_AllValuesExtracted() 26 | { 27 | var cs = new RabbitMQConnectionString(new Uri("amqp://2.2.2.2:2020")); 28 | 29 | Assert.AreEqual("2.2.2.2", cs.Host); 30 | Assert.AreEqual(2020, cs.Port); 31 | Assert.AreEqual("/", cs.VirtualHost); 32 | Assert.AreEqual("", cs.Endpoint); 33 | } 34 | 35 | [Test] 36 | public void OnlyHost_AllValuesExtracted() 37 | { 38 | var cs = new RabbitMQConnectionString(new Uri("amqp://2.2.2.2")); 39 | 40 | Assert.AreEqual("2.2.2.2", cs.Host); 41 | Assert.AreEqual(-1, cs.Port); 42 | Assert.AreEqual("/", cs.VirtualHost); 43 | Assert.AreEqual("", cs.Endpoint); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sources/Core.UnitTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Sources/Core.ZeroMQ/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Core.ZeroMQ")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Core.ZeroMQ")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a45ae886-0b0f-4286-988c-cefef6ed1765")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Sources/Core/API/ICallHandler.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core.API 2 | { 3 | public interface ICallHandler 4 | { 5 | void Dispatch(RawBusMessage message); 6 | } 7 | } -------------------------------------------------------------------------------- /Sources/Core/API/IDispatcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ServiceModel.Channels; 4 | 5 | namespace MessageBus.Core.API 6 | { 7 | internal interface IDispatcher 8 | { 9 | IEnumerable GetApplicableFilters(); 10 | 11 | void Dispatch(Message message); 12 | 13 | RawBusMessage Translate(Message message); 14 | } 15 | 16 | internal interface ICallbackDispatcher : IDispatcher 17 | { 18 | bool Subscribe(Type dataType, ICallHandler handler, bool hierarchy, bool receiveSelfPublish, IEnumerable filter); 19 | bool Subscribe(Type dataType, ICallHandler handler, bool receiveSelfPublish, IEnumerable filter); 20 | bool SubscribeHierarchy(Type baseType, ICallHandler handler, bool receiveSelfPublish, IEnumerable filter); 21 | } 22 | 23 | internal interface ISubscriptionDispatcher : IDispatcher 24 | { 25 | void RegisterSubscribtion(object instance); 26 | } 27 | } -------------------------------------------------------------------------------- /Sources/Core/API/IKnownContractCollector.cs: -------------------------------------------------------------------------------- 1 | using System.Xml; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | internal interface IKnownContractCollector 6 | { 7 | void AddKnownContract(DataContract contract); 8 | void Deserialize(RawBusMessage rawBusMessage, XmlDictionaryReader bodyContent); 9 | } 10 | } -------------------------------------------------------------------------------- /Sources/Core/API/IMessageFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | internal interface IMessageFilter 6 | { 7 | void ApplyFilters(IEnumerable filters); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Sources/Core/API/MessageFilterInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MessageBus.Core.API 4 | { 5 | public class MessageFilterInfo 6 | { 7 | private readonly DataContractKey _contractKey; 8 | private readonly bool _receiveSelfPublish; 9 | private readonly List _filterHeaders; 10 | 11 | public MessageFilterInfo(DataContractKey contractKey, bool receiveSelfPublish, IEnumerable filterHeaders) 12 | { 13 | _contractKey = contractKey; 14 | _receiveSelfPublish = receiveSelfPublish; 15 | _filterHeaders = new List(filterHeaders); 16 | } 17 | 18 | public DataContractKey ContractKey 19 | { 20 | get { return _contractKey; } 21 | } 22 | 23 | public bool ReceiveSelfPublish 24 | { 25 | get { return _receiveSelfPublish; } 26 | } 27 | 28 | public IEnumerable FilterHeaders 29 | { 30 | get { return _filterHeaders; } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Sources/Core/ActionHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class ActionHandler : ICallHandler 7 | { 8 | private readonly Action _action; 9 | 10 | public ActionHandler(Action action) 11 | { 12 | _action = action; 13 | } 14 | 15 | public void Dispatch(RawBusMessage message) 16 | { 17 | _action(message.Data); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sources/Core/BusMessageHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class BusMessageHandler : ICallHandler 7 | { 8 | private readonly Action _action; 9 | 10 | public BusMessageHandler(Action action) 11 | { 12 | _action = action; 13 | } 14 | 15 | public void Dispatch(RawBusMessage message) 16 | { 17 | BusMessage busMessage = new BusMessage 18 | { 19 | BusId = message.BusId, 20 | Sent = message.Sent, 21 | Data = (TData)message.Data 22 | }; 23 | 24 | foreach (BusHeader header in message.Headers) 25 | { 26 | busMessage.Headers.Add(header); 27 | } 28 | 29 | _action(busMessage); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Sources/Core/DataContractKey.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core 2 | { 3 | public class DataContractKey 4 | { 5 | private readonly string _name; 6 | private readonly string _namespace; 7 | 8 | public static readonly DataContractKey BinaryBlob = new DataContractKey("base64Binary", "http://schemas.microsoft.com/2003/10/Serialization/"); 9 | 10 | public DataContractKey(string name, string ns) 11 | { 12 | _name = name; 13 | _namespace = ns; 14 | } 15 | 16 | public string Name 17 | { 18 | get { return _name; } 19 | } 20 | 21 | public string Ns 22 | { 23 | get { return _namespace; } 24 | } 25 | 26 | public bool Equals(DataContractKey other) 27 | { 28 | return string.Equals(_name, other._name) && string.Equals(_namespace, other._namespace); 29 | } 30 | 31 | public override bool Equals(object obj) 32 | { 33 | if (ReferenceEquals(null, obj)) return false; 34 | if (ReferenceEquals(this, obj)) return true; 35 | if (obj.GetType() != this.GetType()) return false; 36 | return Equals((DataContractKey) obj); 37 | } 38 | 39 | public override int GetHashCode() 40 | { 41 | unchecked 42 | { 43 | return ((_name != null ? _name.GetHashCode() : 0)*397) ^ (_namespace != null ? _namespace.GetHashCode() : 0); 44 | } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Sources/Core/FaultMessageProcessor.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel.Channels; 2 | using MessageBus.Binding.RabbitMQ; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | internal class FaultMessageProcessor : IFaultMessageProcessor 8 | { 9 | private readonly IPublishingErrorHandler _errorHandler; 10 | private readonly IKnownContractCollector _collector; 11 | 12 | private readonly RawBusMessageReader _reader = new RawBusMessageReader(); 13 | 14 | public FaultMessageProcessor(IPublishingErrorHandler errorHandler, IKnownContractCollector collector) 15 | { 16 | _errorHandler = errorHandler; 17 | _collector = collector; 18 | } 19 | 20 | public void Process(int code, string text, Message message) 21 | { 22 | RawBusMessage busMessage = _reader.ReadMessage(message, _collector.Deserialize); 23 | 24 | _errorHandler.DeliveryFailed(code, text, busMessage); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Sources/Core/KnownContractCollector.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using System.Runtime.Serialization; 3 | using System.Xml; 4 | using MessageBus.Core.API; 5 | 6 | namespace MessageBus.Core 7 | { 8 | internal class KnownContractCollector : IKnownContractCollector 9 | { 10 | private readonly ConcurrentDictionary _map = new ConcurrentDictionary(); 11 | 12 | public void AddKnownContract(DataContract contract) 13 | { 14 | _map.TryAdd(contract.Key, contract.Serializer); 15 | } 16 | 17 | public void Deserialize(RawBusMessage rawBusMessage, XmlDictionaryReader bodyContent) 18 | { 19 | XmlObjectSerializer serializer; 20 | if (_map.TryGetValue(new DataContractKey(rawBusMessage.Name, rawBusMessage.Namespace), out serializer)) 21 | { 22 | rawBusMessage.Data = serializer.ReadObject(bodyContent); 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Core/MessagePumpSubscriptionBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ServiceModel.Channels; 3 | using System.Threading; 4 | using MessageBus.Core.API; 5 | 6 | namespace MessageBus.Core 7 | { 8 | internal abstract class MessagePumpSubscriptionBase : SubscriptionBase 9 | { 10 | private readonly Thread _receiver; 11 | private bool _receive; 12 | 13 | protected MessagePumpSubscriptionBase(IInputChannel inputChannel, IMessageFilter messageFilter, IDispatcher dispatcher) : base(inputChannel, messageFilter, dispatcher) 14 | { 15 | _receiver = new Thread(MessagePump); 16 | } 17 | 18 | private void MessagePump() 19 | { 20 | while (_receive) 21 | { 22 | Message message; 23 | 24 | if (!_inputChannel.TryReceive(TimeSpan.FromMilliseconds(100), out message)) 25 | { 26 | continue; 27 | } 28 | 29 | using (message) 30 | { 31 | _dispatcher.Dispatch(message); 32 | } 33 | } 34 | } 35 | 36 | public override void Open() 37 | { 38 | if (_stared) return; 39 | 40 | base.Open(); 41 | 42 | _receive = true; 43 | 44 | _receiver.Start(); 45 | } 46 | 47 | public override void Close() 48 | { 49 | _receive = false; 50 | 51 | if (_stared) 52 | { 53 | _receiver.Join(TimeSpan.FromMilliseconds(200)); 54 | } 55 | 56 | base.Close(); 57 | } 58 | 59 | } 60 | 61 | } -------------------------------------------------------------------------------- /Sources/Core/MessageSubscribtionInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.Serialization; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | internal class MessageSubscribtionInfo 8 | { 9 | private readonly ICallHandler _handler; 10 | private readonly XmlObjectSerializer _serializer; 11 | private readonly MessageFilterInfo _filterInfo; 12 | 13 | public MessageSubscribtionInfo(DataContractKey contractKey, ICallHandler handler, XmlObjectSerializer serializer, bool receiveSelfPublish, IEnumerable filterHeaders) 14 | { 15 | _handler = handler; 16 | _serializer = serializer; 17 | 18 | _filterInfo = new MessageFilterInfo(contractKey, receiveSelfPublish, filterHeaders); 19 | } 20 | 21 | public ICallHandler Handler 22 | { 23 | get { return _handler; } 24 | } 25 | 26 | public XmlObjectSerializer Serializer 27 | { 28 | get { return _serializer; } 29 | } 30 | 31 | public MessageFilterInfo FilterInfo 32 | { 33 | get { return _filterInfo; } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Sources/Core/MessagingConstancts.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core 2 | { 3 | internal class MessagingConstancts 4 | { 5 | internal class Namespace 6 | { 7 | public const string MessageBus = "www.messagebus.org"; 8 | } 9 | 10 | internal class Actor 11 | { 12 | public const string User = "User"; 13 | public const string Bus = "Bus"; 14 | } 15 | 16 | internal class MessageAction 17 | { 18 | public const string Regular = "Message"; 19 | } 20 | 21 | internal class HeaderNames 22 | { 23 | public const string BusId = "BusId"; 24 | public const string SentTime = "SentTime"; 25 | public const string Name = "Name"; 26 | public const string NameSpace = "Namespace"; 27 | } 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Sources/Core/MessagingConstants.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core 2 | { 3 | public class MessagingConstants 4 | { 5 | public class Namespace 6 | { 7 | public const string MessageBus = "www.messagebus.org"; 8 | } 9 | 10 | public class Actor 11 | { 12 | public const string User = "User"; 13 | public const string Bus = "Bus"; 14 | } 15 | 16 | public class MessageAction 17 | { 18 | public const string Regular = "Message"; 19 | } 20 | 21 | public class HeaderNames 22 | { 23 | public const string BusId = "BusId"; 24 | public const string SentTime = "SentTime"; 25 | public const string Name = "Name"; 26 | public const string NameSpace = "Namespace"; 27 | } 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Sources/Core/NullCallHandler.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core.API; 2 | 3 | namespace MessageBus.Core 4 | { 5 | internal class NullCallHandler : ICallHandler 6 | { 7 | public void Dispatch(RawBusMessage message) 8 | { 9 | 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Sources/Core/NullErrorSubscriber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class NullErrorSubscriber : IErrorSubscriber 7 | { 8 | public void MessageDeserializeException(RawBusMessage busMessage, Exception exception) 9 | { 10 | } 11 | 12 | public void MessageDispatchException(RawBusMessage busMessage, Exception exception) 13 | { 14 | } 15 | 16 | public void MessageFilteredOut(RawBusMessage busMessage) 17 | { 18 | } 19 | 20 | public void UnregisteredMessageArrived(RawBusMessage busMessage) 21 | { 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Sources/Core/NullMessageFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | internal class NullMessageFilter : IMessageFilter 7 | { 8 | public void ApplyFilters(IEnumerable filters) 9 | { 10 | 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Sources/Core/NullPublishingErrorHandler.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core.API; 2 | 3 | namespace MessageBus.Core 4 | { 5 | internal class NullPublishingErrorHandler : IPublishingErrorHandler 6 | { 7 | public void DeliveryFailed(int errorCode, string text, RawBusMessage message) 8 | { 9 | 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Sources/Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Core")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Core")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("62d8978b-845d-4fd3-8b5d-d72df6b49d74")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | 37 | [assembly: InternalsVisibleTo("MessageBus.Core.ZeroMQ")] 38 | -------------------------------------------------------------------------------- /Sources/Core/PublisherConfigurator.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel.Channels; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class PublisherConfigurator : IPublisherConfigurator 7 | { 8 | private BufferManager _bufferManager; 9 | private IPublishingErrorHandler _errorHandler; 10 | private bool _mandatoryDelivery; 11 | 12 | public BufferManager BufferManager 13 | { 14 | get { return _bufferManager; } 15 | } 16 | 17 | public IPublishingErrorHandler ErrorHandler 18 | { 19 | get 20 | { 21 | return _errorHandler ?? new NullPublishingErrorHandler(); 22 | } 23 | } 24 | 25 | public bool MandatoryDelivery 26 | { 27 | get { return _mandatoryDelivery; } 28 | } 29 | 30 | public IPublisherConfigurator UseBufferManager(BufferManager bufferManager) 31 | { 32 | _bufferManager = bufferManager; 33 | 34 | return this; 35 | } 36 | 37 | public IPublisherConfigurator UseErrorHandler(IPublishingErrorHandler errorHandler) 38 | { 39 | _errorHandler = errorHandler; 40 | 41 | return this; 42 | } 43 | 44 | public IPublisherConfigurator SetMandatoryDelivery() 45 | { 46 | _mandatoryDelivery = true; 47 | 48 | return this; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Sources/Core/RabbitMQBusConfigSectionHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Configuration; 2 | using System.ServiceModel.Configuration; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class RabbitMQBusConfigSectionHandler : ConfigurationSection 7 | { 8 | public const string SectionName = "rabbitMQBus"; 9 | 10 | [ConfigurationProperty("readerQuotas")] 11 | public XmlDictionaryReaderQuotasElement ReaderQuotas 12 | { 13 | get 14 | { 15 | return (XmlDictionaryReaderQuotasElement)this["readerQuotas"]; 16 | } 17 | set 18 | { 19 | this["readerQuotas"] = value; 20 | } 21 | } 22 | 23 | [ConfigurationProperty("brokerHost", DefaultValue = "localhost")] 24 | public string BrokerHost 25 | { 26 | get 27 | { 28 | return (string)this["brokerHost"]; 29 | } 30 | set 31 | { 32 | this["brokerHost"] = value; 33 | } 34 | } 35 | 36 | [ConfigurationProperty("port", DefaultValue = 5672)] 37 | public int Port 38 | { 39 | get 40 | { 41 | return (int)this["port"]; 42 | } 43 | set 44 | { 45 | this["port"] = value; 46 | } 47 | } 48 | 49 | [ConfigurationProperty("exchange", DefaultValue = "amq.headers")] 50 | public string Exchange 51 | { 52 | get 53 | { 54 | return (string)this["exchange"]; 55 | } 56 | set 57 | { 58 | this["exchange"] = value; 59 | } 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /Sources/Core/RabbitMQMessageFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using MessageBus.Binding.RabbitMQ; 4 | using MessageBus.Core.API; 5 | using RabbitMQ.Client; 6 | 7 | namespace MessageBus.Core 8 | { 9 | internal class RabbitMQMessageFilter : IMessageFilter 10 | { 11 | private readonly RabbitMQTransportInputChannel _inputChannel; 12 | private readonly string _exchange; 13 | 14 | public RabbitMQMessageFilter(RabbitMQTransportInputChannel inputChannel, string exchange) 15 | { 16 | _inputChannel = inputChannel; 17 | _exchange = exchange; 18 | } 19 | 20 | public void ApplyFilters(IEnumerable filters) 21 | { 22 | IModel model = _inputChannel.Model; 23 | string queueName = _inputChannel.QueueName; 24 | 25 | foreach (MessageFilterInfo filter in filters) 26 | { 27 | IDictionary arguments = new Dictionary(); 28 | 29 | arguments.Add(MessagingConstants.HeaderNames.Name, filter.ContractKey.Name); 30 | arguments.Add(MessagingConstants.HeaderNames.NameSpace, filter.ContractKey.Ns); 31 | 32 | foreach (BusHeader busHeader in filter.FilterHeaders) 33 | { 34 | arguments.Add(busHeader.Name, busHeader.Value); 35 | } 36 | 37 | model.QueueBind(queueName, _exchange, "", arguments); 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Sources/Core/RawHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class RawHandler : ICallHandler 7 | { 8 | private readonly Action _action; 9 | 10 | public RawHandler(Action action) 11 | { 12 | _action = action; 13 | } 14 | 15 | public void Dispatch(RawBusMessage message) 16 | { 17 | _action(message); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Sources/Core/Subscriber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ServiceModel.Channels; 4 | using MessageBus.Core.API; 5 | 6 | namespace MessageBus.Core 7 | { 8 | internal sealed class Subscriber : MessagePumpSubscriptionBase, ISubscriber 9 | { 10 | private readonly ICallbackDispatcher _callbackDispatcher; 11 | 12 | public Subscriber(IInputChannel inputChannel, IMessageFilter messageFilter, ICallbackDispatcher dispatcher) 13 | : base(inputChannel, messageFilter, dispatcher) 14 | { 15 | _callbackDispatcher = dispatcher; 16 | } 17 | 18 | public bool Subscribe(Action callback, bool hierarchy, IEnumerable filter) 19 | { 20 | return Subscribe(typeof(TData), o => callback((TData)o), hierarchy, filter); 21 | } 22 | 23 | public bool Subscribe(Type dataType, Action callback, bool hierarchy, IEnumerable filter) 24 | { 25 | ActionHandler actionHandler = new ActionHandler(callback); 26 | 27 | return _callbackDispatcher.Subscribe(dataType, actionHandler, hierarchy, false, filter); 28 | } 29 | 30 | public bool Subscribe(Action> callback, bool hierarchy, IEnumerable filter) 31 | { 32 | return _callbackDispatcher.Subscribe(typeof(TData), new BusMessageHandler(o => callback((BusMessage) o)), hierarchy, false, filter); 33 | } 34 | 35 | public bool Subscribe(Type dataType, Action callback, bool hierarchy, IEnumerable filter) 36 | { 37 | return _callbackDispatcher.Subscribe(dataType, new RawHandler(callback), hierarchy, filter); 38 | } 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /Sources/Core/SubscriberConfigurator.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel.Channels; 2 | using System.Threading.Tasks; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public class SubscriberConfigurator : ISubscriberConfigurator 8 | { 9 | private BufferManager _bufferManager; 10 | private IErrorSubscriber _errorSubscriber; 11 | private string _queueName; 12 | 13 | public string QueueName 14 | { 15 | get { return _queueName; } 16 | } 17 | 18 | public BufferManager BufferManager 19 | { 20 | get { return _bufferManager; } 21 | } 22 | 23 | public IErrorSubscriber ErrorSubscriber 24 | { 25 | get { return _errorSubscriber ?? new NullErrorSubscriber(); } 26 | } 27 | 28 | public ISubscriberConfigurator UseBufferManager(BufferManager bufferManager) 29 | { 30 | _bufferManager = bufferManager; 31 | 32 | return this; 33 | } 34 | 35 | public ISubscriberConfigurator UseErrorSubscriber(IErrorSubscriber errorSubscriber) 36 | { 37 | _errorSubscriber = errorSubscriber; 38 | 39 | return this; 40 | } 41 | 42 | public ISubscriberConfigurator UseDurableQueue(string queueName) 43 | { 44 | _queueName = queueName; 45 | 46 | return this; 47 | } 48 | 49 | public ISubscriberConfigurator SetReceiveSelfPublish() 50 | { 51 | throw new System.NotImplementedException(); 52 | } 53 | 54 | public ISubscriberConfigurator SetConcurencyLevel(int level) 55 | { 56 | throw new System.NotImplementedException(); 57 | } 58 | 59 | public ISubscriberConfigurator UseTaskScheduler(TaskScheduler scheduler) 60 | { 61 | throw new System.NotImplementedException(); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /Sources/Core/SubscriptionBase.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ServiceModel.Channels; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | internal abstract class SubscriptionBase : ISubscription 8 | { 9 | private readonly IMessageFilter _messageFilter; 10 | 11 | protected readonly IInputChannel _inputChannel; 12 | protected readonly IDispatcher _dispatcher; 13 | 14 | protected bool _stared; 15 | 16 | protected SubscriptionBase(IInputChannel inputChannel, IMessageFilter messageFilter, IDispatcher dispatcher) 17 | { 18 | _inputChannel = inputChannel; 19 | _messageFilter = messageFilter; 20 | _dispatcher = dispatcher; 21 | } 22 | 23 | public virtual void Open() 24 | { 25 | if (_stared) return; 26 | 27 | _inputChannel.Open(); 28 | 29 | _stared = true; 30 | 31 | ApplyFilters(); 32 | } 33 | 34 | public virtual void Close() 35 | { 36 | if (_stared) 37 | { 38 | _inputChannel.Close(); 39 | } 40 | } 41 | 42 | protected void ApplyFilters() 43 | { 44 | IEnumerable filters = _dispatcher.GetApplicableFilters(); 45 | 46 | _messageFilter.ApplyFilters(filters); 47 | } 48 | 49 | public void Dispose() 50 | { 51 | Close(); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Sources/Core/TypeSubscription.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel.Channels; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | internal sealed class TypeSubscription : MessagePumpSubscriptionBase 7 | { 8 | private readonly ISubscriptionDispatcher _dispatcher; 9 | private readonly object _instance; 10 | 11 | public TypeSubscription(IInputChannel inputChannel, IMessageFilter messageFilter, ISubscriptionDispatcher dispatcher, object instance) 12 | : base(inputChannel, messageFilter, dispatcher) 13 | { 14 | _dispatcher = dispatcher; 15 | _instance = instance; 16 | } 17 | 18 | public override void Open() 19 | { 20 | _dispatcher.RegisterSubscribtion(_instance); 21 | 22 | base.Open(); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Sources/Core/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Sources/Core2/AsyncActionHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public class AsyncActionHandler : ICallHandler 8 | { 9 | private readonly Func _action; 10 | 11 | public AsyncActionHandler(Func action) 12 | { 13 | _action = action; 14 | } 15 | 16 | public async Task Dispatch(RawBusMessage message) 17 | { 18 | await _action((TData)message.Data); 19 | 20 | return new RawBusMessage(); 21 | } 22 | } 23 | 24 | public class ActionHandler : ICallHandler 25 | { 26 | private readonly Action _action; 27 | 28 | public ActionHandler(Action action) 29 | { 30 | _action = action; 31 | } 32 | 33 | public Task Dispatch(RawBusMessage message) 34 | { 35 | _action((TData)message.Data); 36 | 37 | return Task.FromResult(new RawBusMessage()); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/Core2/AsyncBusMessageCallHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public class AsyncBusMessageCallHandler : ICallHandler 8 | { 9 | private readonly Func, Task> _action; 10 | 11 | public AsyncBusMessageCallHandler(Func, Task> action) 12 | { 13 | _action = action; 14 | } 15 | 16 | public async Task Dispatch(RawBusMessage message) 17 | { 18 | BusMessage busMessage = new BusMessage 19 | { 20 | BusId = message.BusId, 21 | Sent = message.Sent, 22 | Data = (TData)message.Data 23 | }; 24 | 25 | foreach (var header in message.Headers) 26 | { 27 | busMessage.Headers.Add(header); 28 | } 29 | 30 | await _action(busMessage); 31 | 32 | return new RawBusMessage(); 33 | } 34 | } 35 | 36 | public class BusMessageCallHandler : ICallHandler 37 | { 38 | private readonly Action> _action; 39 | 40 | public BusMessageCallHandler(Action> action) 41 | { 42 | _action = action; 43 | } 44 | 45 | public Task Dispatch(RawBusMessage message) 46 | { 47 | BusMessage busMessage = new BusMessage 48 | { 49 | BusId = message.BusId, 50 | Sent = message.Sent, 51 | Data = (TData)message.Data 52 | }; 53 | 54 | foreach (var header in message.Headers) 55 | { 56 | busMessage.Headers.Add(header); 57 | } 58 | 59 | _action(busMessage); 60 | 61 | return Task.FromResult(new RawBusMessage()); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /Sources/Core2/AsyncFunctionHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public class AsyncFunctionHandler : ICallHandler 8 | { 9 | private readonly Func> _handler; 10 | 11 | public AsyncFunctionHandler(Func> handler) 12 | { 13 | _handler = handler; 14 | } 15 | 16 | public async Task Dispatch(RawBusMessage message) 17 | { 18 | TOut result = await _handler((TIn) message.Data); 19 | 20 | return new RawBusMessage {Data = result}; 21 | } 22 | } 23 | 24 | public class FunctionHandler : ICallHandler 25 | { 26 | private readonly Func _handler; 27 | 28 | public FunctionHandler(Func handler) 29 | { 30 | _handler = handler; 31 | } 32 | 33 | public Task Dispatch(RawBusMessage message) 34 | { 35 | TOut result = _handler((TIn) message.Data); 36 | 37 | return Task.FromResult(new RawBusMessage {Data = result}); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Sources/Core2/AsyncRawHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public class AsyncRawHandler : ICallHandler 8 | { 9 | private readonly Func _action; 10 | 11 | public AsyncRawHandler(Func action) 12 | { 13 | _action = action; 14 | } 15 | 16 | public async Task Dispatch(RawBusMessage message) 17 | { 18 | await _action(message); 19 | 20 | return new RawBusMessage(); 21 | } 22 | } 23 | public class RawHandler : ICallHandler 24 | { 25 | private readonly Action _action; 26 | 27 | public RawHandler(Action action) 28 | { 29 | _action = action; 30 | } 31 | 32 | public Task Dispatch(RawBusMessage message) 33 | { 34 | _action(message); 35 | 36 | return Task.FromResult(new RawBusMessage()); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Sources/Core2/ConfirmPublisher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | using RabbitMQ.Client; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public class ConfirmPublisher : Publisher, IConfirmPublisher 8 | { 9 | public ConfirmPublisher(IModel model, string busId, PublisherConfigurator configuration, IMessageHelper messageHelper, ISendHelper sendHelper) 10 | : base(model, busId, configuration, messageHelper, sendHelper) 11 | { 12 | _model.ConfirmSelect(); 13 | } 14 | 15 | public bool WaitForConfirms(TimeSpan timeOut) 16 | { 17 | return _model.WaitForConfirms(timeOut); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Sources/Core2/Core2.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | ..\..\Binaries\ 6 | True 7 | MessageBus.Core 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Sources/Core2/ICallHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public interface ICallHandler 7 | { 8 | Task Dispatch(RawBusMessage message); 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /Sources/Core2/IMessageConsumer.cs: -------------------------------------------------------------------------------- 1 | using RabbitMQ.Client; 2 | 3 | namespace MessageBus.Core 4 | { 5 | public interface IMessageConsumer : IBasicConsumer, IMessageRegistry 6 | { 7 | 8 | } 9 | } -------------------------------------------------------------------------------- /Sources/Core2/IMessageHelper.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core; 2 | using MessageBus.Core.API; 3 | using RabbitMQ.Client; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public interface IMessageHelper 8 | { 9 | SerializedBusMessage ConstructMessage(DataContractKey dataContractKey, IBasicProperties properties, byte[] data); 10 | 11 | RawBusMessage ConstructMessage(DataContractKey dataContractKey, IBasicProperties properties, object data); 12 | 13 | BusMessage ConstructMessage(DataContractKey dataContractKey, IBasicProperties properties, T data); 14 | } 15 | } -------------------------------------------------------------------------------- /Sources/Core2/IMessageRegistry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public interface IMessageRegistry 7 | { 8 | bool Register(Type type, MessageFilterInfo filterInfo, ICallHandler handler); 9 | } 10 | } -------------------------------------------------------------------------------- /Sources/Core2/IRpcConsumer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using MessageBus.Core.API; 4 | using RabbitMQ.Client; 5 | 6 | namespace MessageBus.Core 7 | { 8 | 9 | public interface IRpcConsumer : IBasicConsumer 10 | { 11 | WaitHandle RegisterCallback(string correlationId, Type replyType, Action callback); 12 | 13 | void RemoveCallback(string correlationId); 14 | 15 | void HandleBasicReturn(string correlationId, int replyCode, string replyText); 16 | } 17 | } -------------------------------------------------------------------------------- /Sources/Core2/ISendHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | using RabbitMQ.Client; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public interface ISendHelper 8 | { 9 | void Send(SerializedBusMessage message, SendParams sendParams); 10 | 11 | void Send(RawBusMessage message, ISerializer serializer, SendParams sendParams); 12 | 13 | Type GetDataType(DataContractKey dataContractKey); 14 | } 15 | 16 | public class SendParams 17 | { 18 | public IModel Model { get; set; } 19 | 20 | public string RoutingKey { get; set; } 21 | 22 | public string Exchange { get; set; } 23 | 24 | public string CorrelationId { get; set; } 25 | 26 | public string BusId { get; set; } 27 | 28 | public bool MandatoryDelivery { get; set; } 29 | 30 | public bool PersistentDelivery { get; set; } 31 | 32 | public string ReplyTo { get; set; } 33 | 34 | public byte? Priority { get; set; } 35 | } 36 | } -------------------------------------------------------------------------------- /Sources/Core2/ISubscriptionHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using MessageBus.Core.API; 4 | 5 | namespace MessageBus.Core 6 | { 7 | public interface ISubscriptionHelper 8 | { 9 | bool Subscribe(Type dataType, ICallHandler handler, bool hierarchy, IEnumerable filter); 10 | bool Subscribe(Type dataType, ICallHandler handler, IEnumerable filter); 11 | bool SubscribeHierarchy(Type baseType, ICallHandler handler, IEnumerable filter); 12 | void RegisterSubscription(object instance); 13 | } 14 | } -------------------------------------------------------------------------------- /Sources/Core2/JsonSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | using MessageBus.Core.API; 5 | using Newtonsoft.Json; 6 | 7 | namespace MessageBus.Core 8 | { 9 | public class JsonSerializer : ISerializer 10 | { 11 | private readonly Encoding _encoding = Encoding.UTF8; 12 | 13 | private readonly JsonSerializerSettings _settings; 14 | 15 | public JsonSerializer(JsonSerializerSettings settings) 16 | { 17 | _settings = settings; 18 | } 19 | 20 | public string ContentType => "application/json"; 21 | 22 | public byte[] Serialize(RawBusMessage busMessage) 23 | { 24 | object data = busMessage.Data; 25 | 26 | string body = JsonConvert.SerializeObject(data, _settings); 27 | 28 | return _encoding.GetBytes(body); 29 | } 30 | 31 | public object Deserialize(Type dataType, byte[] body) 32 | { 33 | string sBody = _encoding.GetString(body); 34 | 35 | return JsonConvert.DeserializeObject(sBody, dataType, _settings); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Sources/Core2/MessageFilterInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class MessageFilterInfo 7 | { 8 | private readonly DataContractKey _contractKey; 9 | private readonly List _filterHeaders; 10 | 11 | public MessageFilterInfo(DataContractKey contractKey, IEnumerable filterHeaders) 12 | { 13 | _contractKey = contractKey; 14 | _filterHeaders = new List(filterHeaders); 15 | } 16 | 17 | public DataContractKey ContractKey 18 | { 19 | get { return _contractKey; } 20 | } 21 | 22 | public IEnumerable FilterHeaders 23 | { 24 | get { return _filterHeaders; } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Sources/Core2/MessageMonitor.cs: -------------------------------------------------------------------------------- 1 | using RabbitMQ.Client; 2 | 3 | namespace MessageBus.Core 4 | { 5 | public class MessageMonitor : SubscriberBase 6 | { 7 | public MessageMonitor(IModel model, string queue, IBasicConsumer consumer, SubscriberConfigurator configurator) : base(model, queue, consumer, configurator) 8 | { 9 | } 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /Sources/Core2/MessagingConstants.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core 2 | { 3 | public class MessagingConstants 4 | { 5 | public class HeaderNames 6 | { 7 | public const string BusId = "BusId"; 8 | public const string SentTime = "SentTime"; 9 | public const string Name = "Name"; 10 | public const string NameSpace = "Namespace"; 11 | } 12 | public class Actor 13 | { 14 | public const string User = "User"; 15 | public const string Bus = "Bus"; 16 | } 17 | 18 | public class MessageAction 19 | { 20 | public const string Regular = "Message"; 21 | } 22 | public class Namespace 23 | { 24 | public const string MessageBus = "www.messagebus.org"; 25 | } 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/Core2/NullBlockWatcher.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core.API; 2 | 3 | namespace MessageBus.Core 4 | { 5 | public class NullBlockWatcher : IBlockWatcher 6 | { 7 | public void ConnectionBlocked(string reason) 8 | { 9 | 10 | } 11 | 12 | public void ConnectionUnblocked() 13 | { 14 | 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Sources/Core2/NullCallHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | internal class NullCallHandler : ICallHandler 7 | { 8 | public Task Dispatch(RawBusMessage message) 9 | { 10 | return Task.FromResult(new RawBusMessage()); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Sources/Core2/NullErrorSubscriber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class NullErrorSubscriber : IErrorSubscriber 7 | { 8 | public void UnhandledException(Exception exception) 9 | { 10 | 11 | } 12 | 13 | public void MessageDeserializeException(RawBusMessage busMessage, Exception exception) 14 | { 15 | } 16 | 17 | public void MessageDispatchException(RawBusMessage busMessage, Exception exception) 18 | { 19 | } 20 | 21 | public void MessageFilteredOut(RawBusMessage busMessage) 22 | { 23 | } 24 | 25 | public void UnregisteredMessageArrived(RawBusMessage busMessage) 26 | { 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Sources/Core2/NullExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | internal class NullExceptionFilter : IExceptionFilter 7 | { 8 | public bool Filter(Exception exception, RawBusMessage message, bool redelivered, ulong deliveryTag) 9 | { 10 | return true; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Sources/Core2/NullPublishingErrorHandler.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core.API; 2 | 3 | namespace MessageBus.Core 4 | { 5 | internal class NullPublishingErrorHandler : IPublishingErrorHandler 6 | { 7 | public void DeliveryFailed(int errorCode, string text, RawBusMessage message) 8 | { 9 | 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Sources/Core2/NullTrace.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core.API; 2 | 3 | namespace MessageBus.Core 4 | { 5 | public class NullTrace : ITrace 6 | { 7 | public void MessageArrived(string busId, RawBusMessage busMessage, string consumerTag) 8 | { 9 | } 10 | 11 | public void MessageSent(string busId, RawBusMessage busMessage) 12 | { 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Sources/Core2/RpcPublisherConfigurator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBus.Core.API; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class RpcPublisherConfigurator : PublisherConfigurator, IRpcPublisherConfigurator 7 | { 8 | private bool _useFastReply; 9 | private string _replyExchange; 10 | private string _consumerTag = ""; 11 | 12 | public RpcPublisherConfigurator(string exchange, bool useFastReply, string replyExchange, IPublishingErrorHandler errorHandler, ITrace trace, Func blocked) 13 | : base(exchange, errorHandler, trace, blocked) 14 | { 15 | _useFastReply = useFastReply; 16 | _replyExchange = replyExchange; 17 | } 18 | 19 | public bool UseFastReply 20 | { 21 | get { return _useFastReply; } 22 | } 23 | 24 | public string ReplyExchange 25 | { 26 | get { return _replyExchange; } 27 | } 28 | public string ConsumerTag 29 | { 30 | get { return _consumerTag; } 31 | } 32 | 33 | public IRpcPublisherConfigurator DisableFastReply() 34 | { 35 | _useFastReply = false; 36 | 37 | return this; 38 | } 39 | 40 | 41 | public IRpcPublisherConfigurator SetReplyExchange(string replyExchange) 42 | { 43 | _replyExchange = replyExchange; 44 | 45 | return this; 46 | } 47 | 48 | public IRpcPublisherConfigurator SetConsumerTag(string consumerTag) 49 | { 50 | _consumerTag = consumerTag; 51 | 52 | return this; 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Sources/Core2/SubscriberBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using MessageBus.Core.API; 4 | using RabbitMQ.Client; 5 | 6 | namespace MessageBus.Core 7 | { 8 | public class SubscriberBase : ISubscription 9 | { 10 | private readonly IModel _model; 11 | private readonly string _queue; 12 | private readonly IBasicConsumer _consumer; 13 | private readonly SubscriberConfigurator _configurator; 14 | 15 | private string _consumerTag; 16 | 17 | public SubscriberBase(IModel model, string queue, IBasicConsumer consumer, SubscriberConfigurator configurator) 18 | { 19 | _model = model; 20 | 21 | _queue = queue; 22 | 23 | _consumer = consumer; 24 | _configurator = configurator; 25 | } 26 | 27 | ~SubscriberBase() 28 | { 29 | Dispose(true); 30 | } 31 | 32 | private void Dispose(bool finializing) 33 | { 34 | if (finializing && _configurator.Blocked) return; 35 | 36 | _model.Abort(); 37 | } 38 | 39 | public void Dispose() 40 | { 41 | Dispose(false); 42 | 43 | GC.SuppressFinalize(this); 44 | } 45 | 46 | public void Open() 47 | { 48 | if (_configurator.Prefetch > 0) 49 | { 50 | _model.BasicQos(0, _configurator.Prefetch, false); 51 | } 52 | 53 | _consumerTag = _model.BasicConsume(_queue, !_configurator.TransactionalDelivery, _configurator.ConsumerTag, !_configurator.ReceiveSelfPublish, false, new Dictionary(), _consumer); 54 | } 55 | 56 | public void Close() 57 | { 58 | _model.BasicCancel(_consumerTag); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /Sources/Core2/Subscription.cs: -------------------------------------------------------------------------------- 1 | using RabbitMQ.Client; 2 | 3 | namespace MessageBus.Core 4 | { 5 | public class Subscription : SubscriberBase 6 | { 7 | public Subscription(IModel model, string queue, IMessageConsumer consumer, object instance, SubscriberConfigurator configurator, ISubscriptionHelper helper) 8 | : base(model, queue, consumer, configurator) 9 | { 10 | helper.RegisterSubscription(instance); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Sources/Core2/SubscriptionInfo.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBus.Core 2 | { 3 | public class SubscriptionInfo 4 | { 5 | public ICallHandler Handler { get; set; } 6 | 7 | public MessageFilterInfo FilterInfo { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Sources/Core2/SyncTaskScheduler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | 5 | namespace MessageBus.Core 6 | { 7 | /// 8 | /// Default task scheduler which executes all tasks in current thread 9 | /// 10 | public class SyncTaskScheduler : TaskScheduler 11 | { 12 | protected override void QueueTask(Task task) 13 | { 14 | TryExecuteTask(task); 15 | } 16 | 17 | protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) 18 | { 19 | return TryExecuteTask(task); 20 | } 21 | 22 | protected override IEnumerable GetScheduledTasks() 23 | { 24 | return Enumerable.Empty(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Sources/Core2/TransactionalPublisher.cs: -------------------------------------------------------------------------------- 1 | using MessageBus.Core.API; 2 | using RabbitMQ.Client; 3 | 4 | namespace MessageBus.Core 5 | { 6 | public class TransactionalPublisher : Publisher, ITransactionalPublisher 7 | { 8 | public TransactionalPublisher(IModel model, string busId, PublisherConfigurator configuration, IMessageHelper messageHelper, ISendHelper sendHelper) 9 | : base(model, busId, configuration, messageHelper, sendHelper) 10 | { 11 | _model.TxSelect(); 12 | } 13 | 14 | public void Commit() 15 | { 16 | _model.TxCommit(); 17 | } 18 | 19 | public void Rollback() 20 | { 21 | _model.TxRollback(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Sources/Core2/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sources/Local.testsettings: -------------------------------------------------------------------------------- 1 |  2 | 3 | These are default test settings for a local test run. 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Sources/MessageBus.vsmdi: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parshim/MessageBus/0f7bbc3f7a0688555743f8983d224bb9553ae270/icon.png --------------------------------------------------------------------------------