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.
242 lines
8.9 KiB
C#
242 lines
8.9 KiB
C#
using System;
|
|
using System.IO;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace ZB.MOM.WW.LmxProxy.Client
|
|
{
|
|
/// <summary>
|
|
/// Builder for creating configured instances of LmxProxyClient
|
|
/// </summary>
|
|
public class LmxProxyClientBuilder
|
|
{
|
|
private string? _host;
|
|
private int _port = 5050;
|
|
private string? _apiKey;
|
|
private ILogger<LmxProxyClient>? _logger;
|
|
private TimeSpan _defaultTimeout = TimeSpan.FromSeconds(30);
|
|
private int _maxRetryAttempts = 3;
|
|
private TimeSpan _retryDelay = TimeSpan.FromSeconds(1);
|
|
private bool _enableMetrics;
|
|
private string? _correlationIdHeader;
|
|
private ClientTlsConfiguration? _tlsConfiguration;
|
|
|
|
/// <summary>
|
|
/// Sets the host address for the LmxProxy service
|
|
/// </summary>
|
|
/// <param name="host">The host address</param>
|
|
/// <returns>The builder instance for method chaining</returns>
|
|
public LmxProxyClientBuilder WithHost(string host)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(host))
|
|
throw new ArgumentException("Host cannot be null or empty", nameof(host));
|
|
|
|
_host = host;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the port for the LmxProxy service
|
|
/// </summary>
|
|
/// <param name="port">The port number</param>
|
|
/// <returns>The builder instance for method chaining</returns>
|
|
public LmxProxyClientBuilder WithPort(int port)
|
|
{
|
|
if (port < 1 || port > 65535)
|
|
throw new ArgumentOutOfRangeException(nameof(port), "Port must be between 1 and 65535");
|
|
|
|
_port = port;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the API key for authentication
|
|
/// </summary>
|
|
/// <param name="apiKey">The API key</param>
|
|
/// <returns>The builder instance for method chaining</returns>
|
|
public LmxProxyClientBuilder WithApiKey(string apiKey)
|
|
{
|
|
_apiKey = apiKey;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the logger instance
|
|
/// </summary>
|
|
/// <param name="logger">The logger</param>
|
|
/// <returns>The builder instance for method chaining</returns>
|
|
public LmxProxyClientBuilder WithLogger(ILogger<LmxProxyClient> logger)
|
|
{
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the default timeout for operations
|
|
/// </summary>
|
|
/// <param name="timeout">The timeout duration</param>
|
|
/// <returns>The builder instance for method chaining</returns>
|
|
public LmxProxyClientBuilder WithTimeout(TimeSpan timeout)
|
|
{
|
|
if (timeout <= TimeSpan.Zero)
|
|
throw new ArgumentOutOfRangeException(nameof(timeout), "Timeout must be positive");
|
|
if (timeout > TimeSpan.FromMinutes(10))
|
|
throw new ArgumentOutOfRangeException(nameof(timeout), "Timeout cannot exceed 10 minutes");
|
|
|
|
_defaultTimeout = timeout;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enables SSL/TLS with the specified certificate
|
|
/// </summary>
|
|
/// <param name="certificatePath">Path to the certificate file</param>
|
|
/// <returns>The builder instance for method chaining</returns>
|
|
public LmxProxyClientBuilder WithSslCredentials(string? certificatePath = null)
|
|
{
|
|
_tlsConfiguration ??= new ClientTlsConfiguration();
|
|
_tlsConfiguration.UseTls = true;
|
|
_tlsConfiguration.ServerCaCertificatePath = string.IsNullOrWhiteSpace(certificatePath) ? null : certificatePath;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Applies a full TLS configuration to the client.
|
|
/// </summary>
|
|
/// <param name="configuration">The TLS configuration to apply.</param>
|
|
/// <returns>The builder instance for method chaining.</returns>
|
|
public LmxProxyClientBuilder WithTlsConfiguration(ClientTlsConfiguration configuration)
|
|
{
|
|
_tlsConfiguration = configuration ?? throw new ArgumentNullException(nameof(configuration));
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the retry configuration
|
|
/// </summary>
|
|
/// <param name="maxAttempts">Maximum number of retry attempts</param>
|
|
/// <param name="retryDelay">Delay between retries</param>
|
|
/// <returns>The builder instance for method chaining</returns>
|
|
public LmxProxyClientBuilder WithRetryPolicy(int maxAttempts, TimeSpan retryDelay)
|
|
{
|
|
if (maxAttempts <= 0)
|
|
throw new ArgumentOutOfRangeException(nameof(maxAttempts), "Max attempts must be positive");
|
|
if (retryDelay <= TimeSpan.Zero)
|
|
throw new ArgumentOutOfRangeException(nameof(retryDelay), "Retry delay must be positive");
|
|
|
|
_maxRetryAttempts = maxAttempts;
|
|
_retryDelay = retryDelay;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enables metrics collection
|
|
/// </summary>
|
|
/// <returns>The builder instance for method chaining</returns>
|
|
public LmxProxyClientBuilder WithMetrics()
|
|
{
|
|
_enableMetrics = true;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the correlation ID header name for request tracing
|
|
/// </summary>
|
|
/// <param name="headerName">The header name for correlation ID</param>
|
|
/// <returns>The builder instance for method chaining</returns>
|
|
public LmxProxyClientBuilder WithCorrelationIdHeader(string headerName)
|
|
{
|
|
if (string.IsNullOrEmpty(headerName))
|
|
throw new ArgumentException("Header name cannot be null or empty", nameof(headerName));
|
|
|
|
_correlationIdHeader = headerName;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the configured LmxProxyClient instance
|
|
/// </summary>
|
|
/// <returns>A configured LmxProxyClient instance</returns>
|
|
public LmxProxyClient Build()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(_host))
|
|
throw new InvalidOperationException("Host must be specified");
|
|
|
|
ValidateTlsConfiguration();
|
|
|
|
var client = new LmxProxyClient(_host, _port, _apiKey, _tlsConfiguration, _logger)
|
|
{
|
|
DefaultTimeout = _defaultTimeout
|
|
};
|
|
|
|
// Store additional configuration for future use
|
|
client.SetBuilderConfiguration(new ClientConfiguration
|
|
{
|
|
MaxRetryAttempts = _maxRetryAttempts,
|
|
RetryDelay = _retryDelay,
|
|
EnableMetrics = _enableMetrics,
|
|
CorrelationIdHeader = _correlationIdHeader
|
|
});
|
|
|
|
return client;
|
|
}
|
|
|
|
private void ValidateTlsConfiguration()
|
|
{
|
|
if (_tlsConfiguration?.UseTls != true)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(_tlsConfiguration.ServerCaCertificatePath) &&
|
|
!File.Exists(_tlsConfiguration.ServerCaCertificatePath))
|
|
{
|
|
throw new FileNotFoundException(
|
|
$"Certificate file not found: {_tlsConfiguration.ServerCaCertificatePath}",
|
|
_tlsConfiguration.ServerCaCertificatePath);
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(_tlsConfiguration.ClientCertificatePath) &&
|
|
!File.Exists(_tlsConfiguration.ClientCertificatePath))
|
|
{
|
|
throw new FileNotFoundException(
|
|
$"Client certificate file not found: {_tlsConfiguration.ClientCertificatePath}",
|
|
_tlsConfiguration.ClientCertificatePath);
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(_tlsConfiguration.ClientKeyPath) &&
|
|
!File.Exists(_tlsConfiguration.ClientKeyPath))
|
|
{
|
|
throw new FileNotFoundException(
|
|
$"Client key file not found: {_tlsConfiguration.ClientKeyPath}",
|
|
_tlsConfiguration.ClientKeyPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Internal configuration class for storing builder settings
|
|
/// </summary>
|
|
internal class ClientConfiguration
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the maximum number of retry attempts.
|
|
/// </summary>
|
|
public int MaxRetryAttempts { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the retry delay.
|
|
/// </summary>
|
|
public TimeSpan RetryDelay { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether metrics are enabled.
|
|
/// </summary>
|
|
public bool EnableMetrics { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the correlation ID header name.
|
|
/// </summary>
|
|
public string? CorrelationIdHeader { get; set; }
|
|
}
|
|
}
|