rebus-org / Rebus.SqlServer

:bus: Microsoft SQL Server transport and persistence for Rebus
https://mookid.dk/category/rebus
Other
43 stars 42 forks source link

Azure Microsoft.Data.SqlConnection and AccessToken API #69

Closed samartzidis closed 3 years ago

samartzidis commented 3 years ago

Hi,

I am trying to get the 7.0.0-a1 prerelease to play with Azure DBs and AccessToken authentication.

Is there an API for generating and setting the AccessToken on the internally generated Microsoft.Data.SqlClient.SqlConnection of the Rebus.SqlServer library? I was n't able to find anything.

The workaround that I came up with is creating my own implementation of your IDbConnectionProvider interface that provisions for AccessToken generation, but this is a lot of extra boilerplate code that by 99% replicates your own DbConnectionProvider class. Maybe you can make the DbConnectionProvider to accept a callback delegate/DI interface for injecting an AccessToken?

Thanks!

mookid8000 commented 3 years ago

Sorry for taking so long to get back to you – it's vacation time 😎 I promise I'll get back to you some time soon

samartzidis commented 3 years ago

Enjoy your holidays! This is not something urgent as this is about a prerelease version and I've found a workaround already, but maybe you would like to think about that kind of API once you're back! :) Best Regards.

mookid8000 commented 3 years ago

Sorry for taking so long to get back to you!

I've added an SqlConnectionOpening callback to DbConnectionProvider, allowing you to do something like this:

Configure.With(activator)
    .Transport(t =>
    {
        var options = new SqlServerTransportOptions(c =>
        {
            var connectionString = SqlTestHelper.ConnectionString;
            var loggerFactory = c.Get<IRebusLoggerFactory>();

            var connectionProvider = new DbConnectionProvider(connectionString, loggerFactory)
            {
                SqlConnectionOpening = async connection => connection.AccessToken = await GetAccessToken();
            };

            return connectionProvider;
        });

        t.UseSqlServer(options, "test-queue");
    })
    .Start();

where GetAccessToken would then use whichever way you prefer to obtain the relevant token.

It's out in Rebus.SqlServer 7.1.4, which is on NuGet.org now! Let me know how it works out for you 🙂

samartzidis commented 3 years ago

Thanks a lot for this work! Just an extra note, as far as I see this is for configuring the Transport component. How I would configure the Timeouts and the Saga storage (targeting Azure SQL Server in my case) to use the same AccessToken delegate pattern?

As a workaround, for Timeouts I have currently come up with this helper extension method (and something similar for Sagas):

public static void StoreInSqlServerEx(
            this StandardConfigurer<ITimeoutManager> configurer,
            string connectionString, 
            string tableName,
            Func<SqlConnection, Task> sqlConnectionOpening = null,
            bool automaticallyCreateTables = true, 
            bool enlistInAmbientTransaction = false)
        {
            if (configurer == null) throw new ArgumentNullException(nameof(configurer));
            if (connectionString == null) throw new ArgumentNullException(nameof(connectionString));
            if (tableName == null) throw new ArgumentNullException(nameof(tableName));

            configurer.Register(c =>
            {
                var rebusTime = c.Get<IRebusTime>();
                var rebusLoggerFactory = c.Get<IRebusLoggerFactory>();
                var connectionProvider = new DbConnectionProvider(connectionString, rebusLoggerFactory, enlistInAmbientTransaction) { SqlConnectionOpening = sqlConnectionOpening };
                var subscriptionStorage = new SqlServerTimeoutManager(connectionProvider, tableName, rebusLoggerFactory, rebusTime);

                if (automaticallyCreateTables)
                {
                    subscriptionStorage.EnsureTableIsCreated();
                }

                return subscriptionStorage;
            });
        }

Thank you.

mookid8000 commented 3 years ago

Oh yeah, you're right.... I'm on it 🙂

mookid8000 commented 3 years ago

OK I've released Rebus.SqlServer 7.1.5 that has additional overloads of all .StoreInSqlServer(...) configuration methods to accept appropriate options objects.

This should enable a consistent level of customization across all persisters.

Thanks for pointing it put 👍

samartzidis commented 3 years ago

@mookid8000 Thank you!