Add configurable non-transparent OPC UA server redundancy
Separates ApplicationUri from namespace identity so each instance in a redundant pair has a unique server URI while sharing the same Galaxy namespace. Exposes RedundancySupport, ServerUriArray, and dynamic ServiceLevel through the standard OPC UA server object. ServiceLevel is computed from role (Primary/Secondary) and runtime health (MXAccess and DB connectivity). Adds CLI redundancy command, second deployed service instance, and 31 new tests including paired-server integration. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.OpcUa
|
||||
private readonly AuthenticationConfiguration _authConfig;
|
||||
private readonly IUserAuthenticationProvider? _authProvider;
|
||||
private readonly SecurityProfileConfiguration _securityConfig;
|
||||
private readonly RedundancyConfiguration _redundancyConfig;
|
||||
private ApplicationInstance? _application;
|
||||
private LmxOpcUaServer? _server;
|
||||
|
||||
@@ -43,6 +44,12 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.OpcUa
|
||||
/// </summary>
|
||||
public bool IsRunning => _server != null;
|
||||
|
||||
/// <summary>
|
||||
/// Updates the OPC UA ServiceLevel based on current runtime health.
|
||||
/// </summary>
|
||||
public void UpdateServiceLevel(bool mxAccessConnected, bool dbConnected) =>
|
||||
_server?.UpdateServiceLevel(mxAccessConnected, dbConnected);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new host for the Galaxy-backed OPC UA server instance.
|
||||
/// </summary>
|
||||
@@ -54,7 +61,8 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.OpcUa
|
||||
HistorianDataSource? historianDataSource = null,
|
||||
AuthenticationConfiguration? authConfig = null,
|
||||
IUserAuthenticationProvider? authProvider = null,
|
||||
SecurityProfileConfiguration? securityConfig = null)
|
||||
SecurityProfileConfiguration? securityConfig = null,
|
||||
RedundancyConfiguration? redundancyConfig = null)
|
||||
{
|
||||
_config = config;
|
||||
_mxAccessClient = mxAccessClient;
|
||||
@@ -63,6 +71,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.OpcUa
|
||||
_authConfig = authConfig ?? new AuthenticationConfiguration();
|
||||
_authProvider = authProvider;
|
||||
_securityConfig = securityConfig ?? new SecurityProfileConfiguration();
|
||||
_redundancyConfig = redundancyConfig ?? new RedundancyConfiguration();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -71,6 +80,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.OpcUa
|
||||
public async Task StartAsync()
|
||||
{
|
||||
var namespaceUri = $"urn:{_config.GalaxyName}:LmxOpcUa";
|
||||
var applicationUri = _config.ApplicationUri ?? namespaceUri;
|
||||
|
||||
// Resolve configured security profiles
|
||||
var securityPolicies = SecurityProfileResolver.Resolve(_securityConfig.Profiles);
|
||||
@@ -127,7 +137,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.OpcUa
|
||||
var appConfig = new ApplicationConfiguration
|
||||
{
|
||||
ApplicationName = _config.ServerName,
|
||||
ApplicationUri = namespaceUri,
|
||||
ApplicationUri = applicationUri,
|
||||
ApplicationType = ApplicationType.Server,
|
||||
ProductUri = namespaceUri,
|
||||
ServerConfiguration = serverConfig,
|
||||
@@ -174,11 +184,11 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.OpcUa
|
||||
}
|
||||
|
||||
_server = new LmxOpcUaServer(_config.GalaxyName, _mxAccessClient, _metrics, _historianDataSource,
|
||||
_config.AlarmTrackingEnabled, _authConfig, _authProvider);
|
||||
_config.AlarmTrackingEnabled, _authConfig, _authProvider, _redundancyConfig, applicationUri);
|
||||
await _application.Start(_server);
|
||||
|
||||
Log.Information("OPC UA server started on opc.tcp://{BindAddress}:{Port}{EndpointPath} (namespace={Namespace})",
|
||||
_config.BindAddress, _config.Port, _config.EndpointPath, namespaceUri);
|
||||
Log.Information("OPC UA server started on opc.tcp://{BindAddress}:{Port}{EndpointPath} (applicationUri={ApplicationUri}, namespace={Namespace})",
|
||||
_config.BindAddress, _config.Port, _config.EndpointPath, applicationUri, namespaceUri);
|
||||
}
|
||||
|
||||
private void OnCertificateValidation(CertificateValidator sender, CertificateValidationEventArgs e)
|
||||
|
||||
Reference in New Issue
Block a user