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);
}
}
}