akkadotnet / Alpakka

Akka Streams Connectors - Alpakka

Home Page:https://alpakka.getakka.net/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using AmqpConnectionDetails with SSL enabled always results with "localhost" endpoint

vasily-kirichenko opened this issue · comments

The following connection details:

let settings =
        AmqpConnectionDetails.Create("host22", 5671)
            .WithAutomaticRecoveryEnabled(true)
            .WithNetworkRecoveryInterval(TimeSpan.FromSeconds 1.0)
            .WithCredentials(AmqpCredentials.Create("foo", "1"))
            .WithSsl(SslOption("host22", enabled = true))

results with a ConnectionFactory, which's Endpoint is localhost.

A workaround: use AmqpConnectionUri.Create("amqps://foo:1@host22:5671") instead.

@vasily-kirichenko is this a bug with our code or the driver being used?

The driver?.. I'm not sure what you mean. I just expect the code ^^ to connect to "host22" via SSL, but it connects to "localhost".

My bad, thought it might be an issue with the RabbitMQ driver - but no, it's probably an issue with how we propagate settings here:

public static IConnectionFactory ConnectionFactoryFrom(IAmqpConnectionSettings settings)
{
var factory = new ConnectionFactory();
switch (settings)
{
case AmqpConnectionUri connectionUri:
factory.Uri = connectionUri.Uri;
break;
case AmqpConnectionDetails details:
{
if (details.Credentials.HasValue)
{
factory.UserName = details.Credentials.Value.Username;
factory.Password = details.Credentials.Value.Password;
}
if (!string.IsNullOrEmpty(details.VirtualHost))
factory.VirtualHost = details.VirtualHost;
if (details.Ssl != null)
factory.Ssl = details.Ssl;
if (details.AutomaticRecoveryEnabled.HasValue)
factory.AutomaticRecoveryEnabled = details.AutomaticRecoveryEnabled.Value;
if (details.RequestedHeartbeat.HasValue)
factory.RequestedHeartbeat = new TimeSpan(details.RequestedHeartbeat.Value);
if (details.NetworkRecoveryInterval.HasValue)
factory.NetworkRecoveryInterval = details.NetworkRecoveryInterval.Value;
if (details.TopologyRecoveryEnabled.HasValue)
factory.TopologyRecoveryEnabled = details.TopologyRecoveryEnabled.Value;
if (details.ConnectionTimeout.HasValue)
factory.ContinuationTimeout = details.ConnectionTimeout.Value;
if (details.HandshakeTimeout.HasValue)
factory.HandshakeContinuationTimeout = details.HandshakeTimeout.Value;
break;
}
case DefaultAmqpConnection defaultConnection:
//leave it be as is
break;
}
return factory;
}

I'll ask @Arkatufus to look at it

Yeah, in the working branch:

case AmqpConnectionUri connectionUri:
    factory.Uri = connectionUri.Uri;

the Uri setter (which is in RabbitMQ.Client library) does a lot of work (like constructing SslOptions if the schema is amqps and so on). I think it would be a good idea to check if that logic is copied here.

AmqpConnectionDetails doesn't inherit from AmqpConnectionUri so that code shouldn't be called, but it's something we can test easily enough.

Or, even better, just provide a details derivative which accepts a seq of raw amqp(s) Uris, and let RabbitMQ.Client lib parse them.

I mean, to provide a bunch of Uris in case of RMQ cluster.