Search code examples
castle-windsormsmqnservicebusazure-storage-queues

NServiceBus handle (receive) a Msmq message and send to a AzureStorageQueue using CastleWindsor


Is it possible to have an Endpoint that handles a message via a Msmq transport, then as part of the handler it then sends using AzureStorageQueue transport.

The setup I have is an Endpoint on premise which is handling a 'Notification' message via msmq. My handler retrieves some information from a database and then I want to send this data on to an AzureStorageQueue.

My EndpointConfig.cs looks something like this:

public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
    private IWindsorContainer container;

    public void Init()
    {
        this.InitialiseContainer();

        Configure.With()
                 .Log4Net()
                 .CastleWindsorBuilder(this.container)
                 .UseTransport<Msmq>()
                 .PurgeOnStartup(false)
                 .UnicastBus();
    }

    private void InitialiseContainer()
    {
        this.container = new WindsorContainer();
        this.container.Install(FromAssembly.Named("Notifications"));
        this.container.Register(Component.For<IWindsorContainer>()
                                         .Instance(this.container));
    }
}

My Handler looks like this:

public class NotificationHandler : IHandleMessages<NotificationV1>
{
    private readonly IWindsorContainer container;

    public NotificationHandler(IWindsorContainer container)
    {
        this.container = container;
    }

    public void Handle(NotificationV1 message)
    {
        if (message != null && message.CorrelationId != Guid.Empty)
        {
            var thingToPublish = new DataAccess.GetThingToPublish(message.Id);

            var publishMessage = new PublishV1
                {
                    CorrelationId = message.CorrelationId,
                    Timestamp = message.Timestamp,
                    Id = message.Id,
                    ThingToPublish = thingToPublish
                };

            // Here I intend to resolve the AzureStorageBus Queue and send the publishMessage to it
            var bus = this.container.Resolve<IBus>(); //Not I know this bit is wrong as it is sending it to the Msmq
            bus.Send("PublishQueue", publishMessage);
        }
    }
}

Some snippets from my app.config as follows

<configSections>
    <section name="AzureQueueConfig" type="NServiceBus.Config.AzureQueueConfig, NServiceBus.Azure.Transports.WindowsAzureStorageQueues" />
    <section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
    <section name="TransportConfig" type="NServiceBus.Config.TransportConfig, NServiceBus.Core" />
    <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
    <section name="AuditConfig" type="NServiceBus.Config.AuditConfig, NServiceBus.Core" />
</configSections>

<UnicastBusConfig>
    <MessageEndpointMappings>
        <add Messages="Messages.NotificationV1, Messages" Endpoint="notification.endpoint" />
    </MessageEndpointMappings>
</UnicastBusConfig>

<AuditConfig QueueName="Notifications.Audit" />

<AzureQueueConfig QueueName="PublishQueue" ConnectionString="UseDevelopmentStorage=true" />

So in summary: 1. Is it possible to handle a message from msmq and then send a message to AzureStorageQueue? 2. If so, how do I do it?

Thanks Dan


Solution

  • NServicebus does not support multiple transports at the moment, so an endpoint receiving from msmq also has to send to msmq. However it is possible to create a bridge from one transport type to the other if you play around with the internal structure a bit. I did this for a poc with msmq and azure servicebus a while ago, you could do the same for azure storage. See https://github.com/yvesgoeleven/NServiceBus.MsmqAsbBridge