diff --git a/src/Ombi/Extensions/DatabaseExtensions.cs b/src/Ombi/Extensions/DatabaseExtensions.cs index a96011f1c..4697b1daa 100644 --- a/src/Ombi/Extensions/DatabaseExtensions.cs +++ b/src/Ombi/Extensions/DatabaseExtensions.cs @@ -3,11 +3,14 @@ using System.IO; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; +using MySqlConnector; using Newtonsoft.Json; using Ombi.Helpers; using Ombi.Store.Context; using Ombi.Store.Context.MySql; using Ombi.Store.Context.Sqlite; +using Polly; +using Pomelo.EntityFrameworkCore.MySql.Storage.Internal; using SQLitePCL; namespace Ombi.Extensions @@ -120,13 +123,40 @@ namespace Ombi.Extensions public static void ConfigureMySql(DbContextOptionsBuilder options, PerDatabaseConfiguration config) { - options.UseMySql(config.ConnectionString, ServerVersion.AutoDetect(config.ConnectionString), b => + if (string.IsNullOrEmpty(config.ConnectionString)) + { + throw new ArgumentNullException("ConnectionString for the MySql/Mariadb database is empty"); + } + + options.UseMySql(config.ConnectionString, GetServerVersion(config.ConnectionString), b => { //b.CharSetBehavior(Pomelo.EntityFrameworkCore.MySql.Infrastructure.CharSetBehavior.NeverAppend); // ##ISSUE, link to migrations? b.EnableRetryOnFailure(); }); } + private static ServerVersion GetServerVersion(string connectionString) + { + // Workaround Windows bug, that can lead to the following exception: + // + // MySqlConnector.MySqlException (0x80004005): SSL Authentication Error + // ---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception. + // ---> System.ComponentModel.Win32Exception (0x8009030F): The message or signature supplied for verification has been altered + // + // See https://github.com/dotnet/runtime/issues/17005#issuecomment-305848835 + // + // Also workaround for the fact, that ServerVersion.AutoDetect() does not use any retrying strategy. + ServerVersion serverVersion = null; +#pragma warning disable EF1001 + var retryPolicy = Policy.Handle(exception => MySqlTransientExceptionDetector.ShouldRetryOn(exception)) +#pragma warning restore EF1001 + .WaitAndRetry(3, (count, context) => TimeSpan.FromMilliseconds(count * 250)); + + serverVersion = retryPolicy.Execute(() => serverVersion = ServerVersion.AutoDetect(connectionString)); + + return serverVersion; + } + public class DatabaseConfiguration { public DatabaseConfiguration()