< Summary

Information
Class: Services.ApiServices.DatabaseHealthChecker
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ApiServices/DatabaseHealthChecker.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 108
Coverable lines: 108
Total lines: 189
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 46
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
CheckAndPrintDatabaseHealthAsync()0%2040%
CheckDbContextAsync()0%2040%
ExtractConnectionInfo(...)0%1190340%
PrintResults(...)0%2040%
get_ConnectionName()100%210%
get_Server()100%210%
get_Database()100%210%
get_Status()100%210%
get_StatusColor()100%210%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ApiServices/DatabaseHealthChecker.cs

#LineLine coverage
 1using System.Data.Common;
 2using Microsoft.EntityFrameworkCore;
 3using Microsoft.Extensions.Configuration;
 4using Microsoft.Extensions.DependencyInjection;
 5using OzonRepositories.Context;
 6using OzonRepositories.Context.Identity;
 7
 8namespace Services.ApiServices;
 9
 10public class DatabaseHealthChecker
 11{
 12    private readonly IServiceProvider _serviceProvider;
 13    private readonly IConfiguration _configuration;
 14    private readonly bool _isProd;
 15
 016    public DatabaseHealthChecker(
 017        IServiceProvider serviceProvider,
 018        IConfiguration configuration,
 019        bool isProd)
 20    {
 021        _serviceProvider = serviceProvider;
 022        _configuration = configuration;
 023        _isProd = isProd;
 024    }
 25
 26    public async Task CheckAndPrintDatabaseHealthAsync()
 27    {
 028        var results = new List<DatabaseHealthResult>();
 29
 30        // Проверка ApplicationDbContext
 031        await CheckDbContextAsync<ApplicationDbContext>(
 032            results,
 033            "ApplicationDbContext",
 034            _isProd ? "MySqlConnectionProd" : "MySqlConnectionLocal");
 35
 36        // Проверка OzonIdentityOrderContext (использует тот же connection string)
 037        await CheckDbContextAsync<OzonIdentityOrderContext>(
 038            results,
 039            "OzonIdentityOrderContext",
 040            _isProd ? "MySqlConnectionProd" : "MySqlConnectionLocal");
 41
 42        // Проверка BitrixContext
 043        await CheckDbContextAsync<BitrixContext>(
 044            results,
 045            "BitrixContext",
 046            "BitrixConnectionProd");
 47
 48        // Проверка JcEtalonContext
 049        await CheckDbContextAsync<JcEtalonContext>(
 050            results,
 051            "JcEtalonContext",
 052            "JcEtalonConnectionProd");
 53
 54        // Проверка OzonApiContext (каталог ozon_products)
 055        await CheckDbContextAsync<OzonApiContext>(
 056            results,
 057            "OzonApiContext",
 058            "OzonApiConnectionProd");
 59
 60        // Вывод результатов в консоль
 061        PrintResults(results);
 062    }
 63
 64    private async Task CheckDbContextAsync<TContext>(
 65        List<DatabaseHealthResult> results,
 66        string contextName,
 67        string connectionStringName) where TContext : DbContext
 68    {
 069        var connectionString = _configuration.GetConnectionString(connectionStringName);
 70
 071        if (string.IsNullOrWhiteSpace(connectionString))
 72        {
 073            results.Add(new DatabaseHealthResult
 074            {
 075                ConnectionName = contextName,
 076                Server = "N/A",
 077                Database = "N/A",
 078                Status = "Не настроен",
 079                StatusColor = false
 080            });
 081            return;
 82        }
 83
 84        try
 85        {
 86            // Извлекаем информацию о сервере и базе данных из connection string
 087            var (server, database) = ExtractConnectionInfo(connectionString);
 88
 89            // Проверяем соединение через DbContext
 090            using var scope = _serviceProvider.CreateScope();
 091            var context = scope.ServiceProvider.GetRequiredService<TContext>();
 92
 93            // Используем таймаут для проверки соединения
 094            using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
 095            var canConnect = await context.Database.CanConnectAsync(cts.Token);
 96
 097            results.Add(new DatabaseHealthResult
 098            {
 099                ConnectionName = contextName,
 0100                Server = server,
 0101                Database = database,
 0102                Status = canConnect ? "Успешно" : "Ошибка",
 0103                StatusColor = canConnect
 0104            });
 0105        }
 0106        catch (Exception ex)
 107        {
 0108            var (server, database) = ExtractConnectionInfo(connectionString);
 0109            results.Add(new DatabaseHealthResult
 0110            {
 0111                ConnectionName = contextName,
 0112                Server = server,
 0113                Database = database,
 0114                Status = $"Ошибка: {ex.Message.Substring(0, Math.Min(30, ex.Message.Length))}...",
 0115                StatusColor = false
 0116            });
 0117        }
 0118    }
 119
 120    private (string Server, string Database) ExtractConnectionInfo(string connectionString)
 121    {
 122        try
 123        {
 124            // Используем DbConnectionStringBuilder для парсинга connection string
 0125            var builder = new DbConnectionStringBuilder { ConnectionString = connectionString };
 126
 0127            string server = "N/A";
 0128            string database = "N/A";
 129
 130            // Пробуем разные варианты ключей для сервера
 0131            if (builder.ContainsKey("Server"))
 0132                server = builder["Server"]?.ToString() ?? "N/A";
 0133            else if (builder.ContainsKey("Data Source"))
 0134                server = builder["Data Source"]?.ToString() ?? "N/A";
 0135            else if (builder.ContainsKey("Host"))
 0136                server = builder["Host"]?.ToString() ?? "N/A";
 137
 138            // Пробуем разные варианты ключей для базы данных
 0139            if (builder.ContainsKey("Database"))
 0140                database = builder["Database"]?.ToString() ?? "N/A";
 0141            else if (builder.ContainsKey("Initial Catalog"))
 0142                database = builder["Initial Catalog"]?.ToString() ?? "N/A";
 143
 144            // Ограничиваем длину для отображения
 0145            if (server.Length > 25)
 0146                server = server.Substring(0, 22) + "...";
 0147            if (database.Length > 20)
 0148                database = database.Substring(0, 17) + "...";
 149
 0150            return (server, database);
 151        }
 0152        catch
 153        {
 0154            return ("N/A", "N/A");
 155        }
 0156    }
 157
 158    private void PrintResults(List<DatabaseHealthResult> results)
 159    {
 0160        Console.WriteLine("\n╔══════════════════════════════════════════════════════════════════════════════════════════
 0161        Console.WriteLine("║                                  ПРОВЕРКА ПОДКЛЮЧЕНИЙ К БАЗАМ ДАННЫХ                       
 0162        Console.WriteLine("╠════════════════════════════════════════════════════════════════════════════════════════════
 0163        Console.WriteLine("║Имя подключения                    │Сервер                    │База данных            │Стату
 0164        Console.WriteLine("╠════════════════════════════════════════════════════════════════════════════════════════════
 165
 0166        foreach (var result in results)
 167        {
 0168            string connectionName = result.ConnectionName.PadRight(35).Substring(0, 35);
 0169            string server = result.Server.PadRight(25).Substring(0, 25);
 0170            string database = result.Database.PadRight(22).Substring(0, 22);
 0171            string status = result.Status.PadRight(9).Substring(0, 9);
 172
 0173            string colorCode = result.StatusColor ? "\x1b[32m" : "\x1b[31m";
 0174            Console.WriteLine($"║{connectionName}│{server}│{database}│{colorCode}{status}\x1b[0m║");
 175        }
 176
 0177        Console.WriteLine("╚════════════════════════════════════════════════════════════════════════════════════════════
 0178    }
 179
 180    private class DatabaseHealthResult
 181    {
 0182        public string ConnectionName { get; set; } = string.Empty;
 0183        public string Server { get; set; } = string.Empty;
 0184        public string Database { get; set; } = string.Empty;
 0185        public string Status { get; set; } = string.Empty;
 0186        public bool StatusColor { get; set; }
 187    }
 188}
 189