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:
@@ -55,6 +55,7 @@ Controls the OPC UA server endpoint and session limits. Defined in `OpcUaConfigu
|
||||
| `MaxSessions` | `int` | `100` | Maximum simultaneous OPC UA sessions |
|
||||
| `SessionTimeoutMinutes` | `int` | `30` | Idle session timeout in minutes |
|
||||
| `AlarmTrackingEnabled` | `bool` | `false` | Enables `AlarmConditionState` nodes for alarm attributes |
|
||||
| `ApplicationUri` | `string?` | `null` | Explicit application URI for this server instance. Required when redundancy is enabled. Defaults to `urn:{GalaxyName}:LmxOpcUa` when null |
|
||||
|
||||
### MxAccess
|
||||
|
||||
@@ -156,6 +157,30 @@ Example — production deployment with encrypted transport:
|
||||
}
|
||||
```
|
||||
|
||||
### Redundancy
|
||||
|
||||
Controls non-transparent OPC UA redundancy. Defined in `RedundancyConfiguration`. See [Redundancy Guide](Redundancy.md) for detailed usage.
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `Enabled` | `bool` | `false` | Enables redundancy mode and ServiceLevel computation |
|
||||
| `Mode` | `string` | `"Warm"` | Redundancy mode: `Warm` or `Hot` |
|
||||
| `Role` | `string` | `"Primary"` | Instance role: `Primary` (higher ServiceLevel) or `Secondary` |
|
||||
| `ServerUris` | `List<string>` | `[]` | ApplicationUri values for all servers in the redundant set |
|
||||
| `ServiceLevelBase` | `int` | `200` | Base ServiceLevel when healthy (1-255). Secondary receives base - 50 |
|
||||
|
||||
Example — two-instance redundant pair (Primary):
|
||||
|
||||
```json
|
||||
"Redundancy": {
|
||||
"Enabled": true,
|
||||
"Mode": "Warm",
|
||||
"Role": "Primary",
|
||||
"ServerUris": ["urn:localhost:LmxOpcUa:instance1", "urn:localhost:LmxOpcUa:instance2"],
|
||||
"ServiceLevelBase": 200
|
||||
}
|
||||
```
|
||||
|
||||
## Feature Flags
|
||||
|
||||
Three boolean properties act as feature flags that control optional subsystems:
|
||||
@@ -176,6 +201,10 @@ Three boolean properties act as feature flags that control optional subsystems:
|
||||
- Unknown security profile names are logged as warnings
|
||||
- `AutoAcceptClientCertificates = true` emits a warning
|
||||
- Only-`None` profile configuration emits a warning
|
||||
- `OpcUa.ApplicationUri` must be set when `Redundancy.Enabled = true`
|
||||
- `Redundancy.ServiceLevelBase` must be between 1 and 255
|
||||
- `Redundancy.ServerUris` should contain at least 2 entries when enabled
|
||||
- Local `ApplicationUri` should appear in `Redundancy.ServerUris`
|
||||
|
||||
If validation fails, the service throws `InvalidOperationException` and does not start.
|
||||
|
||||
@@ -206,7 +235,8 @@ Integration tests use this constructor to inject substitute implementations of `
|
||||
"GalaxyName": "ZB",
|
||||
"MaxSessions": 100,
|
||||
"SessionTimeoutMinutes": 30,
|
||||
"AlarmTrackingEnabled": false
|
||||
"AlarmTrackingEnabled": false,
|
||||
"ApplicationUri": null
|
||||
},
|
||||
"MxAccess": {
|
||||
"ClientName": "LmxOpcUa",
|
||||
@@ -249,6 +279,13 @@ Integration tests use this constructor to inject substitute implementations of `
|
||||
"MinimumCertificateKeySize": 2048,
|
||||
"PkiRootPath": null,
|
||||
"CertificateSubject": null
|
||||
},
|
||||
"Redundancy": {
|
||||
"Enabled": false,
|
||||
"Mode": "Warm",
|
||||
"Role": "Primary",
|
||||
"ServerUris": [],
|
||||
"ServiceLevelBase": 200
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user