From a43a57468a4bd9b236d1b4fc70ae743c04ddde75 Mon Sep 17 00:00:00 2001 From: DarkDerte <160210611+DarkDerte@users.noreply.github.com> Date: Thu, 22 Jan 2026 22:54:32 +0100 Subject: [PATCH 1/2] Added MqttModule Refactor and delete IConfigContext --- .../ServiceHub.Modules.MQTT/MqttModule.cs | 48 +++++++++++++++++++ .../ServiceHub.Modules.MQTT.csproj | 17 +++++++ .../StaticWebModule.cs | 10 ++-- .../Interfaces/IConfigContext.cs | 13 ----- .../Interfaces/IServiceContext.cs | 20 ++++++++ .../Interfaces/IServiceModule.cs | 2 +- .../ServiceHub.Core/Classes/SimpleContext.cs | 34 +++++++++---- .../ServiceHub.Core/Model/ServiceInstance.cs | 10 ++-- ServiceHub/ServiceHub.Core/ServiceHub.cs | 4 +- ServiceHub/ServiceHub.Host/Program.cs | 14 ++++-- ServiceHub/ServiceHub.slnx | 1 + 11 files changed, 134 insertions(+), 39 deletions(-) create mode 100644 ServiceHub/Modules/ServiceHub.Modules.MQTT/MqttModule.cs create mode 100644 ServiceHub/Modules/ServiceHub.Modules.MQTT/ServiceHub.Modules.MQTT.csproj delete mode 100644 ServiceHub/ServiceHub.Contracts/Interfaces/IConfigContext.cs create mode 100644 ServiceHub/ServiceHub.Contracts/Interfaces/IServiceContext.cs diff --git a/ServiceHub/Modules/ServiceHub.Modules.MQTT/MqttModule.cs b/ServiceHub/Modules/ServiceHub.Modules.MQTT/MqttModule.cs new file mode 100644 index 0000000..e0351e8 --- /dev/null +++ b/ServiceHub/Modules/ServiceHub.Modules.MQTT/MqttModule.cs @@ -0,0 +1,48 @@ +using MQTTnet.Diagnostics.Logger; +using MQTTnet.Server; +using ServiceHub.Contracts.Enums; +using ServiceHub.Contracts.Interfaces; + +namespace ServiceHub.Modules.MQTT +{ + public class MqttModule : IServiceModule + { + private MqttServer? _server = null; + private ILogContext? _log = null; + + public string Name => "MqttModule"; + + + public void Initialize(ILogContext log, IServiceContext config) + { + _log = log; + throw new NotImplementedException(); + } + + public Task StartAsync(CancellationToken token) + { + Stop(); + + var logger = new MqttNetEventLogger(); + + logger.LogMessagePublished += (o, e) => + { + switch (e.LogMessage.Level) + { + case MqttNetLogLevel.Error: _log?.Error(e.LogMessage.Message); break; + case MqttNetLogLevel.Warning: _log?.Warning(e.LogMessage.Message); break; + case MqttNetLogLevel.Info: + case MqttNetLogLevel.Verbose: _log?.Info(e.LogMessage.Message); break; + } + }; + + _server = new MqttServerFactory(logger).CreateMqttServer(new MqttServerOptions()); + + return _server.StartAsync(); + } + + public ServiceState State() => (_server?.IsStarted ?? false ) ? ServiceState.Running : ServiceState.Stoped; + + public void Stop() => _server?.StopAsync().Wait(); + } +} diff --git a/ServiceHub/Modules/ServiceHub.Modules.MQTT/ServiceHub.Modules.MQTT.csproj b/ServiceHub/Modules/ServiceHub.Modules.MQTT/ServiceHub.Modules.MQTT.csproj new file mode 100644 index 0000000..c10761d --- /dev/null +++ b/ServiceHub/Modules/ServiceHub.Modules.MQTT/ServiceHub.Modules.MQTT.csproj @@ -0,0 +1,17 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + diff --git a/ServiceHub/Modules/ServiceHub.Modules.StaticWeb/StaticWebModule.cs b/ServiceHub/Modules/ServiceHub.Modules.StaticWeb/StaticWebModule.cs index 122808e..5e3c2fd 100644 --- a/ServiceHub/Modules/ServiceHub.Modules.StaticWeb/StaticWebModule.cs +++ b/ServiceHub/Modules/ServiceHub.Modules.StaticWeb/StaticWebModule.cs @@ -14,17 +14,17 @@ public class StaticWebModule : IServiceModule private WebServer? _server; private CancellationToken _token; private ILogContext? _logContext; - private IConfigContext? _configContext; + private IServiceContext? _configContext; public string Name => "StaticWebModule"; - public void Initialize(ILogContext log, IConfigContext config) + public void Initialize(ILogContext log, IServiceContext config) { _logContext = log; _configContext = config; - var port = _configContext.Get("port") ?? "8080"; - var root = _configContext.Get("directory") ?? "wwwroot"; + var port = _configContext.Get("parameters:port") ?? "8080"; + var root = _configContext.Get("parameters:directory") ?? "wwwroot"; _port = int.Parse(port); _directory = root; @@ -34,6 +34,8 @@ public void Initialize(ILogContext log, IConfigContext config) public async Task StartAsync(CancellationToken token) { + Stop(); + _token = token; var fileProvider = new PhysicalFileProvider(_directory); diff --git a/ServiceHub/ServiceHub.Contracts/Interfaces/IConfigContext.cs b/ServiceHub/ServiceHub.Contracts/Interfaces/IConfigContext.cs deleted file mode 100644 index f9b6f38..0000000 --- a/ServiceHub/ServiceHub.Contracts/Interfaces/IConfigContext.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace ServiceHub.Contracts.Interfaces -{ - public interface IConfigContext - { - string? Get(string path); - - IConfigContext? GetConfig(string path); - - string? Value { get; } - - IConfigContext[] Items { get; } - } -} diff --git a/ServiceHub/ServiceHub.Contracts/Interfaces/IServiceContext.cs b/ServiceHub/ServiceHub.Contracts/Interfaces/IServiceContext.cs new file mode 100644 index 0000000..182d3b6 --- /dev/null +++ b/ServiceHub/ServiceHub.Contracts/Interfaces/IServiceContext.cs @@ -0,0 +1,20 @@ +using ServiceHub.Contracts.Classes; +using System.Text.Json; + +namespace ServiceHub.Contracts.Interfaces +{ + public interface IServiceContext + { + string? Value { get; } + + void SetNode(string path); + + IServiceContext[] Items { get; } + + void LoadJson(string json); + + string? Get(string path); + + IServiceContext? GetConfig(string path); + } +} diff --git a/ServiceHub/ServiceHub.Contracts/Interfaces/IServiceModule.cs b/ServiceHub/ServiceHub.Contracts/Interfaces/IServiceModule.cs index 3320819..f9acaa9 100644 --- a/ServiceHub/ServiceHub.Contracts/Interfaces/IServiceModule.cs +++ b/ServiceHub/ServiceHub.Contracts/Interfaces/IServiceModule.cs @@ -5,7 +5,7 @@ namespace ServiceHub.Contracts.Interfaces public interface IServiceModule { string Name { get; } - void Initialize(ILogContext log, IConfigContext config); + void Initialize(ILogContext log, IServiceContext config); Task StartAsync(CancellationToken token); void Stop(); ServiceState State(); diff --git a/ServiceHub/ServiceHub.Core/Classes/SimpleContext.cs b/ServiceHub/ServiceHub.Core/Classes/SimpleContext.cs index e40492f..fefaa4c 100644 --- a/ServiceHub/ServiceHub.Core/Classes/SimpleContext.cs +++ b/ServiceHub/ServiceHub.Core/Classes/SimpleContext.cs @@ -1,23 +1,33 @@ using ServiceHub.Contracts.Interfaces; using System.Text.Json; +using System.Xml.Linq; namespace ServiceHub.Core.Classes { - public class SimpleContext : IConfigContext + public class SimpleContext : IServiceContext { - internal ConfigNode Root { get; } = new(); + private ConfigNode Root { get; } = new (); + + private ConfigNode? Node { get; set; } = null; public string? Value { get { - if (Root == null) - return null; - return Root.Value; + if (Node == null) + return Root.Value; + return Node.Value; } } - public IConfigContext[] Items { get => Root.Items.Select(x => new SimpleContext(x)).ToArray(); } + public void SetNode(string path) + { + if (Root == null) + return; + Node = Traverse(path); + } + + public IServiceContext[] Items { get => (Node ?? Root).Items.Select(x => new SimpleContext(x)).ToArray(); } public SimpleContext() { } internal SimpleContext(ConfigNode root) { Root = root; } @@ -59,12 +69,16 @@ private void LoadElement(ConfigNode node, JsonElement element) public string? Get(string path) => Traverse(path)?.Value; - public IConfigContext? GetConfig(string path) => Traverse(path); + public IServiceContext? GetConfig(string path) + { + var data = Traverse(path); + return data == null ? null : (IServiceContext) new SimpleContext(data); + } - private IConfigContext? Traverse(string path) + private ConfigNode? Traverse(string path) { var parts = path.Split(':', StringSplitOptions.RemoveEmptyEntries); - ConfigNode current = Root; + ConfigNode? current = Node ?? Root; foreach (var part in parts) { @@ -78,7 +92,7 @@ private void LoadElement(ConfigNode node, JsonElement element) return null; } - return new SimpleContext(current); + return current; } } } diff --git a/ServiceHub/ServiceHub.Core/Model/ServiceInstance.cs b/ServiceHub/ServiceHub.Core/Model/ServiceInstance.cs index 3a68b04..a93c73c 100644 --- a/ServiceHub/ServiceHub.Core/Model/ServiceInstance.cs +++ b/ServiceHub/ServiceHub.Core/Model/ServiceInstance.cs @@ -7,7 +7,7 @@ internal sealed class ServiceInstance { private string _serviceName; private IServiceModule? _serviceModule { get; set; } - private IConfigContext _config { get; set; } + private IServiceContext _config { get; set; } private ILogContext _log { get; set; } public ServiceState State => _serviceModule?.State() ?? ServiceState.Error; @@ -17,7 +17,7 @@ internal sealed class ServiceInstance public void Stop(CancellationToken ct) => _serviceModule?.Stop(); - public ServiceInstance(ILogContext log, IConfigContext config, Type type) + public ServiceInstance(ILogContext log, IServiceContext config, Type type) { _config = config; _log = log; @@ -26,7 +26,7 @@ public ServiceInstance(ILogContext log, IConfigContext config, Type type) if (string.IsNullOrEmpty(_serviceName)) throw new ArgumentNullException("name"); - IConfigContext? contextValue = config.GetConfig("parameters"); + IServiceContext? contextValue = config.GetConfig("parameters"); if (contextValue == null) throw new ArgumentNullException("parameters"); @@ -35,8 +35,8 @@ public ServiceInstance(ILogContext log, IConfigContext config, Type type) if (!typeof(IServiceModule).IsAssignableFrom(type) || type.IsAbstract) throw new Exception($"The {type.Name} Module is not valid" ); - _serviceModule = (IServiceModule)Activator.CreateInstance(type); - _serviceModule?.Initialize(log, contextValue); + _serviceModule = (IServiceModule?)Activator.CreateInstance(type); + _serviceModule?.Initialize(log, config); } catch (Exception ex) { diff --git a/ServiceHub/ServiceHub.Core/ServiceHub.cs b/ServiceHub/ServiceHub.Core/ServiceHub.cs index 43beffe..d43b0fe 100644 --- a/ServiceHub/ServiceHub.Core/ServiceHub.cs +++ b/ServiceHub/ServiceHub.Core/ServiceHub.cs @@ -28,7 +28,7 @@ private ServiceHub() { } #region Public Methods - public bool InitModule(ILogContext log, IConfigContext config) + public bool InitModule(ILogContext log, IServiceContext config) { var typeService = config.Get("type") ?? string.Empty; @@ -87,7 +87,7 @@ public void LoadModules(ILogContext log, string folderPath) if (!typeof(IServiceModule).IsAssignableFrom(type) || type.IsAbstract) continue; - var name = ((IServiceModule)Activator.CreateInstance(type))?.Name; + var name = ((IServiceModule?)Activator.CreateInstance(type))?.Name; if (!string.IsNullOrWhiteSpace(name)) { _availableModules.Add(name ?? string.Empty, type); diff --git a/ServiceHub/ServiceHub.Host/Program.cs b/ServiceHub/ServiceHub.Host/Program.cs index 8fb3a5d..2d8de4c 100644 --- a/ServiceHub/ServiceHub.Host/Program.cs +++ b/ServiceHub/ServiceHub.Host/Program.cs @@ -28,12 +28,18 @@ static void Main(string[] args) throw new Exception("Json Config is not valid"); log.Info("ServiceHub running..."); - foreach (var localContext in context.GetConfig("services").Items) - { - Core.ServiceHub.Instance.InitModule(log, localContext); - Core.ServiceHub.Instance.Start(localContext.Get("name")); + + var servicesCount = context.GetConfig("services")?.Items.Count() ?? 0; + for (int i = 0; i + From 1d49ac302d75fd9f21a492ddaaf80ba923c2c89c Mon Sep 17 00:00:00 2001 From: DarkDerte <160210611+DarkDerte@users.noreply.github.com> Date: Thu, 22 Jan 2026 23:20:33 +0100 Subject: [PATCH 2/2] Fix bug MqttModule Fix bug SimpleContext --- ServiceHub/Modules/ServiceHub.Modules.MQTT/MqttModule.cs | 9 ++++----- .../ServiceHub.Contracts/Interfaces/IServiceContext.cs | 2 ++ ServiceHub/ServiceHub.Core/Classes/SimpleContext.cs | 4 ++++ ServiceHub/ServiceHub.Host/Program.cs | 6 ++++++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ServiceHub/Modules/ServiceHub.Modules.MQTT/MqttModule.cs b/ServiceHub/Modules/ServiceHub.Modules.MQTT/MqttModule.cs index e0351e8..aa2ab84 100644 --- a/ServiceHub/Modules/ServiceHub.Modules.MQTT/MqttModule.cs +++ b/ServiceHub/Modules/ServiceHub.Modules.MQTT/MqttModule.cs @@ -12,11 +12,10 @@ public class MqttModule : IServiceModule public string Name => "MqttModule"; - public void Initialize(ILogContext log, IServiceContext config) { _log = log; - throw new NotImplementedException(); + _log.Info($"{Name} initialized."); } public Task StartAsync(CancellationToken token) @@ -29,10 +28,10 @@ public Task StartAsync(CancellationToken token) { switch (e.LogMessage.Level) { - case MqttNetLogLevel.Error: _log?.Error(e.LogMessage.Message); break; - case MqttNetLogLevel.Warning: _log?.Warning(e.LogMessage.Message); break; + case MqttNetLogLevel.Error: _log?.Error($"{Name} {e.LogMessage.Message}"); break; + case MqttNetLogLevel.Warning: _log?.Warning($"{Name} {e.LogMessage.Message}"); break; case MqttNetLogLevel.Info: - case MqttNetLogLevel.Verbose: _log?.Info(e.LogMessage.Message); break; + case MqttNetLogLevel.Verbose: _log?.Info($"{Name} {e.LogMessage.Message}"); break; } }; diff --git a/ServiceHub/ServiceHub.Contracts/Interfaces/IServiceContext.cs b/ServiceHub/ServiceHub.Contracts/Interfaces/IServiceContext.cs index 182d3b6..a15ce72 100644 --- a/ServiceHub/ServiceHub.Contracts/Interfaces/IServiceContext.cs +++ b/ServiceHub/ServiceHub.Contracts/Interfaces/IServiceContext.cs @@ -9,6 +9,8 @@ public interface IServiceContext void SetNode(string path); + void ResetNode(); + IServiceContext[] Items { get; } void LoadJson(string json); diff --git a/ServiceHub/ServiceHub.Core/Classes/SimpleContext.cs b/ServiceHub/ServiceHub.Core/Classes/SimpleContext.cs index fefaa4c..c689d12 100644 --- a/ServiceHub/ServiceHub.Core/Classes/SimpleContext.cs +++ b/ServiceHub/ServiceHub.Core/Classes/SimpleContext.cs @@ -27,6 +27,10 @@ public void SetNode(string path) Node = Traverse(path); } + public void ResetNode() { + Node = null; + } + public IServiceContext[] Items { get => (Node ?? Root).Items.Select(x => new SimpleContext(x)).ToArray(); } public SimpleContext() { } diff --git a/ServiceHub/ServiceHub.Host/Program.cs b/ServiceHub/ServiceHub.Host/Program.cs index 2d8de4c..7707981 100644 --- a/ServiceHub/ServiceHub.Host/Program.cs +++ b/ServiceHub/ServiceHub.Host/Program.cs @@ -18,6 +18,11 @@ static void Main(string[] args) ""port"": ""8080"", ""root"": ""wwwroot"" } + }, + { + ""name"": ""MqttIot"", + ""type"": ""MqttModule"", + ""parameters"": { } } ] }"); @@ -35,6 +40,7 @@ static void Main(string[] args) { context.SetNode($"services:{i}"); Core.ServiceHub.Instance.InitModule(log, context); + context.ResetNode(); } foreach (var item in Core.ServiceHub.Instance.ServicesInitialized)