deprecate(lmxproxy): move all LmxProxy code, tests, and docs to deprecated/
LmxProxy is no longer needed. Moved the entire lmxproxy/ workspace, DCL adapter files, and related docs to deprecated/. Removed LmxProxy registration from DataConnectionFactory, project reference from DCL, protocol option from UI, and cleaned up all requirement docs.
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Serilog;
|
||||
|
||||
namespace ZB.MOM.WW.LmxProxy.Host.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Validates the LmxProxy configuration at startup.
|
||||
/// Throws InvalidOperationException on any validation error.
|
||||
/// </summary>
|
||||
public static class ConfigurationValidator
|
||||
{
|
||||
private static readonly ILogger Log = Serilog.Log.ForContext(typeof(ConfigurationValidator));
|
||||
|
||||
/// <summary>
|
||||
/// Validates all configuration settings and logs the effective values.
|
||||
/// Throws on first validation error.
|
||||
/// </summary>
|
||||
public static void ValidateAndLog(LmxProxyConfiguration config)
|
||||
{
|
||||
var errors = new List<string>();
|
||||
|
||||
// GrpcPort
|
||||
if (config.GrpcPort < 1 || config.GrpcPort > 65535)
|
||||
errors.Add($"GrpcPort must be 1-65535, got {config.GrpcPort}");
|
||||
|
||||
// Connection
|
||||
var conn = config.Connection;
|
||||
if (conn.MonitorIntervalSeconds <= 0)
|
||||
errors.Add($"Connection.MonitorIntervalSeconds must be > 0, got {conn.MonitorIntervalSeconds}");
|
||||
if (conn.ConnectionTimeoutSeconds <= 0)
|
||||
errors.Add($"Connection.ConnectionTimeoutSeconds must be > 0, got {conn.ConnectionTimeoutSeconds}");
|
||||
if (conn.ReadTimeoutSeconds <= 0)
|
||||
errors.Add($"Connection.ReadTimeoutSeconds must be > 0, got {conn.ReadTimeoutSeconds}");
|
||||
if (conn.WriteTimeoutSeconds <= 0)
|
||||
errors.Add($"Connection.WriteTimeoutSeconds must be > 0, got {conn.WriteTimeoutSeconds}");
|
||||
if (conn.MaxConcurrentOperations <= 0)
|
||||
errors.Add($"Connection.MaxConcurrentOperations must be > 0, got {conn.MaxConcurrentOperations}");
|
||||
if (conn.NodeName != null && conn.NodeName.Length > 255)
|
||||
errors.Add("Connection.NodeName must be <= 255 characters");
|
||||
if (conn.GalaxyName != null && conn.GalaxyName.Length > 255)
|
||||
errors.Add("Connection.GalaxyName must be <= 255 characters");
|
||||
|
||||
// Subscription
|
||||
var sub = config.Subscription;
|
||||
if (sub.ChannelCapacity < 0 || sub.ChannelCapacity > 100000)
|
||||
errors.Add($"Subscription.ChannelCapacity must be 0-100000, got {sub.ChannelCapacity}");
|
||||
var validModes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{ "DropOldest", "DropNewest", "Wait" };
|
||||
if (!validModes.Contains(sub.ChannelFullMode))
|
||||
errors.Add($"Subscription.ChannelFullMode must be DropOldest, DropNewest, or Wait, got '{sub.ChannelFullMode}'");
|
||||
|
||||
// ServiceRecovery
|
||||
var sr = config.ServiceRecovery;
|
||||
if (sr.FirstFailureDelayMinutes < 0)
|
||||
errors.Add($"ServiceRecovery.FirstFailureDelayMinutes must be >= 0, got {sr.FirstFailureDelayMinutes}");
|
||||
if (sr.SecondFailureDelayMinutes < 0)
|
||||
errors.Add($"ServiceRecovery.SecondFailureDelayMinutes must be >= 0, got {sr.SecondFailureDelayMinutes}");
|
||||
if (sr.SubsequentFailureDelayMinutes < 0)
|
||||
errors.Add($"ServiceRecovery.SubsequentFailureDelayMinutes must be >= 0, got {sr.SubsequentFailureDelayMinutes}");
|
||||
if (sr.ResetPeriodDays <= 0)
|
||||
errors.Add($"ServiceRecovery.ResetPeriodDays must be > 0, got {sr.ResetPeriodDays}");
|
||||
|
||||
// TLS
|
||||
if (config.Tls.Enabled)
|
||||
{
|
||||
if (!File.Exists(config.Tls.ServerCertificatePath))
|
||||
Log.Warning("TLS enabled but server certificate not found at {Path} (will auto-generate)",
|
||||
config.Tls.ServerCertificatePath);
|
||||
if (!File.Exists(config.Tls.ServerKeyPath))
|
||||
Log.Warning("TLS enabled but server key not found at {Path} (will auto-generate)",
|
||||
config.Tls.ServerKeyPath);
|
||||
}
|
||||
|
||||
// WebServer
|
||||
if (config.WebServer.Enabled)
|
||||
{
|
||||
if (config.WebServer.Port < 1 || config.WebServer.Port > 65535)
|
||||
errors.Add($"WebServer.Port must be 1-65535, got {config.WebServer.Port}");
|
||||
}
|
||||
|
||||
if (errors.Count > 0)
|
||||
{
|
||||
foreach (var error in errors)
|
||||
Log.Error("Configuration error: {Error}", error);
|
||||
throw new InvalidOperationException(
|
||||
$"Configuration validation failed with {errors.Count} error(s): {string.Join("; ", errors)}");
|
||||
}
|
||||
|
||||
// Log effective configuration
|
||||
Log.Information("Configuration validated successfully");
|
||||
Log.Information(" GrpcPort: {Port}", config.GrpcPort);
|
||||
Log.Information(" ApiKeyConfigFile: {File}", config.ApiKeyConfigFile);
|
||||
Log.Information(" Connection.AutoReconnect: {AutoReconnect}", conn.AutoReconnect);
|
||||
Log.Information(" Connection.MonitorIntervalSeconds: {Interval}", conn.MonitorIntervalSeconds);
|
||||
Log.Information(" Connection.MaxConcurrentOperations: {Max}", conn.MaxConcurrentOperations);
|
||||
Log.Information(" Subscription.ChannelCapacity: {Capacity}", sub.ChannelCapacity);
|
||||
Log.Information(" Subscription.ChannelFullMode: {Mode}", sub.ChannelFullMode);
|
||||
Log.Information(" Tls.Enabled: {Enabled}", config.Tls.Enabled);
|
||||
Log.Information(" WebServer.Enabled: {Enabled}, Port: {Port}", config.WebServer.Enabled, config.WebServer.Port);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace ZB.MOM.WW.LmxProxy.Host.Configuration
|
||||
{
|
||||
/// <summary>MxAccess connection settings.</summary>
|
||||
public class ConnectionConfiguration
|
||||
{
|
||||
/// <summary>Auto-reconnect check interval in seconds. Default: 5.</summary>
|
||||
public int MonitorIntervalSeconds { get; set; } = 5;
|
||||
|
||||
/// <summary>Initial connection timeout in seconds. Default: 30.</summary>
|
||||
public int ConnectionTimeoutSeconds { get; set; } = 30;
|
||||
|
||||
/// <summary>Per-read operation timeout in seconds. Default: 5.</summary>
|
||||
public int ReadTimeoutSeconds { get; set; } = 5;
|
||||
|
||||
/// <summary>Per-write operation timeout in seconds. Default: 5.</summary>
|
||||
public int WriteTimeoutSeconds { get; set; } = 5;
|
||||
|
||||
/// <summary>Semaphore limit for concurrent MxAccess operations. Default: 10.</summary>
|
||||
public int MaxConcurrentOperations { get; set; } = 10;
|
||||
|
||||
/// <summary>Enable auto-reconnect loop. Default: true.</summary>
|
||||
public bool AutoReconnect { get; set; } = true;
|
||||
|
||||
/// <summary>MxAccess node name (optional).</summary>
|
||||
public string? NodeName { get; set; }
|
||||
|
||||
/// <summary>MxAccess galaxy name (optional).</summary>
|
||||
public string? GalaxyName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
namespace ZB.MOM.WW.LmxProxy.Host.Configuration
|
||||
{
|
||||
/// <summary>Root configuration class bound to appsettings.json.</summary>
|
||||
public class LmxProxyConfiguration
|
||||
{
|
||||
/// <summary>gRPC server listen port. Default: 50051.</summary>
|
||||
public int GrpcPort { get; set; } = 50051;
|
||||
|
||||
/// <summary>Path to API key configuration file. Default: apikeys.json.</summary>
|
||||
public string ApiKeyConfigFile { get; set; } = "apikeys.json";
|
||||
|
||||
/// <summary>Unique client name for MxAccess Register(). Must be unique per instance. Default: auto-generated.</summary>
|
||||
public string? ClientName { get; set; }
|
||||
|
||||
/// <summary>MxAccess connection settings.</summary>
|
||||
public ConnectionConfiguration Connection { get; set; } = new ConnectionConfiguration();
|
||||
|
||||
/// <summary>Subscription channel settings.</summary>
|
||||
public SubscriptionConfiguration Subscription { get; set; } = new SubscriptionConfiguration();
|
||||
|
||||
/// <summary>TLS/SSL settings.</summary>
|
||||
public TlsConfiguration Tls { get; set; } = new TlsConfiguration();
|
||||
|
||||
/// <summary>Status web server settings.</summary>
|
||||
public WebServerConfiguration WebServer { get; set; } = new WebServerConfiguration();
|
||||
|
||||
/// <summary>Windows SCM service recovery settings.</summary>
|
||||
public ServiceRecoveryConfiguration ServiceRecovery { get; set; } = new ServiceRecoveryConfiguration();
|
||||
|
||||
/// <summary>Health check / active probe settings.</summary>
|
||||
public HealthCheckConfiguration HealthCheck { get; set; } = new HealthCheckConfiguration();
|
||||
}
|
||||
|
||||
/// <summary>Health check / probe configuration.</summary>
|
||||
public class HealthCheckConfiguration
|
||||
{
|
||||
/// <summary>Tag address to subscribe to for connection liveness. Default: DevPlatform.Scheduler.ScanTime.</summary>
|
||||
public string TestTagAddress { get; set; } = "DevPlatform.Scheduler.ScanTime";
|
||||
|
||||
/// <summary>
|
||||
/// Maximum time (ms) without a value update on the test tag before forcing reconnect.
|
||||
/// Default: 5000 (5 seconds).
|
||||
/// </summary>
|
||||
public int ProbeStaleThresholdMs { get; set; } = 5000;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace ZB.MOM.WW.LmxProxy.Host.Configuration
|
||||
{
|
||||
/// <summary>Windows SCM service recovery settings.</summary>
|
||||
public class ServiceRecoveryConfiguration
|
||||
{
|
||||
/// <summary>Restart delay after first failure in minutes. Default: 1.</summary>
|
||||
public int FirstFailureDelayMinutes { get; set; } = 1;
|
||||
|
||||
/// <summary>Restart delay after second failure in minutes. Default: 5.</summary>
|
||||
public int SecondFailureDelayMinutes { get; set; } = 5;
|
||||
|
||||
/// <summary>Restart delay after subsequent failures in minutes. Default: 10.</summary>
|
||||
public int SubsequentFailureDelayMinutes { get; set; } = 10;
|
||||
|
||||
/// <summary>Days before failure count resets. Default: 1.</summary>
|
||||
public int ResetPeriodDays { get; set; } = 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace ZB.MOM.WW.LmxProxy.Host.Configuration
|
||||
{
|
||||
/// <summary>Subscription channel settings.</summary>
|
||||
public class SubscriptionConfiguration
|
||||
{
|
||||
/// <summary>Per-client subscription buffer size. Default: 1000.</summary>
|
||||
public int ChannelCapacity { get; set; } = 1000;
|
||||
|
||||
/// <summary>Backpressure strategy: DropOldest, DropNewest, or Wait. Default: DropOldest.</summary>
|
||||
public string ChannelFullMode { get; set; } = "DropOldest";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
namespace ZB.MOM.WW.LmxProxy.Host.Configuration
|
||||
{
|
||||
/// <summary>TLS/SSL settings for the gRPC server.</summary>
|
||||
public class TlsConfiguration
|
||||
{
|
||||
/// <summary>Enable TLS on the gRPC server. Default: false.</summary>
|
||||
public bool Enabled { get; set; } = false;
|
||||
|
||||
/// <summary>PEM server certificate path. Default: certs/server.crt.</summary>
|
||||
public string ServerCertificatePath { get; set; } = "certs/server.crt";
|
||||
|
||||
/// <summary>PEM server private key path. Default: certs/server.key.</summary>
|
||||
public string ServerKeyPath { get; set; } = "certs/server.key";
|
||||
|
||||
/// <summary>CA certificate for mutual TLS client validation. Default: certs/ca.crt.</summary>
|
||||
public string ClientCaCertificatePath { get; set; } = "certs/ca.crt";
|
||||
|
||||
/// <summary>Require client certificates (mutual TLS). Default: false.</summary>
|
||||
public bool RequireClientCertificate { get; set; } = false;
|
||||
|
||||
/// <summary>Check certificate revocation lists. Default: false.</summary>
|
||||
public bool CheckCertificateRevocation { get; set; } = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace ZB.MOM.WW.LmxProxy.Host.Configuration
|
||||
{
|
||||
/// <summary>HTTP status web server settings.</summary>
|
||||
public class WebServerConfiguration
|
||||
{
|
||||
/// <summary>Enable the status web server. Default: true.</summary>
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>HTTP listen port. Default: 8080.</summary>
|
||||
public int Port { get; set; } = 8080;
|
||||
|
||||
/// <summary>Custom URL prefix (defaults to http://+:{Port}/ if null).</summary>
|
||||
public string? Prefix { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user