SQS/SNS - MSMQ - Router not working behind a proxy

I have successfully implemented an endpoint (v7.5.0 using .net 4.8) that runs on a windows server and utilizes the router to bridge between the MSMQ and AWS. It runs correctly from multiple developers machines but we have into some issues moving it into our development environment.
In our dev environment we have added the SQS queues urls to the proxy and the generic SNS url us-east-2 to the proxy as well.
I also have both the router and endpoint itself setting up the client factory to configure to use the SQS client with a SQS config object to set the properties for the proxy.

When we run this all the SQS queues get created properly from behind the proxy, but the SNS topics and subscriptions are not created from behind the proxy. Looking at CloudTrail I donā€™t see any SNS activity except from our local machines.

I wanted to see if there is anything special with the SNS component that needs to be configured differently for it to work from behind a proxy. I am already doing custom config on the router so it will work based on previous responses to questions I have posted in the forums.

                extensions.ClientFactory(() => {
                return (!useProxy)? new AmazonSQSClient(): new AmazonSQSClient(new AmazonSQSConfig
                {
                    ProxyHost = proxyUrl,
                    ProxyPort = proxyPort
                });
            });

            var ctor = typeof(MessageMetadataRegistry).GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(Func<Type, bool>) }, null);
#pragma warning disable CS0618 // Type or member is obsolete
            settings.Set<MessageMetadataRegistry>(ctor.Invoke(new object[] { (Func<Type, bool>)isMessageType }));
#pragma warning restore CS0618 // Type or member is obsolete

Have you tried setting the SNS Client as well?

extensions.ClientFactory(() => {
                return (!useProxy)? new AmazonSimpleNotificationServiceClient(): new AmazonSimpleNotificationServiceClient(new AmazonSimpleNotificationServiceConfig
                {
                    ProxyHost = proxyUrl,
                    ProxyPort = proxyPort
                });

It looks like this configuration option is missing in the documentation

Iā€™ve sent a draft PR

Regards
Daniel

@danielmarbach Thank you for the response.

Besides setting it for the router I also set it for the main endpoint off of the transport object.
It both cases I believe the call to the client factory returns the one client to use. How would I configure both SQS and SNS ?

The client factory has multiple overloads accepting different interfaces. You can call it multiple times for each client you want to configure

That workedā€¦. Thank you so much !!!

1 Like

You are most welcome Robert. In hindsight having more descriptive names for the individual factories might have been a more discoverable API. When I was involved in the design discussions at the time we figured having the same name with multiple overloads is discoverable since they are all client factories but seeing you struggle with this design might be a good indicator to rethink this.

Iā€™m sure the team will value your feedback if you have some thoughts to share.

@RGBZ with the new version of transport, that will be released with NServiceBus V8, we changed the way transports are configured. We moved away from extension methods to properties and constructors. With the new version of the transport, for example, your scenario will be much easier to implement as you have to explicitly provide AWS client instances:

var transport = new SqsTransport(
    new AmazonSQSClient(new InstanceProfileAWSCredentials()), 
    new AmazonSimpleNotificationServiceClient());

endpointConfiguration.UseTransport(transport);

And only the S3 client is optional, transport.S3 is the property to use.

.m

I like the approach you mentioned below. At least to me it makes it a lot clearer as to what should be supplied to properly configure a transport.

Thanks for the feedback @RGBZ.

Thatā€™s probably one of the main reasons why we moved to a property/constructor-based approach. Constructors allow expressing the fact that a parameter is mandatory.