Files
123123/ZA.CoreService.ESBCertificateManager/Services/SonicConncectionRepository.cs
T
2026-07-28 08:03:12 +02:00

333 lines
9.3 KiB
C#

using System.Data;
using Microsoft.Data.SqlClient;
using ZA.CoreService.ESBCertificateManager.Models;
namespace ZA.CoreService.ESBCertificateManager.Services;
public sealed class SonicConnectionRepository
{
private readonly string _connectionString;
public SonicConnectionRepository(
string connectionString)
{
if (string.IsNullOrWhiteSpace(connectionString))
{
throw new ArgumentException(
"Der SQL-Connection-String ist nicht konfiguriert.",
nameof(connectionString));
}
_connectionString = connectionString;
}
public async Task<IReadOnlyList<DatabaseSonicConnection>>
GetActiveAsync(
CancellationToken cancellationToken = default)
{
const string sql = """
SELECT
SonicConnectionId,
ConnectionName,
ManagementHost,
ManagementPort,
ConnectionProtocol,
DomainName,
CredentialUserName,
CredentialReference,
CredentialSecret,
JavaHomePath,
SonicHomePath,
Notes,
IsActive
FROM dbo.SonicConnection
WHERE IsActive = 1
ORDER BY ConnectionName;
""";
List<DatabaseSonicConnection> connections = [];
await using SqlConnection connection =
new(_connectionString);
await connection.OpenAsync(cancellationToken);
await using SqlCommand command =
new(sql, connection);
await using SqlDataReader reader =
await command.ExecuteReaderAsync(
cancellationToken);
int idOrdinal =
reader.GetOrdinal("SonicConnectionId");
int nameOrdinal =
reader.GetOrdinal("ConnectionName");
int hostOrdinal =
reader.GetOrdinal("ManagementHost");
int portOrdinal =
reader.GetOrdinal("ManagementPort");
int protocolOrdinal =
reader.GetOrdinal("ConnectionProtocol");
int domainOrdinal =
reader.GetOrdinal("DomainName");
int userNameOrdinal =
reader.GetOrdinal("CredentialUserName");
int credentialReferenceOrdinal =
reader.GetOrdinal("CredentialReference");
int credentialSecretOrdinal =
reader.GetOrdinal("CredentialSecret");
int javaHomeOrdinal =
reader.GetOrdinal("JavaHomePath");
int sonicHomeOrdinal =
reader.GetOrdinal("SonicHomePath");
int notesOrdinal =
reader.GetOrdinal("Notes");
int isActiveOrdinal =
reader.GetOrdinal("IsActive");
while (await reader.ReadAsync(cancellationToken))
{
connections.Add(
new DatabaseSonicConnection
{
Id = reader.GetInt32(idOrdinal),
Name =
reader.GetString(nameOrdinal),
ManagementHost =
reader.GetString(hostOrdinal),
ManagementPort =
ReadNullableInt32(
reader,
portOrdinal),
ConnectionProtocol =
ReadNullableString(
reader,
protocolOrdinal),
DomainName =
ReadNullableString(
reader,
domainOrdinal),
CredentialUserName =
ReadNullableString(
reader,
userNameOrdinal),
CredentialReference =
ReadNullableString(
reader,
credentialReferenceOrdinal),
CredentialSecret =
ReadNullableString(
reader,
credentialSecretOrdinal),
JavaHomePath =
ReadNullableString(
reader,
javaHomeOrdinal),
SonicHomePath =
ReadNullableString(
reader,
sonicHomeOrdinal),
Notes =
ReadNullableString(
reader,
notesOrdinal),
IsActive =
reader.GetBoolean(
isActiveOrdinal)
});
}
return connections;
}
public async Task SaveCredentialsAsync(
int sonicConnectionId,
string credentialUserName,
string credentialSecret,
CancellationToken cancellationToken = default)
{
if (sonicConnectionId <= 0)
{
throw new ArgumentOutOfRangeException(
nameof(sonicConnectionId),
"Die SonicConnectionId ist ungültig.");
}
if (string.IsNullOrWhiteSpace(
credentialUserName))
{
throw new ArgumentException(
"Der Sonic-Benutzername fehlt.",
nameof(credentialUserName));
}
if (string.IsNullOrEmpty(
credentialSecret))
{
throw new ArgumentException(
"Das Sonic-Kennwort fehlt.",
nameof(credentialSecret));
}
string normalizedUserName =
credentialUserName.Trim();
if (normalizedUserName.Length > 256)
{
throw new ArgumentException(
"Der Sonic-Benutzername darf maximal 256 Zeichen enthalten.",
nameof(credentialUserName));
}
if (credentialSecret.Length > 512)
{
throw new ArgumentException(
"Das Sonic-Kennwort darf maximal 512 Zeichen enthalten.",
nameof(credentialSecret));
}
const string sql = """
UPDATE dbo.SonicConnection
SET
CredentialUserName = @CredentialUserName,
CredentialSecret = @CredentialSecret,
UpdatedAtUtc = SYSUTCDATETIME()
WHERE SonicConnectionId = @SonicConnectionId
AND IsActive = 1;
""";
await using SqlConnection connection =
new(_connectionString);
await connection.OpenAsync(cancellationToken);
await using SqlCommand command =
new(sql, connection);
command.Parameters.Add(
new SqlParameter(
"@CredentialUserName",
SqlDbType.NVarChar,
256)
{
Value = normalizedUserName
});
command.Parameters.Add(
new SqlParameter(
"@CredentialSecret",
SqlDbType.NVarChar,
512)
{
Value = credentialSecret
});
command.Parameters.Add(
new SqlParameter(
"@SonicConnectionId",
SqlDbType.Int)
{
Value = sonicConnectionId
});
int affectedRows =
await command.ExecuteNonQueryAsync(
cancellationToken);
if (affectedRows != 1)
{
throw new InvalidOperationException(
"Die aktive Sonic-Verbindung wurde nicht eindeutig gefunden.");
}
}
public async Task ClearCredentialsAsync(
int sonicConnectionId,
CancellationToken cancellationToken = default)
{
if (sonicConnectionId <= 0)
{
throw new ArgumentOutOfRangeException(
nameof(sonicConnectionId),
"Die SonicConnectionId ist ungültig.");
}
const string sql = """
UPDATE dbo.SonicConnection
SET
CredentialUserName = NULL,
CredentialSecret = NULL,
UpdatedAtUtc = SYSUTCDATETIME()
WHERE SonicConnectionId = @SonicConnectionId;
""";
await using SqlConnection connection =
new(_connectionString);
await connection.OpenAsync(cancellationToken);
await using SqlCommand command =
new(sql, connection);
command.Parameters.Add(
new SqlParameter(
"@SonicConnectionId",
SqlDbType.Int)
{
Value = sonicConnectionId
});
int affectedRows =
await command.ExecuteNonQueryAsync(
cancellationToken);
if (affectedRows != 1)
{
throw new InvalidOperationException(
"Die Sonic-Verbindung wurde nicht eindeutig gefunden.");
}
}
private static string? ReadNullableString(
SqlDataReader reader,
int ordinal)
{
return reader.IsDBNull(ordinal)
? null
: reader.GetString(ordinal);
}
private static int? ReadNullableInt32(
SqlDataReader reader,
int ordinal)
{
return reader.IsDBNull(ordinal)
? null
: reader.GetInt32(ordinal);
}
}