From f6fef62bddb6c948b0186dad4f39e5662983f7cc Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Mon, 13 Jul 2026 11:39:36 +0200 Subject: [PATCH] =?UTF-8?q?Script-Check-Bug=20behoben:=20CheckDBScripts=20?= =?UTF-8?q?pr=C3=BCft=20jetzt=20alle=20registrierten=20Scripts,=20nicht=20?= =?UTF-8?q?nur=20das=20erste.=20Alle=20vier=20Check-Methoden=20sind=20auf?= =?UTF-8?q?=20das=20gleiche=20Muster=20umgestellt=20(Where=20auf=20Fehler?= =?UTF-8?q?=20filtern,=20Meldungen=20mit=20;=20joinen),=20d.h.=20sie=20mel?= =?UTF-8?q?den=20jetzt=20auch=20jeweils=20alle=20fehlenden=20Eintr=C3=A4ge?= =?UTF-8?q?=20ihrer=20Kategorie=20statt=20nur=20den=20ersten.=20Alle=20Feh?= =?UTF-8?q?ler=20sammeln:=20DoHealthCheckup=20bricht=20nicht=20mehr=20beim?= =?UTF-8?q?=20ersten=20Fehler=20ab,=20sondern=20sammelt=20die=20Meldungen?= =?UTF-8?q?=20aller=20Checkups=20und=20gibt=20sie=20zusammen=20in=20Messag?= =?UTF-8?q?e=20zur=C3=BCck.=20Exception-Logging:=20Wirft=20ein=20Checkup?= =?UTF-8?q?=20eine=20Exception,=20wird=20sie=20jetzt=20vollst=C3=A4ndig=20?= =?UTF-8?q?per=20log4net=20geloggt=20(gleiches=20Idiom=20wie=20im=20WCFErr?= =?UTF-8?q?orHandler=20=C3=BCber=20LoggerUtils.GetLogger);=20nach=20au?= =?UTF-8?q?=C3=9Fen=20geht=20weiterhin=20nur=20ex.Message.=20Listen=20dire?= =?UTF-8?q?kt=20initialisiert=20statt=20Lazy-Init=20=E2=80=94=20alle=20is?= =?UTF-8?q?=20null-Checks=20entfallen,=20die=20Add*-Methoden=20sind=20jetz?= =?UTF-8?q?t=20Einzeiler.=20Naming=20auf=20PascalCase=20vereinheitlicht=20?= =?UTF-8?q?(AddWebConfigCheck,=20RegisterCheckup,=20CheckDBScripts,=20?= =?UTF-8?q?=E2=80=A6)=20und=20ungenutzte=20Usings=20entfernt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Enhanced/StatusServiceImp.cs | 18 +-- Service/Status/AiStatusService.cs | 13 +- Service/Status/BaseStatusService.cs | 145 +++++++----------- Service/Status/DatenbankStatusService.cs | 13 +- Service/Status/GeneralStatusService.cs | 11 +- 5 files changed, 68 insertions(+), 132 deletions(-) diff --git a/Service/ServiceImplementations/Enhanced/StatusServiceImp.cs b/Service/ServiceImplementations/Enhanced/StatusServiceImp.cs index ae1a40b31..b4ce42dfd 100644 --- a/Service/ServiceImplementations/Enhanced/StatusServiceImp.cs +++ b/Service/ServiceImplementations/Enhanced/StatusServiceImp.cs @@ -1,8 +1,3 @@ -using BeWo.Data.Access; -using BeWo.Data.Entities; -using BeWo.Service.AI; -using BeWo.Service.Attributes; -using BeWo.Service.Core; using BeWo.Service.ServiceContracts.Enhanced; using BeWo.Service.Status; using BS.Shared; @@ -10,14 +5,11 @@ using BS.Shared.Core; using BS.Shared.DataContracts; using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.ServiceModel; using System.ServiceModel.Web; -using System.Text; -using System.Threading.Tasks; namespace BeWo.Service.ServiceImplementations.Enhanced { @@ -40,8 +32,14 @@ namespace BeWo.Service.ServiceImplementations.Enhanced result.DatabaseOk = new DatenbankStatusService().DoHealthCheckup(); // Einzelne Subsysteme prüfen - result.Services.Add(new GeneralStatusService().DoHealthCheckup()); - result.Services.Add(new AiStatusService().DoHealthCheckup()); + var statusServices = new List + { + new GeneralStatusService(), + new AiStatusService() + }; + + foreach (var service in statusServices) + result.Services.Add(service.DoHealthCheckup()); var allHealthy = result.DatabaseOk.IsOk && result.Services.All(x => x.IsOk); if (!allHealthy) diff --git a/Service/Status/AiStatusService.cs b/Service/Status/AiStatusService.cs index 2d1e03cd0..341735dba 100644 --- a/Service/Status/AiStatusService.cs +++ b/Service/Status/AiStatusService.cs @@ -1,23 +1,16 @@ -using BeWo.Service.Core; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - namespace BeWo.Service.Status { public class AiStatusService : BaseStatusService { public AiStatusService() : base("AI") { - addWebConfigCheck(WebConfigSetting.OllamaUrl, + AddWebConfigCheck(WebConfigSetting.OllamaUrl, WebConfigSetting.Ollama2Url, WebConfigSetting.AiPromptsUrl); - addWebSecretConfigCheck(WebSecretConfigSetting.Ollama2Key); + AddWebSecretConfigCheck(WebSecretConfigSetting.Ollama2Key); - addDBScript("Changes_2026-05-22 AiConv ActionType", + AddDBScript("Changes_2026-05-22 AiConv ActionType", "Changes_2026-06-03 AiRoutine RoutineType", "Changes_2026-06-18 AiModel default updaten", "Changes_2026-07-08 AiConversation Promptreferenz", diff --git a/Service/Status/BaseStatusService.cs b/Service/Status/BaseStatusService.cs index 314e427f0..db9af14d4 100644 --- a/Service/Status/BaseStatusService.cs +++ b/Service/Status/BaseStatusService.cs @@ -1,165 +1,124 @@ -using BeWo.Data.Access; +using BeWo.Data.Access; +using BeWo.ServerUtils.Core; using BeWo.Service.Core; using BS.Shared.DataContracts; using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BeWo.Service.Status { public class BaseStatusService { + private static readonly log4net.ILog log = LoggerUtils.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + protected string Name { get; set; } - protected List> Checkups { get; set; } + protected List> Checkups { get; } = new List>(); - private List RequiredWebConfigs { get; set; } - private List RequiredWebSecretConfigs { get; set; } - private List RequiredDBScripts { get; set; } - private List RequiredConfigs { get; set; } + private List RequiredWebConfigs { get; } = new List(); + private List RequiredWebSecretConfigs { get; } = new List(); + private List RequiredDBScripts { get; } = new List(); + private List RequiredConfigs { get; } = new List(); public BaseStatusService(string name) { Name = name; - registerCheckup(checkWebConfig, - checkWebSecretConfig, - checkDBScripts, - checkConfig); + RegisterCheckup(CheckWebConfig, + CheckWebSecretConfig, + CheckDBScripts, + CheckConfig); } - protected void addWebConfigCheck(params WebConfigSetting[] args) + protected void AddWebConfigCheck(params WebConfigSetting[] args) { - if(RequiredWebConfigs is null) - RequiredWebConfigs = new List(); - RequiredWebConfigs.AddRange(args); } - - protected void addWebSecretConfigCheck(params WebSecretConfigSetting[] args) - { - if(RequiredWebSecretConfigs is null) - RequiredWebSecretConfigs = new List(); + protected void AddWebSecretConfigCheck(params WebSecretConfigSetting[] args) + { RequiredWebSecretConfigs.AddRange(args); } - protected void addDBScript(params string[] args) + protected void AddDBScript(params string[] args) { - if(RequiredDBScripts is null) - RequiredDBScripts = new List(); - RequiredDBScripts.AddRange(args); } - - protected void addCustomConfig(params SpecialConfig[] args) - { - if(RequiredConfigs is null) - RequiredConfigs = new List(); + protected void AddCustomConfig(params SpecialConfig[] args) + { RequiredConfigs.AddRange(args); } - protected void registerCheckup(params Func[] args) + protected void RegisterCheckup(params Func[] args) { - if (Checkups is null) - Checkups = new List>(); - Checkups.AddRange(args); } public ServiceStatusDC DoHealthCheckup() { - string error = string.Empty; - bool ok = true; + var errors = new List(); foreach (var func in Checkups) { try { - error = func(); + var error = func(); + + if (!string.IsNullOrEmpty(error)) + errors.Add(error); } - catch(Exception ex) + catch (Exception ex) { - error = ex.Message; + log.Error($"Health-Checkup '{Name}' fehlgeschlagen", ex); + errors.Add(ex.Message); } - - ok = string.IsNullOrEmpty(error); - - if (!ok) - break; } return new ServiceStatusDC { Name = Name, - IsOk = ok, - Message = ok ? "OK" : error + IsOk = errors.Count == 0, + Message = errors.Count == 0 ? "OK" : string.Join("; ", errors) }; } - private string checkWebConfig() + private string CheckWebConfig() { - if (RequiredWebConfigs is null) - return null; + var missing = RequiredWebConfigs + .Where(x => string.IsNullOrWhiteSpace(MergedConfig.GetSetting(x))) + .Select(x => $"'{x}' wurde nicht korrekt konfiguriert"); - foreach (var webConfig in RequiredWebConfigs) - { - var url = MergedConfig.GetSetting(webConfig); - if (string.IsNullOrWhiteSpace(url)) - return $"'{webConfig}' wurde nicht korrekt konfiguriert"; - } - - return null; + return string.Join("; ", missing); } - private string checkWebSecretConfig() + private string CheckWebSecretConfig() { - if (RequiredWebSecretConfigs is null) - return null; + var missing = RequiredWebSecretConfigs + .Where(x => string.IsNullOrWhiteSpace(MergedConfig.GetSecretSetting(x))) + .Select(x => $"'{x}' wurde nicht korrekt konfiguriert"); - foreach (var webSecretConfig in RequiredWebSecretConfigs) - { - var key = MergedConfig.GetSecretSetting(webSecretConfig); - if (string.IsNullOrWhiteSpace(key)) - return $"'{webSecretConfig}' wurde nicht korrekt konfiguriert"; - } - - return null; - } - - private string checkDBScripts() - { - if (RequiredDBScripts is null) - return null; - - foreach (var script in RequiredDBScripts) - { - var executed = DAOFactory.ScriptDAO.IsScriptExecuted(script); - - return executed ? null : $"Script '{script}' wurde nicht ausgeführt"; - } - - return null; + return string.Join("; ", missing); } - private string checkConfig() + private string CheckDBScripts() { - if (RequiredConfigs is null) - return null; + var missing = RequiredDBScripts + .Where(x => !DAOFactory.ScriptDAO.IsScriptExecuted(x)) + .Select(x => $"Script '{x}' wurde nicht ausgeführt"); - foreach (var config in RequiredConfigs) - { - var configPath = ConfigReader.GetConfigPath(config); + return string.Join("; ", missing); + } - if (!File.Exists(configPath)) - return $"SpecialConfig.{config} wurde nicht korrekt konfiguriert"; - } + private string CheckConfig() + { + var missing = RequiredConfigs + .Where(x => !File.Exists(ConfigReader.GetConfigPath(x))) + .Select(x => $"SpecialConfig.{x} wurde nicht korrekt konfiguriert"); - return null; + return string.Join("; ", missing); } } } diff --git a/Service/Status/DatenbankStatusService.cs b/Service/Status/DatenbankStatusService.cs index ddae73a25..3faa0a723 100644 --- a/Service/Status/DatenbankStatusService.cs +++ b/Service/Status/DatenbankStatusService.cs @@ -1,10 +1,5 @@ -using BeWo.Data.Access; +using BeWo.Data.Access; using BeWo.Data.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BeWo.Service.Status { @@ -12,13 +7,13 @@ namespace BeWo.Service.Status { public DatenbankStatusService() : base("Datenbank") { - registerCheckup(CheckDatenbank); + RegisterCheckup(CheckDatenbank); } private string CheckDatenbank() { - // Leichter DB-Ping – z.B. eine einfache Abfrage über DAOFactory - DAOFactory.GenericDAO.GetAll(); + // Leichter DB-Ping – COUNT-Abfrage statt Laden aller Datensätze + DAOFactory.GenericDAO.Any(); return null; } diff --git a/Service/Status/GeneralStatusService.cs b/Service/Status/GeneralStatusService.cs index 125880fc6..7620b20aa 100644 --- a/Service/Status/GeneralStatusService.cs +++ b/Service/Status/GeneralStatusService.cs @@ -1,19 +1,10 @@ -using BeWo.Data.Access; -using BeWo.Data.Entities; -using BS.Shared.DataContracts; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - namespace BeWo.Service.Status { public class GeneralStatusService : BaseStatusService { public GeneralStatusService() : base("Allgemein") { - addWebSecretConfigCheck(WebSecretConfigSetting.AppStatusApiKey); + AddWebSecretConfigCheck(WebSecretConfigSetting.AppStatusApiKey); } } }