using System.Data; using Microsoft.Data.SqlClient; using ZA.CoreService.ESBCertificateManager.Models; namespace ZA.CoreService.ESBCertificateManager.Services; public sealed class DeploymentTargetRepository { private readonly string _connectionString; public DeploymentTargetRepository(string connectionString) { if (string.IsNullOrWhiteSpace(connectionString)) { throw new ArgumentException( "Der SQL-Connection-String ist nicht konfiguriert.", nameof(connectionString)); } _connectionString = connectionString; } public async Task> GetActiveAsync( string environmentCode, CancellationToken cancellationToken = default) { if (string.IsNullOrWhiteSpace(environmentCode)) { throw new ArgumentException( "Der EnvironmentCode fehlt.", nameof(environmentCode)); } const string sql = """ SELECT target.[CertificateTargetId], target.[TargetDirectory], target.[TargetFileName], target.[BackupEnabled], target.[BackupDirectoryName], target.[IsActive] AS [TargetIsActive], container.[SonicContainerId], container.[ContainerName], container.[ContainerDisplayName], container.[CertificateCheckUrl], container.[RestartTimeoutSeconds], connection.[ConnectionName], environment.[EnvironmentCode], environment.[SortOrder] AS [EnvironmentSortOrder], company.[CompanyCode] FROM [dbo].[CertificateTarget] AS target INNER JOIN [dbo].[SonicContainer] AS container ON container.[SonicContainerId] = target.[SonicContainerId] INNER JOIN [dbo].[SonicConnection] AS connection ON connection.[SonicConnectionId] = container.[SonicConnectionId] INNER JOIN [dbo].[Environment] AS environment ON environment.[EnvironmentId] = connection.[EnvironmentId] INNER JOIN [dbo].[Company] AS company ON company.[CompanyId] = container.[CompanyId] WHERE target.[IsActive] = 1 AND container.[IsActive] = 1 AND connection.[IsActive] = 1 AND company.[IsActive] = 1 AND environment.[IsActive] = 1 AND environment.[EnvironmentCode] = @EnvironmentCode ORDER BY company.[CompanyCode], environment.[SortOrder], container.[ContainerName], target.[TargetDirectory], target.[TargetFileName]; """; List targets = []; await using SqlConnection connection = new(_connectionString); await connection.OpenAsync(cancellationToken); await using SqlCommand command = new(sql, connection); command.Parameters.Add( new SqlParameter( "@EnvironmentCode", SqlDbType.NVarChar, 30) { Value = environmentCode .Trim() .ToUpperInvariant() }); await using SqlDataReader reader = await command.ExecuteReaderAsync(cancellationToken); int targetIdOrdinal = reader.GetOrdinal("CertificateTargetId"); int targetDirectoryOrdinal = reader.GetOrdinal("TargetDirectory"); int targetFileNameOrdinal = reader.GetOrdinal("TargetFileName"); int backupEnabledOrdinal = reader.GetOrdinal("BackupEnabled"); int backupDirectoryNameOrdinal = reader.GetOrdinal("BackupDirectoryName"); int targetIsActiveOrdinal = reader.GetOrdinal("TargetIsActive"); int containerNameOrdinal = reader.GetOrdinal("ContainerName"); int containerDisplayNameOrdinal = reader.GetOrdinal("ContainerDisplayName"); int certificateCheckUrlOrdinal = reader.GetOrdinal("CertificateCheckUrl"); int restartTimeoutOrdinal = reader.GetOrdinal("RestartTimeoutSeconds"); int connectionNameOrdinal = reader.GetOrdinal("ConnectionName"); int environmentCodeOrdinal = reader.GetOrdinal("EnvironmentCode"); int environmentSortOrderOrdinal = reader.GetOrdinal("EnvironmentSortOrder"); int companyCodeOrdinal = reader.GetOrdinal("CompanyCode"); while (await reader.ReadAsync(cancellationToken)) { string containerName = reader.GetString(containerNameOrdinal); string? containerDisplayName = ReadNullableString( reader, containerDisplayNameOrdinal); string? certificateCheckUrl = ReadNullableString( reader, certificateCheckUrlOrdinal); string companyCode = reader.GetString(companyCodeOrdinal); string displayName = string.IsNullOrWhiteSpace(containerDisplayName) ? containerName : containerDisplayName; string tlsHost = string.Empty; int? tlsPort = null; string tlsServerName = string.Empty; if (TlsEndpointProbeService.TryParseEndpoint( certificateCheckUrl, out string host, out int port, out string serverName, out _)) { tlsHost = host; tlsPort = port; tlsServerName = serverName; } targets.Add(new DeploymentTarget { Id = reader.GetInt32(targetIdOrdinal), Name = $"{companyCode} / {displayName}", Environment = reader.GetString(environmentCodeOrdinal), IsActive = reader.GetBoolean(targetIsActiveOrdinal), TargetDirectory = reader.GetString(targetDirectoryOrdinal), CertificateFileName = reader.GetString(targetFileNameOrdinal), BackupEnabled = reader.GetBoolean(backupEnabledOrdinal), BackupDirectoryName = reader.GetString(backupDirectoryNameOrdinal), BackupRetentionDays = null, ContainerName = containerName, RestartType = RestartType.SonicContainer, SonicConnectionName = reader.GetString(connectionNameOrdinal), RestartTimeoutSeconds = reader.GetInt32(restartTimeoutOrdinal), TlsHost = tlsHost, TlsPort = tlsPort, TlsServerName = tlsServerName, ExpectedFingerprint = null, SortOrder = reader.GetInt32(environmentSortOrderOrdinal) }); } return targets; } private static string? ReadNullableString( SqlDataReader reader, int ordinal) { return reader.IsDBNull(ordinal) ? null : reader.GetString(ordinal); } }