Populate Enova database settings from connection string

This commit is contained in:
2026-08-31 23:59:55 +00:00
parent e40f8ccdb1
commit a040a91d1f
10 changed files with 107 additions and 7 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,4 +1,5 @@
using System.Reflection;
using Microsoft.Data.SqlClient;
using SmartB2B.Enova.Contracts;
using Soneta.Business;
using Soneta.Business.App;
@@ -253,18 +254,50 @@ public sealed class EnovaOrderAdapter : IEnovaOrderAdapter
application.Remove(existing, save: false);
}
var database = new MsSqlDatabase
{
Name = connection.DatabaseName,
Active = true,
UseConnectionString = true,
ConnectionString = connection.SqlConnectionString
};
var database = CreateDatabase(connection);
application.Add(database, save: false);
return database;
}
private static MsSqlDatabase CreateDatabase(EnovaConnectionOptions connection)
{
var sqlConnection = ParseSqlConnectionString(connection.SqlConnectionString);
return new MsSqlDatabase
{
Name = connection.DatabaseName,
Active = true,
Server = sqlConnection.DataSource,
DatabaseName = sqlConnection.InitialCatalog,
User = sqlConnection.UserID,
Password = sqlConnection.Password,
Trusted = sqlConnection.IntegratedSecurity,
TrustServerCertificate = sqlConnection.TrustServerCertificate,
UseConnectionString = true,
ConnectionString = connection.SqlConnectionString
};
}
private static SqlConnectionSettings ParseSqlConnectionString(string connectionString)
{
var builder = new SqlConnectionStringBuilder(connectionString);
return new SqlConnectionSettings(
builder.DataSource,
builder.InitialCatalog,
builder.UserID,
builder.Password,
builder.IntegratedSecurity,
builder.TrustServerCertificate);
}
private sealed record SqlConnectionSettings(
string DataSource,
string InitialCatalog,
string UserID,
string Password,
bool IntegratedSecurity,
bool TrustServerCertificate);
private static void ValidateConfiguration(EnovaAdapterConfiguration configuration)
{
var errors = new List<string>();

View File

@@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../SmartB2B.Enova.Contracts/SmartB2B.Enova.Contracts.csproj" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
<PackageReference Include="Soneta.Handel" Version="2604.4.4" />
<PackageReference Include="Soneta.Business.Licence" Version="2604.4.4" />
<PackageReference Include="Soneta.Licence.Local.Proxy" Version="1.0.2" />

View File

@@ -1,5 +1,6 @@
using System.Data.Common;
using System.Reflection;
using System.Runtime.Loader;
using SmartB2B.Enova.Contracts;
using SmartB2B.Enova.Service;
using SmartB2B.Enova.Service.Configuration;
@@ -36,6 +37,7 @@ var tests = new (string Name, Func<Task> Run)[]
("Parametr /debug włącza szczegółowe logowanie", DebugSwitchEnablesVerboseLogging),
("Parametr /verbose można wyłączyć", VerboseSwitchCanBeDisabled),
("Tryb szczegółowy jest przekazywany do adaptera", VerboseModeReachesAdapter),
("Rejestracja bazy przenosi parametry connection stringa", DatabaseRegistrationUsesConnectionString),
("Provider SQL działa na bieżącej platformie", SqlProviderIsSupported)
};
@@ -79,6 +81,69 @@ static Task SqlProviderIsSupported()
return Task.CompletedTask;
}
static Task DatabaseRegistrationUsesConnectionString()
{
var directory = new DirectoryInfo(AppContext.BaseDirectory);
string? installationPath = null;
while (directory is not null)
{
var candidate = Path.Combine(directory.FullName, "enova365 2604.4.4");
if (File.Exists(Path.Combine(candidate, "Soneta.Business.dll")))
{
installationPath = candidate;
break;
}
directory = directory.Parent;
}
if (installationPath is null)
{
throw new InvalidOperationException("Nie znaleziono lokalnej instalacji enova365 do testu adaptera.");
}
Assembly? ResolveSonetaAssembly(AssemblyLoadContext context, AssemblyName name)
{
var candidate = Path.Combine(installationPath, $"{name.Name}.dll");
return File.Exists(candidate) ? context.LoadFromAssemblyPath(candidate) : null;
}
AssemblyLoadContext.Default.Resolving += ResolveSonetaAssembly;
var adapterAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(
Path.Combine(AppContext.BaseDirectory, "SmartB2B.Enova.Adapter.dll"));
var adapterType = adapterAssembly.GetType("SmartB2B.Enova.Adapter.EnovaOrderAdapter", throwOnError: true)
?? throw new InvalidOperationException("Nie znaleziono typu adaptera Enovy.");
var parseConnectionString = adapterType.GetMethod(
"ParseSqlConnectionString",
BindingFlags.Static | BindingFlags.NonPublic)
?? throw new InvalidOperationException("Nie znaleziono metody analizującej connection string Enovy.");
object settings;
try
{
settings = parseConnectionString.Invoke(
null,
["Server=sql01;Database=Moms_Care;User ID=smartb2b;Password=haslo-sql;TrustServerCertificate=True"])
?? throw new InvalidOperationException("Adapter nie odczytał konfiguracji połączenia Enovy.");
}
catch (TargetInvocationException exception) when (exception.InnerException is not null)
{
throw exception.InnerException;
}
AssertEqual("sql01", GetProperty(settings, "DataSource"), "serwer SQL");
AssertEqual("Moms_Care", GetProperty(settings, "InitialCatalog"), "nazwa bazy SQL");
AssertEqual("smartb2b", GetProperty(settings, "UserID"), "użytkownik SQL");
AssertEqual("haslo-sql", GetProperty(settings, "Password"), "hasło SQL");
AssertEqual(false, GetProperty(settings, "IntegratedSecurity"), "uwierzytelnianie zintegrowane");
AssertEqual(true, GetProperty(settings, "TrustServerCertificate"), "zaufanie certyfikatowi SQL");
return Task.CompletedTask;
}
static object? GetProperty(object instance, string name) =>
instance.GetType().GetProperty(name)?.GetValue(instance)
?? throw new InvalidOperationException($"Nie znaleziono wartości właściwości '{name}'.");
static Task ValidFractionalDiscount()
{
AssertNoErrors(CreateValidRequest(12.5m));

View File

@@ -6,6 +6,7 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../../src/SmartB2B.Enova.Adapter/SmartB2B.Enova.Adapter.csproj" />
<ProjectReference Include="../../src/SmartB2B.Enova.Contracts/SmartB2B.Enova.Contracts.csproj" />
<ProjectReference Include="../../src/SmartB2B.Enova.Service/SmartB2B.Enova.Service.csproj" />
</ItemGroup>