Endpoints running on different transports cannot exchange messages and require additional integration work.
Common examples include:
- A hybrid solution that spans across endpoints deployed on-premises and in a cloud environment.
- Departments within organization integrating their systems that use different messaging technologies for historical reasons.
Traditionally, such integrations would require native messaging or relaying. Bridging is an alternative, allowing endpoints to communicate over different transports without a need to get into low-level messaging technology code. With time, when endpoints can standardize on a single transport, bridging can be removed with a minimal impact on the entire system.
Prerequisites
An environment variable named AzureServiceBus.
with the connection string for the Azure Service Bus namespace.
Azure Service Bus Transport
This sample uses the Azure Service Bus Transport (Legacy).
Code walk-through
This sample shows an integration between two endpoints running on two different transports, MsmqEndpoint
endpoint running on MSMQ and AsbEndpoint
running on Azure Service Bus.
Covered scenarios are:
- Sending commands from Azure Service Bus endpoint to MSMQ endpoint.
- Publishing events from MSMQ endpoint and subscribing to those events from Azure Service Bus endpoint.
Bridging
Endpoints are bridged using NServiceBus.Router. Bridge
project is implemented as a standalone process that runs side-by-side with the bridged endpoints, MsmqEndpoint
and AsbEndpoint
.
Azure Service Bus endpoint configuration
In this example Azure Service Bus transport is configured to use the EndpointOrientedTopology
(to learn more check the topologies documentation). This topology requires some additional steps to be properly bridged.
topology.RegisterPublisher(typeof(MyEvent), "Bridge");
Azure Service Bus endpoint is bridged via Bridge
queue:
var routing = transport.Routing();
var bridge = routing.ConnectToBridge("Bridge");
The routing of commands to the MSMQ endpoint is specified using bridge extension method:
bridge.RouteToEndpoint(typeof(MyCommand), "Samples.Azure.ServiceBus.MsmqEndpoint");
NServiceBus.Router.Connector
NuGet package for NServiceBus 7 or NServiceBus.Bridge.Connector
NuGet package for NServiceBus 6.To subscribe to an event published by MSMQ endpoint, Azure Service Bus endpoint must register publishing endpoint using bridge extension method:
bridge.RegisterPublisher(typeof(MyEvent), "Samples.Azure.ServiceBus.MsmqEndpoint");
MSMQ endpoint configuration
MSMQ endpoint is bridged via Bridge
queue:
Bridge configuration
Bridge process is connecting between MSMQ and Azure ServiceBus transports and provide any configuration settings required by any of the transports. For Azure Service Bus that would be a mandatory connection string and topology.
var bridgeConfiguration = new RouterConfiguration("Bridge");
var azureInterface = bridgeConfiguration.AddInterface<AzureServiceBusTransport>("ASB", transport =>
{
//Prevents ASB from using TransactionScope
transport.Transactions(TransportTransactionMode.ReceiveOnly);
transport.ConnectionString(connectionString);
// TODO: ASB requires serializer to be registered.
// Currently, there's no way to specify serialization for the bridged endpoints
// endpointConfiguration.UseSerialization<T>();
var settings = transport.GetSettings();
var serializer = Tuple.Create(new NewtonsoftSerializer() as SerializationDefinition, new SettingsHolder());
settings.Set("MainSerializer", serializer);
var topology = transport.UseEndpointOrientedTopology().EnableMigrationToForwardingTopology();
topology.RegisterPublisher(typeof(OtherEvent), "Samples.Azure.ServiceBus.AsbEndpoint");
});
var msmqInterface = bridgeConfiguration.AddInterface<MsmqTransport>("MSMQ", transport =>
{
transport.Transactions(TransportTransactionMode.ReceiveOnly);
});
msmqInterface.EnableMessageDrivenPublishSubscribe(new InMemorySubscriptionStorage());
bridgeConfiguration.AutoCreateQueues();
var staticRouting = bridgeConfiguration.UseStaticRoutingProtocol();
staticRouting.AddForwardRoute(
incomingInterface: "MSMQ",
outgoingInterface: "ASB");
staticRouting.AddForwardRoute(
incomingInterface: "ASB",
outgoingInterface: "MSMQ");
A bridge is created, started, and should be executed as long as bridging is required.
InMemorySubscriptionStorage
. In production SqlSubscriptionStorage
(included in the NServiceBus.Router package) or custom persistent subscription storage should be used to prevent message loss.var bridge = Router.Create(bridgeConfiguration);
await bridge.Start().ConfigureAwait(false);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
await bridge.Stop().ConfigureAwait(false);