SzymonPobiega / NServiceBus.Router

Cross-transport, cross-site and possibly cross-cloud router component for NServiceBus
MIT License
5 stars 10 forks source link

SQS to AzureServiceBus - The given key (NServiceBus.Unicast.Messages.MessageMetadataRegistry) was not present in the dictionary. #40

Closed CraftJackDeveloper closed 3 years ago

CraftJackDeveloper commented 3 years ago

I'm trying to set up a router for sending messages from AzureServiceBus to SQS but am getting the following exception in the SQS interface when starting the router:

System.Collections.Generic.KeyNotFoundException: The given key (NServiceBus.Unicast.Messages.MessageMetadataRegistry) was not present in the dictionary.
   at NServiceBus.Settings.SettingsHolder.Get(String key) in /_/src/NServiceBus.Core/Settings/SettingsHolder.cs:line 91
   at NServiceBus.Settings.SettingsHolder.Get[T]() in /_/src/NServiceBus.Core/Settings/SettingsHolder.cs:line 70
   at NServiceBus.Transport.SQS.Configure.SqsTransportInfrastructure..ctor(ReadOnlySettings settings) in /_/src/NServiceBus.Transport.SQS/Configure/SqsTransportInfrastructure.cs:line 24
   at NServiceBus.SqsTransport.Initialize(SettingsHolder settings, String connectionString) in /_/src/NServiceBus.Transport.SQS/Configure/SqsTransport.cs:line 42
   at NServiceBus.Raw.InitializableRawEndpoint.Initialize()
   at ThrottlingRawEndpointConfig`1.Create()
   at Interface`1.Initialize(InterfaceChains interfaces, RootContext rootContext)
   at RouterImpl.Initialize()
   at RouterImpl.Start()

Here is my router configuration code:

...
var routerConfig = new RouterConfiguration($"ASBToSQS.Router");
var azureInterface = routerConfig.AddInterface<AzureServiceBusTransport>("Azure", t =>
{
    t.ConnectionString(context.Configuration["NServiceBus:Router:AzureConnectionString"]);

    t.Transactions(TransportTransactionMode.ReceiveOnly);
    t.SubscriptionRuleNamingConvention((entityType) =>
    {
        var entityPathOrName = entityType.Name;
        if (entityPathOrName.Length >= 50)
        {
            return entityPathOrName.Split('.').Last();
        }

        return entityPathOrName;
    });
});

var sqsInterface = routerConfig.AddInterface<SqsTransport>("SQS", t =>
{
    // using default environment variable credentials
});

var staticRouting = routerConfig.UseStaticRoutingProtocol();

staticRouting.AddForwardRoute("Azure", "SQS");

routerConfig.AutoCreateQueues();
...

I've tried calling .EnableMessageDrivenPublishSubscribe(...) using sql subscription storage because I found this issue and it seemed like that was the only notable difference in setups, but I'm still getting the same error.

This is running in a .NET Core 5.0 worker app using:

I'm sure I'm just missing something but am out of ideas. Any help would be greatly appreciated.

SzymonPobiega commented 3 years ago

Hi

Unfortunately due to a legacy design of the SQS transport, you need some additional configuration in your SQS interface, namely you need to provide a placeholder MessageMetadataRegistry. Take a look here to see how it can be done via reflection (the ctor of this type is internal, but the type itself is public).

CraftJackDeveloper commented 3 years ago

That worked like a charm, thank you!