using JdeScoping.DataAccess.Exceptions; using JdeScoping.DataAccess.Interfaces; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Oracle.ManagedDataAccess.Client; namespace JdeScoping.DataAccess; /// /// Factory for creating database connections to all data sources. /// public class DbConnectionFactory : IDbConnectionFactory { private readonly IConfiguration _configuration; private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// Application configuration. /// Logger instance. public DbConnectionFactory(IConfiguration configuration, ILogger logger) { _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } /// public async Task CreateLotFinderConnectionAsync(CancellationToken ct = default) { const string dataSource = "LotFinderDB"; var connectionString = _configuration.GetConnectionString(dataSource); if (string.IsNullOrEmpty(connectionString)) { throw new ConnectionException( $"{dataSource}: Connection string not found in configuration.", dataSource); } try { _logger.LogDebug("Creating connection to {DataSource}", dataSource); var connection = new SqlConnection(connectionString); await connection.OpenAsync(ct).ConfigureAwait(false); _logger.LogDebug("Successfully connected to {DataSource}", dataSource); return connection; } catch (OperationCanceledException) { throw; } catch (Exception ex) { using (_logger.BeginScope(new Dictionary { ["DataSource"] = dataSource, ["Operation"] = "CreateConnection" })) { _logger.LogError(ex, "Failed to connect to {DataSource}", dataSource); } throw new ConnectionException( $"{dataSource}: Failed to open connection to database.", dataSource, ex); } } /// public async Task CreateJdeConnectionAsync(CancellationToken ct = default) { return await CreateOracleConnectionAsync("JDE", ct).ConfigureAwait(false); } /// public async Task CreateJdeStageConnectionAsync(CancellationToken ct = default) { return await CreateOracleConnectionAsync("JDEStage", ct).ConfigureAwait(false); } /// public async Task CreateCmsConnectionAsync(CancellationToken ct = default) { return await CreateOracleConnectionAsync("CMS", ct).ConfigureAwait(false); } /// public async Task CreateGiwConnectionAsync(CancellationToken ct = default) { return await CreateOracleConnectionAsync("GIW", ct).ConfigureAwait(false); } private async Task CreateOracleConnectionAsync(string dataSource, CancellationToken ct) { var connectionString = _configuration.GetConnectionString(dataSource); if (string.IsNullOrEmpty(connectionString)) { throw new ConnectionException( $"{dataSource}: Connection string not found in configuration.", dataSource); } try { _logger.LogDebug("Creating connection to {DataSource}", dataSource); var connection = new OracleConnection(connectionString); await connection.OpenAsync(ct).ConfigureAwait(false); _logger.LogDebug("Successfully connected to {DataSource}", dataSource); return connection; } catch (OperationCanceledException) { throw; } catch (Exception ex) { using (_logger.BeginScope(new Dictionary { ["DataSource"] = dataSource, ["Operation"] = "CreateConnection" })) { _logger.LogError(ex, "Failed to connect to {DataSource}", dataSource); } throw new ConnectionException( $"{dataSource}: Failed to open connection to database.", dataSource, ex); } } }