From 64e3fbe03592636bb2cc68f34a5c55607fecf279 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 28 May 2026 08:10:17 -0400 Subject: [PATCH] docs: backfill XML documentation across 756 files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds , , , and tags to public members surfaced by commentchecker — resolves 5,847 of 5,869 issues (99.6%) across three /fixdocs passes. --- .../Commands/AlarmsCommand.cs | 1 + .../Commands/BrowseCommand.cs | 5 +- .../Commands/ConnectCommand.cs | 5 +- .../Commands/HistoryReadCommand.cs | 5 +- .../Commands/ReadCommand.cs | 5 +- .../Commands/RedundancyCommand.cs | 6 +- .../Commands/SubscribeCommand.cs | 6 +- .../Commands/WriteCommand.cs | 1 + .../DefaultApplicationConfigurationFactory.cs | 3 + .../Adapters/DefaultEndpointDiscovery.cs | 4 + .../Adapters/DefaultSessionFactory.cs | 8 + .../IApplicationConfigurationFactory.cs | 2 + .../Adapters/IEndpointDiscovery.cs | 3 + .../Helpers/AggregateTypeMapper.cs | 2 + .../Helpers/SecurityModeMapper.cs | 6 +- .../IOpcUaClientServiceFactory.cs | 2 + .../Models/AlarmEventArgs.cs | 14 ++ .../Models/BrowseResult.cs | 5 + .../Models/ConnectionInfo.cs | 7 + .../Models/ConnectionStateChangedEventArgs.cs | 4 + .../Models/DataChangedEventArgs.cs | 3 + .../Models/RedundancyInfo.cs | 5 + .../OpcUaClientServiceFactory.cs | 2 + .../ZB.MOM.WW.OtOpcUa.Client.UI/App.axaml.cs | 2 + .../Controls/DateTimeRangePicker.axaml.cs | 7 + .../Helpers/StatusCodeFormatter.cs | 3 + .../Helpers/ValueFormatter.cs | 3 + .../ZB.MOM.WW.OtOpcUa.Client.UI/Program.cs | 5 + .../Services/AvaloniaUiDispatcher.cs | 2 + .../Services/ISettingsService.cs | 3 + .../Services/IUiDispatcher.cs | 1 + .../Services/JsonSettingsService.cs | 4 + .../Services/SynchronousUiDispatcher.cs | 2 + .../ViewModels/AlarmsViewModel.cs | 8 + .../ViewModels/BrowseTreeViewModel.cs | 5 + .../ViewModels/HistoryValueViewModel.cs | 9 ++ .../ViewModels/HistoryViewModel.cs | 4 + .../ViewModels/ReadWriteViewModel.cs | 4 + .../ViewModels/SubscriptionItemViewModel.cs | 3 + .../ViewModels/TreeNodeViewModel.cs | 7 + .../Views/AckAlarmWindow.axaml.cs | 4 + .../Views/AlarmsView.axaml.cs | 2 + .../Views/BrowseTreeView.axaml.cs | 1 + .../Views/HistoryView.axaml.cs | 1 + .../Views/MainWindow.axaml.cs | 3 + .../Views/ReadWriteView.axaml.cs | 1 + .../Views/SubscriptionsView.axaml.cs | 2 + .../Views/WriteValueWindow.axaml.cs | 5 + .../AkkaClusterOptions.cs | 6 + .../ClusterRoleInfo.cs | 25 +++ .../ZB.MOM.WW.OtOpcUa.Cluster/HoconLoader.cs | 3 + .../ZB.MOM.WW.OtOpcUa.Cluster/RoleParser.cs | 2 + .../ServiceCollectionExtensions.cs | 4 + .../Engines/IAlarmActorStateStore.cs | 13 ++ .../Engines/IScriptedAlarmEvaluator.cs | 17 ++ .../Engines/IVirtualTagEvaluator.cs | 17 ++ .../Interfaces/IAdminOperationsClient.cs | 4 + .../Interfaces/IClusterRoleInfo.cs | 12 ++ .../Interfaces/IFleetDiagnosticsClient.cs | 3 + .../Interfaces/RoleLeaderChangedEventArgs.cs | 6 + .../Observability/OtOpcUaTelemetry.cs | 1 + .../OpcUa/DeferredAddressSpaceSink.cs | 21 +++ .../OpcUa/DeferredServiceLevelPublisher.cs | 3 + .../OpcUa/IOpcUaAddressSpaceSink.cs | 24 +++ .../OpcUa/IServiceLevelPublisher.cs | 7 + .../Types/CorrelationId.cs | 7 + .../Types/DeploymentId.cs | 13 ++ .../Types/ExecutionId.cs | 13 ++ .../ZB.MOM.WW.OtOpcUa.Commons/Types/NodeId.cs | 11 ++ .../Types/RevisionHash.cs | 13 ++ .../DesignTimeDbContextFactory.cs | 3 + .../Entities/ClusterNode.cs | 9 ++ .../Entities/ClusterNodeCredential.cs | 10 +- .../Entities/ConfigAuditLog.cs | 7 + .../Entities/ConfigEdit.cs | 10 +- .../Entities/Deployment.cs | 9 ++ .../Entities/Device.cs | 12 ++ .../Entities/DriverHostStatus.cs | 1 + .../Entities/DriverInstance.cs | 6 + .../DriverInstanceResilienceStatus.cs | 2 + .../Entities/Equipment.cs | 11 ++ .../Entities/EquipmentImportBatch.cs | 58 +++++++ .../Entities/ExternalIdReservation.cs | 8 + .../Entities/Namespace.cs | 6 + .../Entities/NodeAcl.cs | 6 + .../Entities/NodeDeploymentState.cs | 9 ++ .../Entities/PollGroup.cs | 5 + .../Entities/Script.cs | 1 + .../Entities/ScriptedAlarm.cs | 2 + .../Entities/ScriptedAlarmState.cs | 3 + .../Entities/ServerCluster.cs | 11 ++ .../Entities/Tag.cs | 21 +++ .../Entities/UnsArea.cs | 5 + .../Entities/UnsLine.cs | 3 + .../Entities/VirtualTag.cs | 6 +- .../LocalCache/GenerationSealedCache.cs | 15 ++ .../LocalCache/GenerationSnapshot.cs | 5 + .../LocalCache/ILocalConfigCache.cs | 11 ++ .../LocalCache/LiteDbConfigCache.cs | 13 ++ .../LocalCache/ResilientConfigReader.cs | 20 ++- .../OtOpcUaConfigDbContext.cs | 30 ++++ .../ServiceCollectionExtensions.cs | 3 + .../Services/ILdapGroupRoleMappingService.cs | 9 ++ .../Services/LdapGroupRoleMappingService.cs | 15 ++ .../Validation/DraftSnapshot.cs | 10 ++ .../Validation/DraftValidator.cs | 7 + .../DriverTypeRegistry.cs | 3 + .../Historian/IHistorianDataSource.cs | 19 +++ .../IAddressSpaceBuilder.cs | 5 + .../IAlarmSource.cs | 6 + .../IDriver.cs | 6 + .../IDriverFactory.cs | 10 ++ .../IHistoryProvider.cs | 17 ++ .../IPerCallHostResolver.cs | 2 + .../IReadable.cs | 3 + .../ISubscribable.cs | 6 + .../ITagDiscovery.cs | 2 + .../PollGroupEngine.cs | 5 + .../IAlarmHistorianSink.cs | 8 + .../SqliteStoreAndForwardSink.cs | 34 +++- .../AlarmConditionState.cs | 3 + .../AlarmPredicateContext.cs | 13 ++ .../IAlarmStateStore.cs | 22 +++ .../MessageTemplate.cs | 5 + .../Part9StateMachine.cs | 73 +++++++++ .../ScriptedAlarmEngine.cs | 71 +++++++++ .../ScriptedAlarmSource.cs | 10 ++ .../CompiledScriptCache.cs | 4 + .../DependencyExtractor.cs | 5 + .../ForbiddenTypeAnalyzer.cs | 5 + .../ScriptContext.cs | 6 + .../ScriptEvaluator.cs | 12 +- .../ScriptGlobals.cs | 1 + .../ScriptLogCompanionSink.cs | 5 + .../ScriptLoggerFactory.cs | 4 + .../ScriptSandbox.cs | 1 + .../TimedScriptEvaluator.cs | 12 ++ .../DependencyGraph.cs | 18 +++ .../IHistoryWriter.cs | 7 + .../ITagUpstreamSource.cs | 3 + .../TimerTriggerScheduler.cs | 11 ++ .../VirtualTagContext.cs | 9 ++ .../VirtualTagEngine.cs | 33 ++++ .../VirtualTagSource.cs | 34 ++++ .../Authorization/AuthorizationDecision.cs | 3 + .../Authorization/IPermissionEvaluator.cs | 3 + .../Authorization/PermissionTrie.cs | 2 + .../Authorization/PermissionTrieCache.cs | 14 ++ .../Authorization/TriePermissionEvaluator.cs | 10 ++ .../Authorization/UserAuthorizationState.cs | 2 + .../Hosting/DriverFactoryRegistry.cs | 3 + .../Hosting/DriverFactoryRegistryAdapter.cs | 7 + .../Hosting/DriverHost.cs | 11 ++ .../Observability/DriverHealthReport.cs | 2 + .../Observability/LogContextEnricher.cs | 8 + .../OpcUa/EquipmentNodeWalker.cs | 1 + .../OpcUa/GenericDriverNodeManager.cs | 19 +++ .../OpcUa/IdentificationFolderBuilder.cs | 12 +- .../Resilience/AlarmSurfaceInvoker.cs | 19 +++ .../Resilience/CapabilityInvoker.cs | 13 ++ .../Resilience/DriverResilienceOptions.cs | 4 + .../DriverResilienceOptionsParser.cs | 10 ++ .../DriverResiliencePipelineBuilder.cs | 2 + .../DriverResilienceStatusTracker.cs | 29 ++++ .../Stability/MemoryRecycle.cs | 7 + .../Stability/MemoryTracking.cs | 6 + .../Stability/ScheduledRecycleScheduler.cs | 6 + .../Stability/WedgeDetector.cs | 4 + .../AbCipCommandBase.cs | 5 + .../Commands/ProbeCommand.cs | 3 + .../Commands/ReadCommand.cs | 7 + .../Commands/SubscribeCommand.cs | 5 + .../Commands/WriteCommand.cs | 7 + .../AbLegacyCommandBase.cs | 6 + .../Commands/ProbeCommand.cs | 3 + .../Commands/ReadCommand.cs | 5 + .../Commands/SubscribeCommand.cs | 4 + .../Commands/WriteCommand.cs | 7 + .../DriverCommandBase.cs | 3 + .../SnapshotFormatter.cs | 15 ++ .../Commands/ProbeCommand.cs | 3 + .../Commands/ReadCommand.cs | 7 + .../Commands/SubscribeCommand.cs | 4 + .../Commands/WriteCommand.cs | 7 + .../FocasCommandBase.cs | 7 + .../Commands/ProbeCommand.cs | 5 + .../Commands/ReadCommand.cs | 12 ++ .../Commands/SubscribeCommand.cs | 9 ++ .../Commands/WriteCommand.cs | 17 +- .../ModbusCommandBase.cs | 6 + .../Commands/ProbeCommand.cs | 3 + .../Commands/ReadCommand.cs | 6 + .../Commands/SubscribeCommand.cs | 4 + .../Commands/WriteCommand.cs | 8 + .../S7CommandBase.cs | 8 + .../Commands/BrowseCommand.cs | 18 +++ .../Commands/ProbeCommand.cs | 3 + .../Commands/ReadCommand.cs | 7 + .../Commands/SubscribeCommand.cs | 7 + .../Commands/WriteCommand.cs | 6 + .../TwinCATCommandBase.cs | 16 +- .../TwinCATTagCommandBase.cs | 4 + .../AbCipAlarmProjection.cs | 40 +++++ .../AbCipDataType.cs | 2 + .../AbCipDriver.cs | 88 +++++++++++ .../AbCipDriverFactoryExtensions.cs | 124 +++++++++++++++ .../AbCipDriverOptions.cs | 3 + .../AbCipHostAddress.cs | 6 +- .../AbCipStatusMapper.cs | 3 + .../AbCipSystemTagFilter.cs | 1 + .../AbCipTagPath.cs | 2 + .../AbCipTemplateCache.cs | 5 + .../AbCipUdtMemberLayout.cs | 1 + .../AbCipUdtReadPlanner.cs | 3 + .../CipSymbolObjectDecoder.cs | 6 + .../CipTemplateObjectDecoder.cs | 4 + .../IAbCipTagEnumerator.cs | 16 ++ .../IAbCipTagRuntime.cs | 13 ++ .../IAbCipTemplateReader.cs | 4 + .../LibplctagTagEnumerator.cs | 7 + .../LibplctagTagRuntime.cs | 33 ++++ .../LibplctagTemplateReader.cs | 8 + .../PlcFamilies/AbCipPlcFamilyProfile.cs | 1 + .../AbLegacyAddress.cs | 3 + .../AbLegacyDataType.cs | 3 + .../AbLegacyDriver.cs | 148 ++++++++++++++++++ .../AbLegacyDriverFactoryExtensions.cs | 79 ++++++++++ .../AbLegacyDriverOptions.cs | 14 +- .../AbLegacyHostAddress.cs | 4 + .../AbLegacyStatusMapper.cs | 6 + .../IAbLegacyTagRuntime.cs | 21 +++ .../LibplctagLegacyTagRuntime.cs | 14 ++ .../PlcFamilies/AbLegacyPlcFamilyProfile.cs | 2 + .../FocasAddress.cs | 4 + .../FocasAlarmProjection.cs | 30 ++++ .../FocasCapabilityMatrix.cs | 31 ++-- .../FocasDataType.cs | 3 + .../FocasDriver.cs | 95 ++++++++++- .../FocasDriverFactoryExtensions.cs | 64 ++++++++ .../FocasDriverOptions.cs | 15 +- .../FocasHostAddress.cs | 4 + .../FocasStatusMapper.cs | 2 + .../IFocasClient.cs | 32 ++++ .../Wire/FocasConstants.cs | 10 +- .../Wire/FocasWireClient.cs | 113 +++++++++++++ .../Wire/FocasWireException.cs | 13 ++ .../Wire/FocasWireProtocol.cs | 19 +++ .../Wire/WireFocasClient.cs | 57 +++++++ .../Browse/AlarmRefBuilder.cs | 3 + .../Browse/DataTypeMap.cs | 2 + .../Browse/DeployWatcher.cs | 11 ++ .../Browse/GalaxyDiscoverer.cs | 4 + .../Browse/GatewayGalaxyDeployWatchSource.cs | 6 + .../Browse/GatewayGalaxyHierarchySource.cs | 8 + .../Browse/IGalaxyDeployWatchSource.cs | 2 + .../Browse/IGalaxyHierarchySource.cs | 1 + .../Browse/SecurityMap.cs | 3 + .../Browse/TracedGalaxyHierarchySource.cs | 1 + .../GalaxyDriver.cs | 28 ++++ .../GalaxyDriverFactoryExtensions.cs | 34 ++++ .../Health/HostConnectivityForwarder.cs | 6 + .../Health/HostStatusAggregator.cs | 3 + .../Health/PerPlatformProbeWatcher.cs | 14 ++ .../Runtime/EventPump.cs | 11 ++ .../Runtime/GalaxyAlarmSubscriptionHandle.cs | 2 + .../Runtime/GalaxyMxSession.cs | 9 ++ .../Runtime/GalaxySubscriptionHandle.cs | 1 + .../Runtime/GalaxyTelemetry.cs | 2 + .../Runtime/GatewayGalaxyAlarmAcknowledger.cs | 8 + .../Runtime/GatewayGalaxyAlarmFeed.cs | 11 ++ .../Runtime/GatewayGalaxyDataWriter.cs | 9 ++ .../Runtime/GatewayGalaxySubscriber.cs | 14 ++ .../Runtime/IGalaxyDataReader.cs | 3 + .../Runtime/IGalaxySubscriber.cs | 6 + .../Runtime/MxAccessSeverityMapper.cs | 1 + .../Runtime/MxValueDecoder.cs | 2 + .../Runtime/MxValueEncoder.cs | 4 + .../Runtime/ReconnectSupervisor.cs | 16 ++ .../Runtime/StatusCodeMap.cs | 8 + .../Runtime/SubscriptionRegistry.cs | 17 ++ .../Runtime/TracedGalaxyDataWriter.cs | 4 + .../Runtime/TracedGalaxySubscriber.cs | 8 + .../Internal/PipeChannel.cs | 16 ++ .../Internal/QualityMapper.cs | 3 + .../Ipc/Contracts.cs | 56 +++++++ .../Ipc/FrameReader.cs | 11 ++ .../Ipc/FrameWriter.cs | 9 ++ .../Ipc/Hello.cs | 11 ++ .../WonderwareHistorianClient.cs | 38 +++++ .../WonderwareHistorianClientOptions.cs | 3 + .../AahClientManagedAlarmEventWriter.cs | 12 ++ .../Backend/HistorianClusterEndpointPicker.cs | 19 +++ .../Backend/HistorianClusterNodeState.cs | 11 ++ .../Backend/HistorianConfiguration.cs | 8 + .../Backend/HistorianDataSource.cs | 44 ++++++ .../Backend/HistorianEventDto.cs | 11 ++ .../Backend/HistorianHealthSnapshot.cs | 14 ++ .../Backend/HistorianQualityMapper.cs | 2 + .../Backend/HistorianSample.cs | 6 +- .../Backend/IAlarmHistorianWriteBackend.cs | 2 + .../Backend/IHistorianConnectionFactory.cs | 13 ++ .../Backend/IHistorianDataSource.cs | 29 ++++ .../Backend/SdkAlarmHistorianWriteBackend.cs | 15 ++ .../Ipc/Contracts.cs | 98 ++++++++++++ .../Ipc/FrameReader.cs | 10 ++ .../Ipc/FrameWriter.cs | 9 ++ .../Ipc/Hello.cs | 9 ++ .../Ipc/HistorianFrameHandler.cs | 11 ++ .../Ipc/PipeAcl.cs | 3 + .../Ipc/PipeServer.cs | 24 +++ .../Program.cs | 3 + .../DirectLogicAddress.cs | 6 + .../MelsecAddress.cs | 7 + .../ModbusAddressParser.cs | 19 +++ .../ModbusModiconAddress.cs | 4 + .../IModbusTransport.cs | 11 ++ .../ModbusDriver.cs | 53 +++++++ .../ModbusDriverFactoryExtensions.cs | 53 ++++++- .../ModbusDriverOptions.cs | 8 + .../ModbusTcpTransport.cs | 16 ++ .../NamespaceMap.cs | 8 + .../OpcUaClientDriver.cs | 73 +++++++++ .../S7AddressParser.cs | 6 + .../ZB.MOM.WW.OtOpcUa.Driver.S7/S7Driver.cs | 66 +++++++- .../S7DriverFactoryExtensions.cs | 29 ++++ .../S7DriverOptions.cs | 3 + .../AdsTwinCATClient.cs | 85 ++++++++++ .../ITwinCATClient.cs | 15 ++ .../TwinCATAmsAddress.cs | 4 + .../TwinCATDataType.cs | 4 + .../TwinCATDriver.cs | 67 ++++++++ .../TwinCATDriverFactoryExtensions.cs | 41 +++++ .../TwinCATDriverOptions.cs | 8 + .../TwinCATStatusMapper.cs | 4 + .../TwinCATSymbolPath.cs | 5 + .../TwinCATSystemSymbolFilter.cs | 3 +- .../Clients/AdminOperationsClient.cs | 6 + .../Clients/FleetDiagnosticsClient.cs | 7 + .../Clients/ServiceCollectionExtensions.cs | 5 + .../EndpointRouteBuilderExtensions.cs | 6 + .../Hubs/AlertSignalRBridge.cs | 9 ++ .../Hubs/FleetStatusSignalRBridge.cs | 6 + .../Hubs/HubRouteBuilderExtensions.cs | 5 + .../Hubs/HubServiceCollectionExtensions.cs | 1 + .../Hubs/ScriptLogSignalRBridge.cs | 5 + .../AdminOperations/AdminOperationsActor.cs | 7 + .../AdminOperations/ConfigComposer.cs | 4 + .../Audit/AuditWriterActor.cs | 8 + .../Coordinators/ConfigPublishCoordinator.cs | 10 ++ .../Fleet/FleetStatusBroadcaster.cs | 8 + .../Redundancy/RedundancyStateActor.cs | 9 ++ .../Redundancy/ServiceLevelCalculator.cs | 3 + .../ServiceCollectionExtensions.cs | 7 +- .../Drivers/DriverFactoryBootstrap.cs | 1 + .../Engines/RoslynScriptedAlarmEvaluator.cs | 9 ++ .../Engines/RoslynVirtualTagEvaluator.cs | 9 ++ .../Health/AdminRoleLeaderHealthCheck.cs | 6 + .../Health/AkkaClusterHealthCheck.cs | 9 ++ .../Health/DatabaseHealthCheck.cs | 9 ++ .../Health/HealthEndpoints.cs | 3 + .../Observability/ObservabilityExtensions.cs | 3 + .../OpcUa/LdapOpcUaUserAuthenticator.cs | 4 + .../OpcUa/OtOpcUaServerHostedService.cs | 19 +++ .../OpcUaApplicationHost.cs | 21 +++ .../OtOpcUaNodeManager.cs | 20 +++ .../Phase7Applier.cs | 7 + .../Phase7Composer.cs | 29 ++++ .../Phase7Plan.cs | 3 + .../SdkAddressSpaceSink.cs | 22 +++ .../SdkServiceLevelPublisher.cs | 5 + .../Security/IOpcUaUserAuthenticator.cs | 16 ++ .../Drivers/DeploymentArtifact.cs | 2 + .../Drivers/DriverHostActor.cs | 29 ++++ .../Drivers/DriverInstanceActor.cs | 18 +++ .../Drivers/DriverSpawnPlan.cs | 2 + .../Health/DbHealthProbeActor.cs | 6 + .../Health/PeerOpcUaProbeActor.cs | 15 ++ .../Historian/HistorianAdapterActor.cs | 5 + .../OpcUa/OpcUaPublishActor.cs | 21 +++ .../ScriptedAlarms/EfAlarmActorStateStore.cs | 10 ++ .../ScriptedAlarms/ScriptedAlarmActor.cs | 14 ++ .../ServiceCollectionExtensions.cs | 2 + .../VirtualTags/DependencyMuxActor.cs | 3 + .../VirtualTags/VirtualTagActor.cs | 18 +++ .../CookieAuthenticationStateProvider.cs | 6 + .../CookieOptions.cs | 1 + .../Endpoints/AuthEndpoints.cs | 4 + .../Jwt/JwtOptions.cs | 2 + .../Jwt/JwtTokenService.cs | 12 ++ .../Ldap/ILdapAuthService.cs | 5 + .../Ldap/LdapAuthService.cs | 12 ++ .../Ldap/LdapOptions.cs | 13 ++ .../Ldap/RoleMapper.cs | 4 + .../ServiceCollectionExtensions.cs | 5 + .../UnwrappedCapabilityCallAnalyzer.cs | 8 + .../AlarmsCommandTests.cs | 6 + .../BrowseCommandTests.cs | 6 + .../CommandBaseTests.cs | 4 + .../CommandRangeValidationTests.cs | 9 ++ .../ConnectCommandTests.cs | 3 + .../EventHandlerLifecycleTests.cs | 2 + .../Fakes/FakeOpcUaClientService.cs | 48 ++++++ .../Fakes/FakeOpcUaClientServiceFactory.cs | 3 + .../HistoryReadCommandTests.cs | 6 + .../InputValidationErrorsTests.cs | 5 + .../LoggerLifecycleTests.cs | 5 + .../NodeIdParserTests.cs | 11 ++ .../ReadCommandTests.cs | 4 + .../RedundancyCommandTests.cs | 4 + .../SubscribeCommandSummaryTests.cs | 8 + .../SubscribeCommandTests.cs | 4 + .../TestConsoleHelper.cs | 4 + .../WriteCommandTests.cs | 4 + .../ClientStoragePathsTests.cs | 5 + .../FakeApplicationConfigurationFactory.cs | 6 + .../Fakes/FakeEndpointDiscovery.cs | 8 + .../Fakes/FakeSessionAdapter.cs | 23 +++ .../Fakes/FakeSessionFactory.cs | 13 ++ .../Fakes/FakeSubscriptionAdapter.cs | 9 ++ .../Helpers/AggregateTypeMapperTests.cs | 10 ++ .../Helpers/FailoverUrlParserTests.cs | 14 ++ .../Helpers/SecurityModeMapperTests.cs | 10 ++ .../Helpers/ValueConverterTests.cs | 21 +++ .../Models/ConnectionSettingsTests.cs | 8 + .../Models/ModelConstructionTests.cs | 11 ++ .../OpcUaClientServiceTests.cs | 1 + .../AlarmsViewModelTests.cs | 13 ++ .../BrowseTreeViewModelTests.cs | 10 ++ .../Fakes/FakeOpcUaClientService.cs | 28 ++++ .../Fakes/FakeOpcUaClientServiceFactory.cs | 4 + .../Fakes/FakeSettingsService.cs | 7 + .../HistoryViewModelTests.cs | 13 ++ .../MainWindowViewModelTests.cs | 1 + .../ReadWriteViewModelTests.cs | 12 ++ .../SubscriptionsViewModelTests.cs | 23 +++ .../HoconLoaderTests.cs | 6 + .../RoleParserTests.cs | 8 + .../AuthorizationTests.cs | 5 + .../DraftValidatorTests.cs | 19 +++ .../DriverHostStatusTests.cs | 3 + .../GenerationSealedCacheTests.cs | 11 ++ .../LdapGroupRoleMappingServiceTests.cs | 11 ++ .../LiteDbConfigCacheTests.cs | 8 + .../NodePermissionsTests.cs | 3 + .../Phase7ScriptingEntitiesTests.cs | 12 ++ .../ResilientConfigReaderTests.cs | 35 +++++ .../SchemaComplianceFixture.cs | 6 + .../SchemaComplianceTests.cs | 9 ++ .../Alarms/AlarmConditionInfoTests.cs | 5 + .../DriverHealthTests.cs | 2 + .../DriverTypeRegistryTests.cs | 32 ++++ .../IHistorianDataSourceContractTests.cs | 19 +++ .../InterfaceIndependenceTests.cs | 4 + .../PollGroupEngineTests.cs | 18 +++ .../SqliteStoreAndForwardSinkTests.cs | 36 +++++ .../FakeUpstream.cs | 21 +++ .../MessageTemplateTests.cs | 12 ++ .../Part9StateMachineTests.cs | 17 ++ .../ScriptedAlarmEngineTests.cs | 58 +++++++ .../ScriptedAlarmSourceTests.cs | 5 + .../CompiledScriptCacheTests.cs | 16 ++ .../DependencyExtractorTests.cs | 18 +++ .../FakeScriptContext.cs | 14 ++ .../ScriptContextTests.cs | 7 + .../ScriptLogCompanionSinkTests.cs | 13 ++ .../ScriptLoggerFactoryTests.cs | 10 ++ .../ScriptSandboxBuildTests.cs | 4 + .../ScriptSandboxTests.cs | 39 +++++ .../TimedScriptEvaluatorTests.cs | 10 ++ .../PermissionTrieBuilderTests.cs | 4 + .../Authorization/PermissionTrieCacheTests.cs | 9 ++ .../Authorization/PermissionTrieTests.cs | 8 + .../TriePermissionEvaluatorTests.cs | 13 ++ .../UserAuthorizationStateTests.cs | 5 + .../DriverHostTests.cs | 60 +++++++ .../GenericDriverNodeManagerTests.cs | 74 +++++++++ .../CapabilityInvokerEnrichmentTests.cs | 5 + .../Observability/DriverHealthReportTests.cs | 9 ++ .../Observability/LogContextEnricherTests.cs | 8 + .../OpcUa/EquipmentNodeWalkerTests.cs | 39 +++++ .../OpcUa/IdentificationFolderBuilderTests.cs | 24 +++ .../Resilience/AlarmSurfaceInvokerTests.cs | 38 +++++ .../Resilience/CapabilityInvokerTests.cs | 6 + .../DriverResilienceOptionsParserTests.cs | 17 ++ .../DriverResilienceOptionsTests.cs | 15 ++ .../DriverResiliencePipelineBuilderTests.cs | 14 ++ .../DriverResilienceStatusTrackerTests.cs | 9 ++ .../FlakeyDriverIntegrationTests.cs | 19 +++ .../Resilience/InFlightCounterTests.cs | 8 + .../PerCallHostResolverDispatchTests.cs | 10 ++ .../Stability/MemoryRecycleTests.cs | 14 ++ .../Stability/MemoryTrackingTests.cs | 13 ++ .../ScheduledRecycleSchedulerTests.cs | 17 ++ .../Stability/WedgeDetectorTests.cs | 10 ++ .../DependencyGraphTests.cs | 32 ++++ .../FakeUpstream.cs | 21 +++ .../TimerTriggerSchedulerTests.cs | 5 + .../VirtualTagEngineTests.cs | 38 +++++ .../VirtualTagSourceTests.cs | 6 + .../AbCipCommandBaseTests.cs | 44 ++++++ .../SubscribeCommandIntervalTests.cs | 4 + .../WriteCommandParseValueTests.cs | 21 +++ .../BuildOptionsTests.cs | 12 ++ .../CommandMetadataTests.cs | 6 + .../WriteCommandParseValueTests.cs | 19 +++ .../SnapshotFormatterTests.cs | 32 +++- .../CommandDisposalConventionsTests.cs | 4 + .../FocasCommandBaseBuildOptionsTests.cs | 8 + .../FocasCommandBaseValidationTests.cs | 13 ++ .../SubscribeCommandConsoleHandlerTests.cs | 2 + .../WriteCommandParseValueTests.cs | 21 +++ .../CommandCancellationTests.cs | 3 + .../ModbusCommandBaseTests.cs | 23 +++ .../ProbeCommandTests.cs | 6 + .../ReadCommandTests.cs | 5 + .../WriteCommandParseValueTests.cs | 12 ++ .../WriteCommandRegionValidationTests.cs | 6 + .../CommandDisposalConventionsTests.cs | 4 + .../S7CommandBaseBuildOptionsTests.cs | 10 ++ ...scribeCommandConsoleHandlerCommentTests.cs | 1 + .../WriteCommandParseValueTests.cs | 21 +++ .../BrowseCommandFilterTests.cs | 10 ++ .../SubscribeCommandMechanismTests.cs | 4 + .../TwinCATCommandBaseTests.cs | 17 ++ .../WriteCommandParseValueTests.cs | 24 +++ .../AbCipReadSmokeTests.cs | 3 + .../AbServerFixture.cs | 9 ++ .../AbServerProfile.cs | 14 +- .../AbServerProfileGate.cs | 1 + .../AbServerProfileTests.cs | 5 + .../Emulate/AbCipEmulateAlmdTests.cs | 1 + .../Emulate/AbCipEmulateUdtReadTests.cs | 1 + .../AbCipAlarmProjectionTests.cs | 6 + .../AbCipBoolInDIntRmwTests.cs | 5 + .../AbCipDriverCodeReviewRegressionTests.cs | 16 ++ .../AbCipDriverDiscoveryTests.cs | 45 ++++++ .../AbCipDriverReadTests.cs | 12 ++ .../AbCipDriverTests.cs | 8 + .../AbCipDriverWholeUdtReadTests.cs | 5 + .../AbCipDriverWriteTests.cs | 17 ++ .../AbCipFetchUdtShapeTests.cs | 34 ++++ .../AbCipHostAddressTests.cs | 13 ++ .../AbCipHostProbeTests.cs | 10 ++ .../AbCipLoggingTests.cs | 22 +++ .../AbCipPerDeviceConnectionOptionsTests.cs | 6 + .../AbCipPlcFamilyTests.cs | 36 ++++- .../AbCipStatusMapperTests.cs | 7 + .../AbCipSubscriptionTests.cs | 7 + .../AbCipTagPathTests.cs | 13 ++ .../AbCipUdtMemberLayoutTests.cs | 5 + .../AbCipUdtMemberTests.cs | 33 +++- .../AbCipUdtReadPlannerTests.cs | 6 + .../CipSymbolObjectDecoderTests.cs | 15 ++ .../CipTemplateObjectDecoderTests.cs | 11 ++ .../FakeAbCipTag.cs | 35 +++++ .../AbLegacyReadSmokeTests.cs | 4 + .../AbLegacyServerFixture.cs | 13 ++ .../AbLegacyAddressTests.cs | 21 +++ .../AbLegacyBitIndexRangeTests.cs | 12 ++ .../AbLegacyBitRmwTests.cs | 4 + .../AbLegacyCapabilityTests.cs | 33 +++- .../AbLegacyDisposeAndResolveHostTests.cs | 12 ++ .../AbLegacyDriverTests.cs | 14 ++ .../AbLegacyHostAndStatusTests.cs | 15 ++ .../AbLegacyLoggerInjectionTests.cs | 11 ++ .../AbLegacyReadWriteTests.cs | 19 +++ .../AbLegacyRuntimeConcurrencyTests.cs | 12 ++ .../FakeAbLegacyTag.cs | 53 +++++++ .../FocasSimFixture.cs | 18 +++ .../Series/WireBackendCoverageTests.cs | 33 +++- .../Series/WireBackendTests.cs | 8 + .../FakeFocasClient.cs | 64 ++++++++ .../FocasAlarmProjectionTests.cs | 4 + .../FocasCapabilityMatrixTests.cs | 26 +++ .../FocasCapabilityTests.cs | 36 ++++- .../FocasDriverMediumFindingsTests.cs | 37 ++++- .../FocasFactoryConfigTests.cs | 12 ++ .../FocasHandleRecycleTests.cs | 2 + .../FocasLoggingTests.cs | 17 ++ .../FocasLowFindingsTests.cs | 23 +++ .../FocasPmcBitRmwTests.cs | 7 + .../FocasReadWriteTests.cs | 15 ++ .../FocasScaffoldingTests.cs | 35 +++++ .../Browse/DataTypeMapTests.cs | 6 + .../Browse/DeployWatcherTests.cs | 33 ++++ .../Browse/GalaxyDiscovererTests.cs | 54 ++++++- ...alaxyDriverAlarmEventArgsExtensionTests.cs | 19 +++ .../GalaxyDriverAlarmSourceTests.cs | 24 +++ .../GalaxyDriverApiKeyResolverTests.cs | 17 ++ .../GalaxyDriverFactoryTests.cs | 16 ++ .../GalaxyDriverInfrastructureTests.cs | 30 ++++ .../Health/HostConnectivityForwarderTests.cs | 5 + .../Health/HostStatusAggregatorTests.cs | 9 ++ .../Health/PerPlatformProbeWatcherTests.cs | 27 ++++ .../Runtime/EventPumpBoundedChannelTests.cs | 24 +++ .../Runtime/EventPumpStreamFaultTests.cs | 26 +++ .../Runtime/GalaxyDriverReadTests.cs | 10 ++ .../Runtime/GalaxyDriverSubscribeTests.cs | 37 +++++ .../Runtime/GalaxyDriverWriteTests.cs | 37 ++++- .../Runtime/GalaxyTelemetryTests.cs | 12 ++ .../Runtime/GatewayGalaxyAlarmFeedTests.cs | 3 + .../Runtime/MxAccessSeverityMapperTests.cs | 5 + .../Runtime/MxValueDecoderTests.cs | 13 ++ .../Runtime/MxValueEncoderTests.cs | 19 +++ .../Runtime/ReconnectSupervisorTests.cs | 9 ++ .../Runtime/StatusCodeMapTests.cs | 16 ++ .../Runtime/SubscriptionRegistryTests.cs | 41 +++++ .../ContractsWireParityTests.cs | 11 ++ .../FakeSidecarServer.cs | 15 ++ .../WonderwareHistorianClientTests.cs | 11 ++ .../AahClientManagedAlarmEventWriterTests.cs | 25 +++ .../HistorianClusterEndpointPickerTests.cs | 7 + ...HistorianDataSourceConnectFailoverTests.cs | 18 +++ .../HistorianDataSourceRequestTimeoutTests.cs | 5 + ...DataSourceStartQueryClassificationTests.cs | 4 + ...storianDataSourceValueAndAggregateTests.cs | 12 ++ .../Backend/HistorianQualityMapperTests.cs | 8 + .../SdkAlarmHistorianWriteBackendTests.cs | 19 +++ .../Ipc/PipeRoundTripTests.cs | 64 ++++++++ .../Ipc/PipeServerSidRejectTests.cs | 7 + .../ProgramAlarmWriterTests.cs | 10 ++ .../ProgramSmokeTests.cs | 1 + .../ModbusAddressEdgeCaseTests.cs | 20 +++ .../ModbusAddressParserTests.cs | 46 ++++++ .../ModbusFamilyParserTests.cs | 20 +++ .../ModbusModiconAddressTests.cs | 11 ++ .../AddressingGrammarTests.cs | 7 + .../DL205/DL205BcdQuirkTests.cs | 1 + .../DL205/DL205CoilMappingTests.cs | 3 + .../DL205/DL205ExceptionCodeTests.cs | 1 + .../DL205/DL205FloatCdabQuirkTests.cs | 1 + .../DL205/DL205Profile.cs | 4 + .../DL205/DL205SmokeTests.cs | 1 + .../DL205/DL205StringQuirkTests.cs | 1 + .../DL205/DL205VMemoryQuirkTests.cs | 2 + .../DL205/DL205XInputTests.cs | 1 + .../ExceptionInjectionTests.cs | 9 ++ .../Mitsubishi/MitsubishiProfile.cs | 3 + .../Mitsubishi/MitsubishiQuirkTests.cs | 7 + .../Mitsubishi/MitsubishiSmokeTests.cs | 1 + .../ModbusSimulatorFixture.cs | 7 + .../S7/S7_1500Profile.cs | 4 + .../S7/S7_1500SmokeTests.cs | 1 + .../S7/S7_ByteOrderTests.cs | 3 + .../DirectLogicAddressTests.cs | 32 ++++ .../MelsecAddressTests.cs | 29 ++++ .../ModbusArrayTests.cs | 32 ++++ .../ModbusBitRmwTests.cs | 15 ++ .../ModbusByteOrderTests.cs | 8 + .../ModbusCapTests.cs | 11 ++ .../ModbusCoalescingAutoRecoveryTests.cs | 11 ++ .../ModbusCoalescingBisectionTests.cs | 24 +++ .../ModbusCoalescingTests.cs | 14 ++ .../ModbusConnectionOptionsTests.cs | 5 + .../ModbusDataTypeTests.cs | 89 +++++++++++ .../ModbusDriverTests.cs | 46 ++++++ .../ModbusEdgeCaseValidationTests.cs | 8 + .../ModbusExceptionMapperTests.cs | 26 +++ .../ModbusLifecycleHygieneTests.cs | 28 ++++ .../ModbusLoggerInjectionTests.cs | 38 ++++- .../ModbusMultiUnitTests.cs | 11 ++ .../ModbusProbeTests.cs | 17 ++ .../ModbusProtocolOptionsTests.cs | 16 ++ .../ModbusSubscribeOptionsTests.cs | 12 ++ .../ModbusSubscriptionTests.cs | 14 ++ .../ModbusTcpReconnectTests.cs | 6 + .../OpcPlcFixture.cs | 9 ++ .../OpcPlcProfile.cs | 3 + .../OpcUaClientSmokeTests.cs | 3 + .../OpcUaClientAlarmTests.cs | 9 ++ .../OpcUaClientAttributeMappingTests.cs | 10 ++ .../OpcUaClientCertAuthTests.cs | 9 ++ .../OpcUaClientDiscoveryTests.cs | 27 ++++ .../OpcUaClientDriverScaffoldTests.cs | 5 + .../OpcUaClientFailoverTests.cs | 5 + .../OpcUaClientHistoryTests.cs | 8 + .../OpcUaClientLowFindingsRegressionTests.cs | 12 ++ ...pcUaClientMediumFindingsRegressionTests.cs | 27 ++++ .../OpcUaClientNamespaceTests.cs | 11 ++ .../OpcUaClientReadWriteTests.cs | 2 + .../OpcUaClientReconnectTests.cs | 3 + .../OpcUaClientSecurityPolicyTests.cs | 6 + .../OpcUaClientSubscribeAndProbeTests.cs | 5 + .../S7_1500/S7_1500Profile.cs | 3 + .../S7_1500/S7_1500SmokeTests.cs | 3 + .../Snap7ServerFixture.cs | 7 + .../S7AddressParserTests.cs | 25 +++ .../S7DiscoveryAndSubscribeTests.cs | 30 ++++ .../S7DriverCodeReviewFixTests.cs | 8 + .../S7DriverCodeReviewFixTests2.cs | 11 ++ .../S7DriverReadWriteTests.cs | 3 + .../S7DriverScaffoldTests.cs | 5 + .../S7TypeMappingTests.cs | 20 +++ .../TwinCAT3SmokeTests.cs | 38 +++++ .../TwinCATXarFixture.cs | 9 ++ .../FakeTwinCATClient.cs | 66 ++++++++ .../TwinCATAmsAddressTests.cs | 11 ++ .../TwinCATCapabilityTests.cs | 34 +++- .../TwinCATDriverTests.cs | 9 ++ .../TwinCATHighFindingsRegressionTests.cs | 9 ++ .../TwinCATLowFindingsRegressionTests.cs | 16 ++ .../TwinCATNativeNotificationTests.cs | 13 ++ .../TwinCATReadWriteTests.cs | 14 ++ .../TwinCATSymbolBrowserTests.cs | 57 ++++++- .../TwinCATSymbolPathTests.cs | 13 ++ .../AdminOperationsActorTests.cs | 2 + .../AuditWriterActorTests.cs | 4 + .../ConfigComposerTests.cs | 4 + .../ConfigPublishCoordinatorTests.cs | 2 + .../ConfigPublishCoordinatorTimeoutTests.cs | 3 + .../FleetStatusBroadcasterTests.cs | 2 + .../Harness/ControlPlaneTestHarness.cs | 7 + .../RedundancyStateActorTests.cs | 2 + .../ServiceLevelCalculatorTests.cs | 8 + .../ClusterFormationTests.cs | 2 + .../DeployHappyPathTests.cs | 2 + .../FailoverDuringDeployTests.cs | 3 + .../FleetDiagnosticsRoundTripTests.cs | 2 + .../LdapOpcUaUserAuthenticatorTests.cs | 15 ++ .../RoslynScriptedAlarmEvaluatorTests.cs | 7 + .../RoslynVirtualTagEvaluatorTests.cs | 6 + .../TwoNodeClusterHarness.cs | 20 +++ .../DualEndpointTests.cs | 1 + .../DeferredAddressSpaceSinkTests.cs | 10 ++ .../DeferredServiceLevelPublisherTests.cs | 6 + .../OpcUaApplicationHostImpersonationTests.cs | 19 +++ .../OpcUaApplicationHostSecurityTests.cs | 21 +++ .../OpcUaApplicationHostServerArrayTests.cs | 3 + .../OpcUaApplicationHostTests.cs | 3 + .../Phase7ApplierHierarchyTests.cs | 20 +++ .../Phase7ApplierTests.cs | 43 +++++ .../Phase7ComposerPurityTests.cs | 4 + .../Phase7PlannerTests.cs | 9 ++ .../SdkAddressSpaceSinkTests.cs | 5 + .../SdkServiceLevelPublisherTests.cs | 3 + .../Drivers/DeploymentArtifactTests.cs | 7 + .../Drivers/DriverHostActorReconcileTests.cs | 25 +++ .../Drivers/DriverHostActorTests.cs | 4 + .../Drivers/DriverInstanceActorTests.cs | 45 ++++++ .../Drivers/DriverSpawnPlannerTests.cs | 7 + .../Harness/RuntimeActorTestBase.cs | 7 + .../Health/HealthProbeActorTests.cs | 10 ++ .../OtOpcUaTelemetryHookTests.cs | 36 ++++- .../OpcUa/OpcUaPublishActorRebuildTests.cs | 21 +++ .../OpcUa/OpcUaPublishActorTests.cs | 33 ++++ .../OpcUa/ServiceLevelEndToEndTests.cs | 2 + .../ScriptedAlarms/ScriptedAlarmActorTests.cs | 19 +++ .../ScriptedAlarmStatePersistenceTests.cs | 14 ++ .../ServiceCollectionExtensionsTests.cs | 15 ++ .../VirtualTags/DependencyMuxActorTests.cs | 10 ++ .../VirtualTags/VirtualTagActorTests.cs | 32 ++++ .../AuthEndpointsIntegrationTests.cs | 14 ++ .../JwtTokenServiceTests.cs | 5 + .../LdapHelperTests.cs | 9 ++ .../RoleMapperTests.cs | 12 ++ .../UnwrappedCapabilityCallAnalyzerTests.cs | 26 +++ 756 files changed, 9876 insertions(+), 96 deletions(-) diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/AlarmsCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/AlarmsCommand.cs index a0a10f79..e2821984 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/AlarmsCommand.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/AlarmsCommand.cs @@ -42,6 +42,7 @@ public class AlarmsCommand : CommandBase /// Connects to the server, subscribes to alarm events, and streams operator-facing alarm state changes to the console. /// /// The CLI console used for output and cancellation handling. + /// public override async ValueTask ExecuteAsync(IConsole console) { ConfigureLogging(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/BrowseCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/BrowseCommand.cs index fda8c057..d4650e1d 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/BrowseCommand.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/BrowseCommand.cs @@ -36,10 +36,7 @@ public class BrowseCommand : CommandBase [CommandOption("recursive", 'r', Description = "Browse recursively (uses --depth as max depth)")] public bool Recursive { get; init; } - /// - /// Connects to the server and prints a tree view of the requested address-space branch. - /// - /// The CLI console used for output and cancellation handling. + /// public override async ValueTask ExecuteAsync(IConsole console) { ConfigureLogging(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ConnectCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ConnectCommand.cs index a246d798..72e2c33e 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ConnectCommand.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ConnectCommand.cs @@ -15,10 +15,7 @@ public class ConnectCommand : CommandBase { } - /// - /// Connects to the server and prints the negotiated endpoint details for operator verification. - /// - /// The CLI console used for output and cancellation handling. + /// public override async ValueTask ExecuteAsync(IConsole console) { ConfigureLogging(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/HistoryReadCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/HistoryReadCommand.cs index 61926bd7..8ea809c4 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/HistoryReadCommand.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/HistoryReadCommand.cs @@ -56,10 +56,7 @@ public class HistoryReadCommand : CommandBase [CommandOption("interval", Description = "Processing interval in milliseconds for aggregates")] public double IntervalMs { get; init; } = 3600000; - /// - /// Connects to the server and prints raw or processed historical values for the requested node. - /// - /// The CLI console used for output and cancellation handling. + /// public override async ValueTask ExecuteAsync(IConsole console) { ConfigureLogging(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ReadCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ReadCommand.cs index 68892786..a8a0ff93 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ReadCommand.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ReadCommand.cs @@ -24,10 +24,7 @@ public class ReadCommand : CommandBase [CommandOption("node", 'n', Description = "Node ID (e.g. ns=2;s=MyNode)", IsRequired = true)] public string NodeId { get; init; } = default!; - /// - /// Connects to the server and prints the current value, status, and timestamps for the requested node. - /// - /// The CLI console used for output and cancellation handling. + /// public override async ValueTask ExecuteAsync(IConsole console) { ConfigureLogging(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/RedundancyCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/RedundancyCommand.cs index fd01b336..3f1a3459 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/RedundancyCommand.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/RedundancyCommand.cs @@ -15,10 +15,8 @@ public class RedundancyCommand : CommandBase { } - /// - /// Connects to the server and prints redundancy mode, service level, and partner-server identity data. - /// - /// The CLI console used for output and cancellation handling. + /// Connects to the server and prints redundancy mode, service level, and partner-server identity data. + /// public override async ValueTask ExecuteAsync(IConsole console) { ConfigureLogging(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/SubscribeCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/SubscribeCommand.cs index 28cccd52..d8c202b3 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/SubscribeCommand.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/SubscribeCommand.cs @@ -67,11 +67,7 @@ public class SubscribeCommand : CommandBase [CommandOption("summary-file", Description = "Write summary to this file path on exit (in addition to stdout)")] public string? SummaryFile { get; init; } - /// - /// Connects to the server, subscribes to (or its subtree when recursive), - /// streams data-change notifications to the console, and prints a summary when the command exits. - /// - /// The CLI console used for output and cancellation handling. + /// public override async ValueTask ExecuteAsync(IConsole console) { ConfigureLogging(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/WriteCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/WriteCommand.cs index d92fa2df..f31a3a34 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/WriteCommand.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/WriteCommand.cs @@ -35,6 +35,7 @@ public class WriteCommand : CommandBase /// Connects to the server, converts the supplied value to the node's current data type, and issues the write. /// /// The CLI console used for output and cancellation handling. + /// public override async ValueTask ExecuteAsync(IConsole console) { ConfigureLogging(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultApplicationConfigurationFactory.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultApplicationConfigurationFactory.cs index 36b5edff..18e683a7 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultApplicationConfigurationFactory.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultApplicationConfigurationFactory.cs @@ -12,6 +12,9 @@ internal sealed class DefaultApplicationConfigurationFactory : IApplicationConfi { private static readonly ILogger Logger = Log.ForContext(); + /// Creates an OPC UA application configuration from the provided connection settings. + /// The connection settings to use. + /// Token to cancel the operation. public async Task CreateAsync(ConnectionSettings settings, CancellationToken ct) { // Resolve the canonical PKI path lazily on first use so constructing a diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultEndpointDiscovery.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultEndpointDiscovery.cs index bcf1997e..a8719460 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultEndpointDiscovery.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultEndpointDiscovery.cs @@ -11,6 +11,10 @@ internal sealed class DefaultEndpointDiscovery : IEndpointDiscovery { private static readonly ILogger Logger = Log.ForContext(); + /// Selects an OPC UA endpoint matching the requested security mode. + /// The application configuration. + /// The endpoint URL to query. + /// The requested message security mode. public EndpointDescription SelectEndpoint(ApplicationConfiguration config, string endpointUrl, MessageSecurityMode requestedMode) { diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultSessionFactory.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultSessionFactory.cs index ecb81dad..4f44bd30 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultSessionFactory.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultSessionFactory.cs @@ -11,6 +11,14 @@ internal sealed class DefaultSessionFactory : ISessionFactory { private static readonly ILogger Logger = Log.ForContext(); + /// Creates a new OPC UA session. + /// The OPC UA application configuration. + /// The endpoint description to connect to. + /// The name for the session. + /// The session timeout in milliseconds. + /// The user identity for the session. + /// The cancellation token. + /// An adapter wrapping the created session. public async Task CreateSessionAsync( ApplicationConfiguration config, EndpointDescription endpoint, diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IApplicationConfigurationFactory.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IApplicationConfigurationFactory.cs index b076bf59..29d8ae30 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IApplicationConfigurationFactory.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IApplicationConfigurationFactory.cs @@ -11,5 +11,7 @@ internal interface IApplicationConfigurationFactory /// /// Creates a validated ApplicationConfiguration for the given connection settings. /// + /// The connection settings to configure. + /// Cancellation token for the operation. Task CreateAsync(ConnectionSettings settings, CancellationToken ct = default); } \ No newline at end of file diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IEndpointDiscovery.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IEndpointDiscovery.cs index bd881fd1..4f802729 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IEndpointDiscovery.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IEndpointDiscovery.cs @@ -11,6 +11,9 @@ internal interface IEndpointDiscovery /// Discovers endpoints at the given URL and returns the best match for the requested security mode. /// Also rewrites the endpoint URL hostname to match the requested URL when they differ. /// + /// The OPC UA application configuration. + /// The endpoint URL to discover. + /// The requested message security mode. EndpointDescription SelectEndpoint(ApplicationConfiguration config, string endpointUrl, MessageSecurityMode requestedMode); } \ No newline at end of file diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/AggregateTypeMapper.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/AggregateTypeMapper.cs index 08fdee57..ab672344 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/AggregateTypeMapper.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/AggregateTypeMapper.cs @@ -11,6 +11,8 @@ public static class AggregateTypeMapper /// /// Returns the OPC UA NodeId for the specified aggregate type. /// + /// The aggregate type to map to a NodeId. + /// The OPC UA NodeId for the aggregate function. public static NodeId ToNodeId(AggregateType aggregate) { return aggregate switch diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/SecurityModeMapper.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/SecurityModeMapper.cs index 1922cb86..d4adb6d6 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/SecurityModeMapper.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/SecurityModeMapper.cs @@ -8,9 +8,9 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Helpers; /// public static class SecurityModeMapper { - /// - /// Converts a to an OPC UA . - /// + /// Converts a SecurityMode to an OPC UA MessageSecurityMode. + /// The security mode to convert. + /// The corresponding message security mode. public static MessageSecurityMode ToMessageSecurityMode(SecurityMode mode) { return mode switch diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/IOpcUaClientServiceFactory.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/IOpcUaClientServiceFactory.cs index 72241959..f80aaaf4 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/IOpcUaClientServiceFactory.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/IOpcUaClientServiceFactory.cs @@ -5,5 +5,7 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared; /// public interface IOpcUaClientServiceFactory { + /// Creates a new OPC UA client service instance. + /// A new instance. IOpcUaClientService Create(); } \ No newline at end of file diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/AlarmEventArgs.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/AlarmEventArgs.cs index 069fa89d..b47e0426 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/AlarmEventArgs.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/AlarmEventArgs.cs @@ -5,6 +5,20 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models; /// public sealed class AlarmEventArgs : EventArgs { + /// Initializes a new instance of the class. + /// The name of the source object that raised the alarm. + /// The condition type name. + /// The alarm severity (0-1000). + /// Human-readable alarm message. + /// Whether the alarm should be retained in the display. + /// Whether the alarm condition is currently active. + /// Whether the alarm has been acknowledged. + /// The time the event occurred. + /// The EventId used for alarm acknowledgment. + /// The NodeId of the condition instance. + /// Operator-supplied comment on acknowledgment transitions. + /// When the alarm originally entered the active state. + /// Upstream alarm taxonomy bucket (e.g. Process, Safety, Diagnostics). public AlarmEventArgs( string sourceName, string conditionName, diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/BrowseResult.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/BrowseResult.cs index a8191e37..4e3658f8 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/BrowseResult.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/BrowseResult.cs @@ -5,6 +5,11 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models; /// public sealed class BrowseResult { + /// Initializes a new instance of the BrowseResult class. + /// The string representation of the node's NodeId. + /// The display name of the node. + /// The node class (e.g., "Object", "Variable", "Method"). + /// Whether the node has child references. public BrowseResult(string nodeId, string displayName, string nodeClass, bool hasChildren) { NodeId = nodeId; diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionInfo.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionInfo.cs index 39bc0f49..1bf96318 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionInfo.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionInfo.cs @@ -5,6 +5,13 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models; /// public sealed class ConnectionInfo { + /// Initializes a new instance of the ConnectionInfo with session details. + /// The endpoint URL of the connected server. + /// The server application name. + /// The security mode in use. + /// The security policy URI. + /// The session identifier. + /// The session name. public ConnectionInfo( string endpointUrl, string serverName, diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionStateChangedEventArgs.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionStateChangedEventArgs.cs index 5949073e..449ae2a2 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionStateChangedEventArgs.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionStateChangedEventArgs.cs @@ -5,6 +5,10 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models; /// public sealed class ConnectionStateChangedEventArgs : EventArgs { + /// Initializes a new instance of the ConnectionStateChangedEventArgs class. + /// The previous connection state. + /// The new connection state. + /// The endpoint URL associated with the state change. public ConnectionStateChangedEventArgs(ConnectionState oldState, ConnectionState newState, string endpointUrl) { OldState = oldState; diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/DataChangedEventArgs.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/DataChangedEventArgs.cs index 30660495..719a92ff 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/DataChangedEventArgs.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/DataChangedEventArgs.cs @@ -7,6 +7,9 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models; /// public sealed class DataChangedEventArgs : EventArgs { + /// Initializes a new instance of the DataChangedEventArgs class. + /// The node ID that changed. + /// The new data value. public DataChangedEventArgs(string nodeId, DataValue value) { NodeId = nodeId; diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/RedundancyInfo.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/RedundancyInfo.cs index 1a376235..c6c3a339 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/RedundancyInfo.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/RedundancyInfo.cs @@ -5,6 +5,11 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models; /// public sealed class RedundancyInfo { + /// Initializes a new instance of the RedundancyInfo class. + /// The redundancy mode (e.g., "None", "Cold", "Warm", "Hot"). + /// The server's current service level (0-255). + /// URIs of all servers in the redundant set. + /// The application URI of the connected server. public RedundancyInfo(string mode, byte serviceLevel, string[] serverUris, string applicationUri) { Mode = mode; diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/OpcUaClientServiceFactory.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/OpcUaClientServiceFactory.cs index fee69237..e5107664 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/OpcUaClientServiceFactory.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/OpcUaClientServiceFactory.cs @@ -5,6 +5,8 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared; /// public sealed class OpcUaClientServiceFactory : IOpcUaClientServiceFactory { + /// Creates a new OPC UA client service instance with production adapters. + /// A new OpcUaClientService instance. public IOpcUaClientService Create() { return new OpcUaClientService(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/App.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/App.axaml.cs index 979be387..43d2bb87 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/App.axaml.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/App.axaml.cs @@ -10,11 +10,13 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI; public class App : Application { + /// public override void Initialize() { AvaloniaXamlLoader.Load(this); } + /// public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Controls/DateTimeRangePicker.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Controls/DateTimeRangePicker.axaml.cs index 39a2473b..89ef445b 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Controls/DateTimeRangePicker.axaml.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Controls/DateTimeRangePicker.axaml.cs @@ -32,35 +32,41 @@ public partial class DateTimeRangePicker : UserControl private bool _isUpdating; + /// Initializes a new instance of the class. public DateTimeRangePicker() { InitializeComponent(); } + /// Gets or sets the start date and time. public DateTimeOffset? StartDateTime { get => GetValue(StartDateTimeProperty); set => SetValue(StartDateTimeProperty, value); } + /// Gets or sets the end date and time. public DateTimeOffset? EndDateTime { get => GetValue(EndDateTimeProperty); set => SetValue(EndDateTimeProperty, value); } + /// Gets or sets the start date/time as formatted text. public string StartText { get => GetValue(StartTextProperty); set => SetValue(StartTextProperty, value); } + /// Gets or sets the end date/time as formatted text. public string EndText { get => GetValue(EndTextProperty); set => SetValue(EndTextProperty, value); } + /// protected override void OnLoaded(RoutedEventArgs e) { base.OnLoaded(e); @@ -82,6 +88,7 @@ public partial class DateTimeRangePicker : UserControl if (lastWeek != null) lastWeek.Click += (_, _) => ApplyPreset(TimeSpan.FromDays(7)); } + /// protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { base.OnPropertyChanged(change); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/StatusCodeFormatter.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/StatusCodeFormatter.cs index 7aaf524d..2a43d215 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/StatusCodeFormatter.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/StatusCodeFormatter.cs @@ -7,6 +7,9 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Helpers; /// internal static class StatusCodeFormatter { + /// Formats an OPC UA status code as a hexadecimal code with description. + /// The OPC UA status code to format. + /// A formatted string in the form "0xHEX (description)". public static string Format(StatusCode statusCode) { var code = statusCode.Code; diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/ValueFormatter.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/ValueFormatter.cs index 07343a6d..9956d027 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/ValueFormatter.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/ValueFormatter.cs @@ -7,6 +7,9 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Helpers; /// internal static class ValueFormatter { + /// Formats an OPC UA value for display, handling arrays and enumerables specially. + /// The value to format, or null. + /// A string representation of the value suitable for display. public static string Format(object? value) { if (value is null) return "(null)"; diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Program.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Program.cs index 6013f980..506d0d44 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Program.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Program.cs @@ -4,8 +4,11 @@ using ZB.MOM.WW.OtOpcUa.Client.Shared; namespace ZB.MOM.WW.OtOpcUa.Client.UI; +/// Entry point for the OPC UA client UI application. public class Program { + /// Main entry point for the application. + /// Command-line arguments passed to the application. [STAThread] public static void Main(string[] args) { @@ -21,6 +24,8 @@ public class Program } } + /// Builds the Avalonia AppBuilder with platform-specific configuration. + /// Configured AppBuilder for desktop lifetime. public static AppBuilder BuildAvaloniaApp() { return AppBuilder.Configure() diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/AvaloniaUiDispatcher.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/AvaloniaUiDispatcher.cs index 30b81729..13275830 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/AvaloniaUiDispatcher.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/AvaloniaUiDispatcher.cs @@ -7,6 +7,8 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Services; /// public sealed class AvaloniaUiDispatcher : IUiDispatcher { + /// Posts an action to the Avalonia UI thread for execution. + /// The action to execute on the UI thread. public void Post(Action action) { Dispatcher.UIThread.Post(action); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/ISettingsService.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/ISettingsService.cs index 20563651..f95c56c0 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/ISettingsService.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/ISettingsService.cs @@ -5,6 +5,9 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Services; /// public interface ISettingsService { + /// Loads user settings from persistent storage. UserSettings Load(); + /// Saves user settings to persistent storage. + /// The settings to save. void Save(UserSettings settings); } diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/IUiDispatcher.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/IUiDispatcher.cs index 46d0dc5c..a22c3087 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/IUiDispatcher.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/IUiDispatcher.cs @@ -8,5 +8,6 @@ public interface IUiDispatcher /// /// Posts an action to be executed on the UI thread. /// + /// The action to execute on the UI thread. void Post(Action action); } \ No newline at end of file diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/JsonSettingsService.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/JsonSettingsService.cs index d2b418a9..2f793cad 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/JsonSettingsService.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/JsonSettingsService.cs @@ -19,6 +19,8 @@ public sealed class JsonSettingsService : ISettingsService WriteIndented = true }; + /// Loads user settings from the settings file. + /// The loaded user settings, or a new default instance if load fails. public UserSettings Load() { try @@ -35,6 +37,8 @@ public sealed class JsonSettingsService : ISettingsService } } + /// Saves user settings to the settings file. + /// The user settings to save. public void Save(UserSettings settings) { try diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/SynchronousUiDispatcher.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/SynchronousUiDispatcher.cs index 46772cec..06c5f6bc 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/SynchronousUiDispatcher.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/SynchronousUiDispatcher.cs @@ -6,6 +6,8 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Services; /// public sealed class SynchronousUiDispatcher : IUiDispatcher { + /// Executes the action synchronously on the calling thread. + /// The action to execute. public void Post(Action action) { action(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/AlarmsViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/AlarmsViewModel.cs index db20fadf..f7033901 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/AlarmsViewModel.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/AlarmsViewModel.cs @@ -44,6 +44,9 @@ public partial class AlarmsViewModel : ObservableObject [ObservableProperty] private int _activeAlarmCount; + /// Initializes a new instance of the AlarmsViewModel class. + /// The OPC UA client service. + /// The UI dispatcher for thread-safe operations. public AlarmsViewModel(IOpcUaClientService service, IUiDispatcher dispatcher) { _service = service; @@ -168,6 +171,9 @@ public partial class AlarmsViewModel : ObservableObject /// /// Acknowledges an alarm and returns (success, message). /// + /// The alarm event to acknowledge. + /// Optional comment for the acknowledgment. + /// A tuple with success flag and message. public async Task<(bool Success, string Message)> AcknowledgeAlarmAsync(AlarmEventViewModel alarm, string comment) { if (!IsConnected || alarm.EventId == null || alarm.ConditionNodeId == null) @@ -197,6 +203,8 @@ public partial class AlarmsViewModel : ObservableObject /// /// Restores an alarm subscription and requests a condition refresh. /// + /// The source node ID to restore the subscription for. + /// A task that completes when the restore operation finishes. public async Task RestoreAlarmSubscriptionAsync(string? sourceNodeId) { if (!IsConnected || string.IsNullOrWhiteSpace(sourceNodeId)) return; diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/BrowseTreeViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/BrowseTreeViewModel.cs index f19281ec..6ca20cbf 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/BrowseTreeViewModel.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/BrowseTreeViewModel.cs @@ -13,6 +13,11 @@ public class BrowseTreeViewModel : ObservableObject private readonly IUiDispatcher _dispatcher; private readonly IOpcUaClientService _service; + /// + /// Initializes a new instance of the class. + /// + /// The OPC UA client service. + /// The UI dispatcher for marshaling updates. public BrowseTreeViewModel(IOpcUaClientService service, IUiDispatcher dispatcher) { _service = service; diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryValueViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryValueViewModel.cs index a128ae21..04abe5a7 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryValueViewModel.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryValueViewModel.cs @@ -7,6 +7,11 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.ViewModels; /// public class HistoryValueViewModel : ObservableObject { + /// Initializes a new instance of the class. + /// The historical value. + /// The status code or text. + /// The source timestamp in string format. + /// The server timestamp in string format. public HistoryValueViewModel(string value, string status, string sourceTimestamp, string serverTimestamp) { Value = value; @@ -15,8 +20,12 @@ public class HistoryValueViewModel : ObservableObject ServerTimestamp = serverTimestamp; } + /// Gets the historical value. public string Value { get; } + /// Gets the status code or text. public string Status { get; } + /// Gets the source timestamp in string format. public string SourceTimestamp { get; } + /// Gets the server timestamp in string format. public string ServerTimestamp { get; } } \ No newline at end of file diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryViewModel.cs index d828dfa3..dbc82b1c 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryViewModel.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryViewModel.cs @@ -34,6 +34,9 @@ public partial class HistoryViewModel : ObservableObject [ObservableProperty] private DateTimeOffset? _startTime = DateTimeOffset.UtcNow.AddHours(-1); + /// Initializes a new instance of the HistoryViewModel. + /// The OPC UA client service. + /// The UI dispatcher for thread marshalling. public HistoryViewModel(IOpcUaClientService service, IUiDispatcher dispatcher) { _service = service; @@ -53,6 +56,7 @@ public partial class HistoryViewModel : ObservableObject AggregateType.StandardDeviation ]; + /// Gets a value indicating whether an aggregate read is selected. public bool IsAggregateRead => SelectedAggregateType != null; /// History read results. diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/ReadWriteViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/ReadWriteViewModel.cs index 6d94913e..cbad31d0 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/ReadWriteViewModel.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/ReadWriteViewModel.cs @@ -36,12 +36,16 @@ public partial class ReadWriteViewModel : ObservableObject [ObservableProperty] private string? _writeValue; + /// Initializes a new instance of the ReadWriteViewModel class. + /// The OPC UA client service for read/write operations. + /// The UI dispatcher for posting updates to the UI thread. public ReadWriteViewModel(IOpcUaClientService service, IUiDispatcher dispatcher) { _service = service; _dispatcher = dispatcher; } + /// Gets a value indicating whether a node is currently selected. public bool IsNodeSelected => !string.IsNullOrEmpty(SelectedNodeId); partial void OnSelectedNodeIdChanged(string? value) diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/SubscriptionItemViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/SubscriptionItemViewModel.cs index c14c7bd3..f8af20dc 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/SubscriptionItemViewModel.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/SubscriptionItemViewModel.cs @@ -13,6 +13,9 @@ public partial class SubscriptionItemViewModel : ObservableObject [ObservableProperty] private string? _value; + /// Initializes a new subscription item with the specified node ID and interval. + /// The OPC UA NodeId to subscribe to. + /// The subscription interval in milliseconds. public SubscriptionItemViewModel(string nodeId, int intervalMs) { NodeId = nodeId; diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/TreeNodeViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/TreeNodeViewModel.cs index 492b7c6a..7e7cefd2 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/TreeNodeViewModel.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/TreeNodeViewModel.cs @@ -31,6 +31,13 @@ public partial class TreeNodeViewModel : ObservableObject HasChildren = false; } + /// Initializes a new tree node view model. + /// The OPC UA node identifier. + /// The display name for this node. + /// The OPC UA node class. + /// Whether this node has child nodes. + /// The OPC UA client service for browsing. + /// The UI dispatcher for thread-safe updates. public TreeNodeViewModel( string nodeId, string displayName, diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AckAlarmWindow.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AckAlarmWindow.axaml.cs index 79f69a3c..0ea27bbe 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AckAlarmWindow.axaml.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AckAlarmWindow.axaml.cs @@ -10,6 +10,7 @@ public partial class AckAlarmWindow : Window private readonly AlarmsViewModel _alarmsVm; private readonly AlarmEventViewModel _alarm; + /// Initializes a new instance of the AckAlarmWindow class for XAML designer support. public AckAlarmWindow() { InitializeComponent(); @@ -17,6 +18,9 @@ public partial class AckAlarmWindow : Window _alarm = null!; } + /// Initializes a new instance of the AckAlarmWindow class with alarm context. + /// The alarms view model. + /// The alarm event to acknowledge. public AckAlarmWindow(AlarmsViewModel alarmsVm, AlarmEventViewModel alarm) { InitializeComponent(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AlarmsView.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AlarmsView.axaml.cs index 4fc6b51f..10d902c2 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AlarmsView.axaml.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AlarmsView.axaml.cs @@ -16,11 +16,13 @@ public partial class AlarmsView : UserControl private static readonly IBrush HighBrush = new SolidColorBrush(Color.Parse("#FEE2E2")); // light red (666-899) private static readonly IBrush CriticalBrush = new SolidColorBrush(Color.Parse("#FECACA")); // red (900-1000) + /// Initializes a new instance of the class. public AlarmsView() { InitializeComponent(); } + /// protected override void OnLoaded(RoutedEventArgs e) { base.OnLoaded(e); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/BrowseTreeView.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/BrowseTreeView.axaml.cs index 5432f962..6a365047 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/BrowseTreeView.axaml.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/BrowseTreeView.axaml.cs @@ -4,6 +4,7 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Views; public partial class BrowseTreeView : UserControl { + /// Initializes a new instance of the BrowseTreeView. public BrowseTreeView() { InitializeComponent(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/HistoryView.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/HistoryView.axaml.cs index ebe3d59c..f20beae3 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/HistoryView.axaml.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/HistoryView.axaml.cs @@ -4,6 +4,7 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Views; public partial class HistoryView : UserControl { + /// Initializes a new instance of the HistoryView control. public HistoryView() { InitializeComponent(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/MainWindow.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/MainWindow.axaml.cs index 57516d2e..02da7bde 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/MainWindow.axaml.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/MainWindow.axaml.cs @@ -11,6 +11,7 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Views; public partial class MainWindow : Window { + /// Initializes a new instance of the MainWindow, loading the application icon. public MainWindow() { InitializeComponent(); @@ -51,6 +52,7 @@ public partial class MainWindow : Window } } + /// protected override void OnLoaded(RoutedEventArgs e) { base.OnLoaded(e); @@ -157,6 +159,7 @@ public partial class MainWindow : Window vm.CertificateStorePath = picked; } + /// protected override void OnClosing(WindowClosingEventArgs e) { if (DataContext is MainWindowViewModel vm) diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/ReadWriteView.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/ReadWriteView.axaml.cs index 4f4326dd..7edbaa72 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/ReadWriteView.axaml.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/ReadWriteView.axaml.cs @@ -4,6 +4,7 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Views; public partial class ReadWriteView : UserControl { + /// Initializes a new instance of the ReadWriteView class. public ReadWriteView() { InitializeComponent(); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/SubscriptionsView.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/SubscriptionsView.axaml.cs index 9dd248c7..d71aa06c 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/SubscriptionsView.axaml.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/SubscriptionsView.axaml.cs @@ -8,11 +8,13 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Views; public partial class SubscriptionsView : UserControl { + /// Initializes a new instance of the class. public SubscriptionsView() { InitializeComponent(); } + /// protected override void OnLoaded(RoutedEventArgs e) { base.OnLoaded(e); diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/WriteValueWindow.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/WriteValueWindow.axaml.cs index 8d629b98..d0d5ee3d 100644 --- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/WriteValueWindow.axaml.cs +++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/WriteValueWindow.axaml.cs @@ -10,6 +10,7 @@ public partial class WriteValueWindow : Window private readonly SubscriptionsViewModel _subscriptionsVm; private readonly string _nodeId; + /// Initializes a default instance of the WriteValueWindow for XAML designer support. public WriteValueWindow() { InitializeComponent(); @@ -17,6 +18,10 @@ public partial class WriteValueWindow : Window _nodeId = string.Empty; } + /// Initializes a WriteValueWindow with the node to write and its current value. + /// The subscriptions view model for write operations. + /// The OPC UA node ID to write to. + /// The current value of the node, or null if unknown. public WriteValueWindow(SubscriptionsViewModel subscriptionsVm, string nodeId, string? currentValue) { InitializeComponent(); diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/AkkaClusterOptions.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/AkkaClusterOptions.cs index 89a7cc7b..9e46b0fa 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/AkkaClusterOptions.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/AkkaClusterOptions.cs @@ -4,8 +4,13 @@ public sealed class AkkaClusterOptions { public const string SectionName = "Cluster"; + /// Gets or sets the Akka system name. public string SystemName { get; set; } = "otopcua"; + + /// Gets or sets the hostname to bind to (default 0.0.0.0). public string Hostname { get; set; } = "0.0.0.0"; + + /// Gets or sets the port to listen on (default 4053). public int Port { get; set; } = 4053; /// @@ -15,6 +20,7 @@ public sealed class AkkaClusterOptions /// public string PublicHostname { get; set; } = "127.0.0.1"; + /// Gets or sets the seed nodes for cluster bootstrapping. public string[] SeedNodes { get; set; } = Array.Empty(); /// diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ClusterRoleInfo.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ClusterRoleInfo.cs index ef1a1455..512be105 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ClusterRoleInfo.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ClusterRoleInfo.cs @@ -25,6 +25,10 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable private readonly Dictionary> _membersByRole = new(StringComparer.Ordinal); private IActorRef? _subscriber; + /// Initializes a new instance of the ClusterRoleInfo class. + /// The Akka actor system. + /// The cluster configuration options. + /// The logger instance. public ClusterRoleInfo(ActorSystem system, IOptions options, ILogger logger) { _cluster = Akka.Cluster.Cluster.Get(system); @@ -39,12 +43,20 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable _subscriber = system.ActorOf(Props.Create(() => new SubscriberActor(this)), "clusterroleinfo-subscriber"); } + /// Gets the local cluster node identifier. public CommonsNodeId LocalNode => _localNode; + /// Gets the set of roles assigned to the local node. public IReadOnlySet LocalRoles => _localRoles; + /// Checks if the local node has a specific role. + /// The role name to check. + /// True if the local node has the specified role; otherwise false. public bool HasRole(string role) => _localRoles.Contains(role); + /// Gets all cluster members that have a specific role. + /// The role name. + /// A read-only list of node IDs with the specified role. public IReadOnlyList MembersWithRole(string role) { lock (_lock) @@ -56,6 +68,9 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable } } + /// Gets the current leader node for a specific role. + /// The role name. + /// The node ID of the current role leader, or null if no leader is elected. public CommonsNodeId? RoleLeader(string role) { lock (_lock) @@ -66,6 +81,7 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable } } + /// Occurs when the leader for a role changes. public event EventHandler? RoleLeaderChanged; private void SeedFromCurrentState() @@ -91,6 +107,8 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable } } + /// Handles a cluster member event (member up/removed). + /// The member event from the cluster. internal void HandleMemberEvent(ClusterEvent.IMemberEvent evt) { lock (_lock) @@ -114,6 +132,8 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable } } + /// Handles a role leader change event. + /// The role leader changed event from the cluster. internal void HandleRoleLeaderChanged(ClusterEvent.RoleLeaderChanged evt) { CommonsNodeId? previous = null; @@ -156,6 +176,7 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable private static CommonsNodeId ToNodeId(Akka.Actor.Address address) => CommonsNodeId.Parse($"{address.Host ?? string.Empty}:{address.Port ?? 0}"); + /// Disposes the ClusterRoleInfo and stops the subscriber actor. public void Dispose() { _subscriber?.Tell(PoisonPill.Instance); @@ -164,6 +185,8 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable private sealed class SubscriberActor : ReceiveActor { + /// Initializes a new instance of the SubscriberActor class. + /// The ClusterRoleInfo instance to forward events to. public SubscriberActor(ClusterRoleInfo owner) { Receive(e => owner.HandleMemberEvent(e)); @@ -172,6 +195,7 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable Receive(_ => { /* seeded from initial snapshot */ }); } + /// protected override void PreStart() { Akka.Cluster.Cluster.Get(Context.System).Subscribe( @@ -182,6 +206,7 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable typeof(ClusterEvent.RoleLeaderChanged)); } + /// protected override void PostStop() => Akka.Cluster.Cluster.Get(Context.System).Unsubscribe(Self); } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/HoconLoader.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/HoconLoader.cs index 23f1b00c..d3448416 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/HoconLoader.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/HoconLoader.cs @@ -1,9 +1,12 @@ namespace ZB.MOM.WW.OtOpcUa.Cluster; +/// Loads embedded HOCON configuration resources. public static class HoconLoader { private const string ResourceName = "ZB.MOM.WW.OtOpcUa.Cluster.Resources.akka.conf"; + /// Loads the base Akka configuration from embedded resources. + /// The loaded HOCON configuration as a string. public static string LoadBaseConfig() { using var stream = typeof(HoconLoader).Assembly.GetManifestResourceStream(ResourceName) diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/RoleParser.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/RoleParser.cs index c233a19c..a2de2290 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/RoleParser.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/RoleParser.cs @@ -7,6 +7,8 @@ public static class RoleParser "admin", "driver", "dev", }; + /// Parses a comma-separated string of role names into a validated array. + /// The raw role string to parse. public static string[] Parse(string? raw) { if (string.IsNullOrWhiteSpace(raw)) return Array.Empty(); diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ServiceCollectionExtensions.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ServiceCollectionExtensions.cs index eb743d0b..e2bab992 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ServiceCollectionExtensions.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ServiceCollectionExtensions.cs @@ -16,6 +16,8 @@ public static class ServiceCollectionExtensions /// configurator via — keeping the entire Akka graph /// under Akka.Hosting's management so cluster singletons land on the same ActorSystem. /// + /// The service collection to configure. + /// The application configuration containing cluster options. public static IServiceCollection AddOtOpcUaCluster(this IServiceCollection services, IConfiguration configuration) { services.AddOptions() @@ -41,6 +43,8 @@ public static class ServiceCollectionExtensions /// }); /// /// + /// The Akka configuration builder to configure. + /// The service provider for resolving cluster options. public static AkkaConfigurationBuilder WithOtOpcUaClusterBootstrap( this AkkaConfigurationBuilder builder, IServiceProvider serviceProvider) diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IAlarmActorStateStore.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IAlarmActorStateStore.cs index d84d3821..56b195a4 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IAlarmActorStateStore.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IAlarmActorStateStore.cs @@ -10,7 +10,14 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Engines; /// public interface IAlarmActorStateStore { + /// Loads the persisted state snapshot for an alarm actor. + /// The alarm identifier. + /// Cancellation token. + /// The alarm state snapshot if found; null if the alarm has no persisted state. Task LoadAsync(string alarmId, CancellationToken ct); + /// Saves the alarm actor state snapshot. + /// The state snapshot to persist. + /// Cancellation token. Task SaveAsync(AlarmActorStateSnapshot snapshot, CancellationToken ct); } @@ -34,8 +41,14 @@ public sealed class NullAlarmActorStateStore : IAlarmActorStateStore { public static readonly NullAlarmActorStateStore Instance = new(); private NullAlarmActorStateStore() { } + /// Always returns null, indicating no persisted state. + /// The alarm identifier (unused). + /// Cancellation token (unused). public Task LoadAsync(string alarmId, CancellationToken ct) => Task.FromResult(null); + /// Completes immediately without persisting anything. + /// The state snapshot (ignored). + /// Cancellation token (unused). public Task SaveAsync(AlarmActorStateSnapshot snapshot, CancellationToken ct) => Task.CompletedTask; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IScriptedAlarmEvaluator.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IScriptedAlarmEvaluator.cs index b1239364..6ad1464e 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IScriptedAlarmEvaluator.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IScriptedAlarmEvaluator.cs @@ -8,6 +8,11 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Engines; /// public interface IScriptedAlarmEvaluator { + /// Evaluates an alarm predicate against the provided dependencies. + /// The unique identifier of the alarm being evaluated. + /// The predicate expression to evaluate. + /// Read-only dictionary of variable names to values for predicate evaluation. + /// Result containing success flag, alarm active state, and optional failure reason. ScriptedAlarmEvalResult Evaluate(string alarmId, string predicate, IReadOnlyDictionary dependencies); } @@ -15,7 +20,14 @@ public interface IScriptedAlarmEvaluator /// Success is true; on failure the caller should keep the prior state and log Reason. public sealed record ScriptedAlarmEvalResult(bool Success, bool Active, string? Reason) { + /// Creates a successful alarm evaluation result with the given active state. + /// Whether the alarm condition is active. + /// A successful evaluation result. public static ScriptedAlarmEvalResult Ok(bool active) => new(true, active, null); + + /// Creates a failed alarm evaluation result with the given reason. + /// Description of the evaluation failure cause. + /// A failed evaluation result. public static ScriptedAlarmEvalResult Failure(string reason) => new(false, false, reason); } @@ -25,6 +37,11 @@ public sealed class NullScriptedAlarmEvaluator : IScriptedAlarmEvaluator { public static readonly NullScriptedAlarmEvaluator Instance = new(); private NullScriptedAlarmEvaluator() { } + /// Returns an inactive alarm result for every evaluation (safe no-op behavior). + /// The alarm identifier (ignored). + /// The predicate expression (ignored). + /// The variable dependencies (ignored). + /// Always returns an inactive alarm result. public ScriptedAlarmEvalResult Evaluate(string alarmId, string predicate, IReadOnlyDictionary dependencies) => ScriptedAlarmEvalResult.Ok(active: false); } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IVirtualTagEvaluator.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IVirtualTagEvaluator.cs index ce0d15e4..023b48cf 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IVirtualTagEvaluator.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IVirtualTagEvaluator.cs @@ -13,6 +13,10 @@ public interface IVirtualTagEvaluator /// . Implementations must not throw — script failures /// are reported via . /// + /// The unique identifier of the virtual tag being evaluated. + /// The expression string to evaluate. + /// Read-only dictionary of variable names to values for expression evaluation. + /// Result containing success flag, evaluated value, and optional failure reason. VirtualTagEvalResult Evaluate(string virtualTagId, string expression, IReadOnlyDictionary dependencies); } @@ -21,7 +25,15 @@ public interface IVirtualTagEvaluator public sealed record VirtualTagEvalResult(bool Success, object? Value, string? Reason) { public static readonly VirtualTagEvalResult NoChange = new(true, null, "no-change"); + + /// Creates a successful evaluation result with the given value. + /// The evaluated value. + /// A successful evaluation result. public static VirtualTagEvalResult Ok(object? value) => new(true, value, null); + + /// Creates a failed evaluation result with the given reason. + /// Description of the failure cause. + /// A failed evaluation result. public static VirtualTagEvalResult Failure(string reason) => new(false, null, reason); } @@ -31,6 +43,11 @@ public sealed class NullVirtualTagEvaluator : IVirtualTagEvaluator { public static readonly NullVirtualTagEvaluator Instance = new(); private NullVirtualTagEvaluator() { } + /// Returns for every evaluation. + /// The virtual tag identifier (ignored). + /// The expression string (ignored). + /// The variable dependencies (ignored). + /// Always returns . public VirtualTagEvalResult Evaluate(string virtualTagId, string expression, IReadOnlyDictionary dependencies) => VirtualTagEvalResult.NoChange; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IAdminOperationsClient.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IAdminOperationsClient.cs index 3a099867..3957b121 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IAdminOperationsClient.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IAdminOperationsClient.cs @@ -9,5 +9,9 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Interfaces; /// public interface IAdminOperationsClient { + /// Starts a new deployment on the cluster-singleton admin operations actor. + /// The user or system identifier triggering the deployment. + /// The cancellation token. + /// A task representing the asynchronous operation containing the deployment start result. Task StartDeploymentAsync(string createdBy, CancellationToken ct); } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IClusterRoleInfo.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IClusterRoleInfo.cs index 29c1dc1a..927c0754 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IClusterRoleInfo.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IClusterRoleInfo.cs @@ -10,11 +10,23 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Interfaces; /// public interface IClusterRoleInfo { + /// Gets the local cluster node identifier. NodeId LocalNode { get; } + /// Gets the set of roles assigned to the local node. IReadOnlySet LocalRoles { get; } + /// Checks if the local node has the specified role. + /// Role name to check. + /// True if the local node has the role; otherwise, false. bool HasRole(string role); + /// Gets all nodes assigned to the specified role. + /// Role name to query. + /// List of node identifiers with the role. IReadOnlyList MembersWithRole(string role); + /// Gets the leader node for the specified role, or null if no leader is elected. + /// Role name to query. + /// The leader node identifier, or null if no leader exists. NodeId? RoleLeader(string role); + /// Occurs when the leader of a role changes. event EventHandler? RoleLeaderChanged; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IFleetDiagnosticsClient.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IFleetDiagnosticsClient.cs index cab512ac..262cf795 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IFleetDiagnosticsClient.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IFleetDiagnosticsClient.cs @@ -8,5 +8,8 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Interfaces; /// public interface IFleetDiagnosticsClient { + /// Gets diagnostics for the specified node. + /// The node ID to retrieve diagnostics for. + /// The cancellation token. Task GetDiagnosticsAsync(NodeId nodeId, CancellationToken ct); } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/RoleLeaderChangedEventArgs.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/RoleLeaderChangedEventArgs.cs index 50fb8f12..2ccf85e3 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/RoleLeaderChangedEventArgs.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/RoleLeaderChangedEventArgs.cs @@ -2,9 +2,15 @@ using ZB.MOM.WW.OtOpcUa.Commons.Types; namespace ZB.MOM.WW.OtOpcUa.Commons.Interfaces; +/// Event arguments for role leader change notifications. public sealed class RoleLeaderChangedEventArgs : EventArgs { + /// Gets the role name that changed leadership. public required string Role { get; init; } + + /// Gets the previous leader node ID, or null if there was no previous leader. public required NodeId? PreviousLeader { get; init; } + + /// Gets the new leader node ID, or null if the role is now leaderless. public required NodeId? NewLeader { get; init; } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Observability/OtOpcUaTelemetry.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Observability/OtOpcUaTelemetry.cs index efb99090..1a284860 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Observability/OtOpcUaTelemetry.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Observability/OtOpcUaTelemetry.cs @@ -68,6 +68,7 @@ public static class OtOpcUaTelemetry /// Starts a deploy span tagged with the deployment id. Caller disposes to close. Returns /// null when no listener is attached so the call site stays cheap on undecorated builds. /// + /// The deployment identifier to tag the span with. public static Activity? StartDeployApplySpan(string deploymentId) { var activity = ActivitySource.StartActivity("otopcua.deploy.apply", ActivityKind.Internal); diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredAddressSpaceSink.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredAddressSpaceSink.cs index 09ff634e..3bb7e934 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredAddressSpaceSink.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredAddressSpaceSink.cs @@ -18,20 +18,41 @@ public sealed class DeferredAddressSpaceSink : IOpcUaAddressSpaceSink /// Swap in the production sink. Pass null to revert to the null sink /// (used during graceful shutdown so post-stop writes don't hit a half-disposed manager). + /// The sink implementation to use, or null to use the null sink. public void SetSink(IOpcUaAddressSpaceSink? sink) => _inner = sink ?? NullOpcUaAddressSpaceSink.Instance; + /// Writes a value to the OPC UA address space through the inner sink. + /// The node ID of the variable. + /// The value to write. + /// The OPC UA quality value. + /// The source timestamp in UTC. public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc) => _inner.WriteValue(nodeId, value, quality, sourceTimestampUtc); + /// Writes an alarm state through the inner sink. + /// The node ID of the alarm condition. + /// Whether the alarm is active. + /// Whether the alarm has been acknowledged. + /// The source timestamp in UTC. public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc) => _inner.WriteAlarmState(alarmNodeId, active, acknowledged, sourceTimestampUtc); + /// Ensures a folder exists in the address space through the inner sink. + /// The node ID of the folder. + /// The node ID of the parent folder, or null for root. + /// The display name of the folder. public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName) => _inner.EnsureFolder(folderNodeId, parentNodeId, displayName); + /// Ensures a variable exists in the address space through the inner sink. + /// The node ID of the variable. + /// The node ID of the parent folder, or null for root. + /// The display name of the variable. + /// The OPC UA data type of the variable. public void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType) => _inner.EnsureVariable(variableNodeId, parentFolderNodeId, displayName, dataType); + /// Rebuilds the address space through the inner sink. public void RebuildAddressSpace() => _inner.RebuildAddressSpace(); } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredServiceLevelPublisher.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredServiceLevelPublisher.cs index 092845cc..eb227979 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredServiceLevelPublisher.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredServiceLevelPublisher.cs @@ -12,8 +12,11 @@ public sealed class DeferredServiceLevelPublisher : IServiceLevelPublisher private volatile IServiceLevelPublisher _inner = NullServiceLevelPublisher.Instance; /// Swap the underlying publisher. Pass null to revert to the Null no-op. + /// The publisher implementation to use, or null to use the null publisher. public void SetInner(IServiceLevelPublisher? inner) => _inner = inner ?? NullServiceLevelPublisher.Instance; + /// Publishes a service level value to the inner publisher. + /// The service level to publish. public void Publish(byte serviceLevel) => _inner.Publish(serviceLevel); } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IOpcUaAddressSpaceSink.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IOpcUaAddressSpaceSink.cs index a4690e17..eb7b7c3a 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IOpcUaAddressSpaceSink.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IOpcUaAddressSpaceSink.cs @@ -9,9 +9,17 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa; public interface IOpcUaAddressSpaceSink { /// Write a Variable node's current value + quality + source timestamp. + /// The OPC UA node ID of the variable. + /// The value to write. + /// The quality status of the value. + /// The source timestamp in UTC. void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc); /// Write an alarm-condition Variable's active/acknowledged state. + /// The OPC UA node ID of the alarm. + /// Whether the alarm is active. + /// Whether the alarm has been acknowledged. + /// The source timestamp in UTC. void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc); /// @@ -20,6 +28,9 @@ public interface IOpcUaAddressSpaceSink /// is null the folder is parented under the namespace /// root. Idempotent: calling twice with the same id is safe. /// + /// The OPC UA node ID for the folder. + /// The parent folder node ID, or null for namespace root. + /// The display name for the folder. void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName); /// @@ -29,6 +40,9 @@ public interface IOpcUaAddressSpaceSink /// Used by Phase7Applier to materialise Galaxy / SystemPlatform tags ahead of any /// driver-side subscribe so OPC UA clients can browse them. Idempotent. /// + /// The OPC UA node ID for the variable. + /// The parent folder node ID, or null for namespace root. + /// The display name for the variable. /// OPC UA built-in type name ("Boolean" / "Int32" / "Float" / etc.). void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType); @@ -49,9 +63,19 @@ public sealed class NullOpcUaAddressSpaceSink : IOpcUaAddressSpaceSink { public static readonly NullOpcUaAddressSpaceSink Instance = new(); private NullOpcUaAddressSpaceSink() { } + + /// public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc) { } + + /// public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc) { } + + /// public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName) { } + + /// public void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType) { } + + /// public void RebuildAddressSpace() { } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IServiceLevelPublisher.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IServiceLevelPublisher.cs index 67f66e03..c464670a 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IServiceLevelPublisher.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IServiceLevelPublisher.cs @@ -8,6 +8,8 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa; /// public interface IServiceLevelPublisher { + /// Publishes the service level value to the OPC UA Server object. + /// The service level value (0-255). void Publish(byte serviceLevel); } @@ -17,6 +19,11 @@ public sealed class NullServiceLevelPublisher : IServiceLevelPublisher { public static readonly NullServiceLevelPublisher Instance = new(); private NullServiceLevelPublisher() { } + + /// Gets the last published service level value. public byte LastPublished { get; private set; } + + /// Records the service level value without publishing. + /// The service level value (0-255). public void Publish(byte serviceLevel) => LastPublished = serviceLevel; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/CorrelationId.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/CorrelationId.cs index da7894e1..fbf9dc06 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/CorrelationId.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/CorrelationId.cs @@ -2,9 +2,16 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Types; public readonly record struct CorrelationId(Guid Value) { + /// Creates a new CorrelationId with a randomly generated GUID. public static CorrelationId NewId() => new(Guid.NewGuid()); + /// public override string ToString() => Value.ToString("N"); + /// Parses a lowercase hex string without hyphens into a CorrelationId. + /// The string to parse. public static CorrelationId Parse(string s) => new(Guid.ParseExact(s, "N")); + /// Attempts to parse a lowercase hex string without hyphens into a CorrelationId. + /// The string to parse, or null. + /// The resulting CorrelationId if parsing succeeds. public static bool TryParse(string? s, out CorrelationId id) { if (Guid.TryParseExact(s, "N", out var g)) { id = new CorrelationId(g); return true; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/DeploymentId.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/DeploymentId.cs index 8d74194b..657f4e18 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/DeploymentId.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/DeploymentId.cs @@ -2,9 +2,22 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Types; public readonly record struct DeploymentId(Guid Value) { + /// Creates a new deployment ID with a random GUID. + /// A new DeploymentId. public static DeploymentId NewId() => new(Guid.NewGuid()); + + /// public override string ToString() => Value.ToString("N"); + + /// Parses a deployment ID from a hex string without hyphens. + /// The hex string to parse. + /// The parsed DeploymentId. public static DeploymentId Parse(string s) => new(Guid.ParseExact(s, "N")); + + /// Attempts to parse a deployment ID from a hex string without hyphens. + /// The hex string to parse, or null. + /// The parsed DeploymentId if successful, or default. + /// True if parsing succeeded; false otherwise. public static bool TryParse(string? s, out DeploymentId id) { if (Guid.TryParseExact(s, "N", out var g)) { id = new DeploymentId(g); return true; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/ExecutionId.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/ExecutionId.cs index 7920a66d..d8b6bfff 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/ExecutionId.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/ExecutionId.cs @@ -2,9 +2,22 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Types; public readonly record struct ExecutionId(Guid Value) { + /// Creates a new execution ID with a randomly generated GUID. + /// A new ExecutionId instance. public static ExecutionId NewId() => new(Guid.NewGuid()); + + /// public override string ToString() => Value.ToString("N"); + + /// Parses the specified string into an ExecutionId in format N. + /// The string to parse. + /// The parsed ExecutionId. public static ExecutionId Parse(string s) => new(Guid.ParseExact(s, "N")); + + /// Tries to parse the specified string into an ExecutionId in format N. + /// The string to parse, or null. + /// The parsed ExecutionId, or default if parsing fails. + /// true if parsing succeeded; otherwise, false. public static bool TryParse(string? s, out ExecutionId id) { if (Guid.TryParseExact(s, "N", out var g)) { id = new ExecutionId(g); return true; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/NodeId.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/NodeId.cs index 273f7a3f..e1251a4c 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/NodeId.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/NodeId.cs @@ -7,11 +7,22 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Types; /// public readonly record struct NodeId(string Value) { + /// public override string ToString() => Value; + + /// Parses a string into a NodeId. + /// The string to parse. + /// A new NodeId instance. + /// Thrown when the string is null, empty, or whitespace. public static NodeId Parse(string s) => string.IsNullOrWhiteSpace(s) ? throw new ArgumentException("NodeId value cannot be empty.", nameof(s)) : new NodeId(s); + + /// Attempts to parse a string into a NodeId. + /// The string to parse. + /// The parsed NodeId if successful. + /// True if the parse succeeded; otherwise false. public static bool TryParse(string? s, out NodeId id) { if (!string.IsNullOrWhiteSpace(s)) { id = new NodeId(s); return true; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RevisionHash.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RevisionHash.cs index 30440eb9..0180becd 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RevisionHash.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RevisionHash.cs @@ -6,11 +6,24 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Types; /// public readonly record struct RevisionHash(string Value) { + /// public override string ToString() => Value; + /// + /// Parses a string into a . + /// + /// The string to parse. + /// A instance. + /// Thrown if the input is null, empty, or whitespace. public static RevisionHash Parse(string s) => string.IsNullOrWhiteSpace(s) ? throw new ArgumentException("RevisionHash value cannot be empty.", nameof(s)) : new RevisionHash(s); + /// + /// Attempts to parse a string into a . + /// + /// The string to parse. + /// The parsed hash, or default if parsing fails. + /// True if parsing succeeded; otherwise false. public static bool TryParse(string? s, out RevisionHash hash) { if (!string.IsNullOrWhiteSpace(s)) { hash = new RevisionHash(s); return true; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/DesignTimeDbContextFactory.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/DesignTimeDbContextFactory.cs index 402a0f0f..183ca972 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/DesignTimeDbContextFactory.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/DesignTimeDbContextFactory.cs @@ -17,6 +17,9 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration; /// public sealed class DesignTimeDbContextFactory : IDesignTimeDbContextFactory { + /// Creates a new DbContext instance for design-time operations. + /// Command-line arguments (unused). + /// The configured DbContext instance. public OtOpcUaConfigDbContext CreateDbContext(string[] args) { var connection = Environment.GetEnvironmentVariable("OTOPCUA_CONFIG_CONNECTION"); diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNode.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNode.cs index 5c95ec95..c7368c93 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNode.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNode.cs @@ -6,13 +6,16 @@ public sealed class ClusterNode /// Stable per-machine logical ID, e.g. "LINE3-OPCUA-A". public required string NodeId { get; set; } + /// The unique identifier of the cluster this node belongs to. public required string ClusterId { get; set; } /// Machine hostname / IP. public required string Host { get; set; } + /// The OPC UA server port (default 4840). public int OpcUaPort { get; set; } = 4840; + /// The dashboard HTTP port (default 8081). public int DashboardPort { get; set; } = 8081; /// @@ -32,15 +35,21 @@ public sealed class ClusterNode /// public string? DriverConfigOverridesJson { get; set; } + /// Gets or sets a value indicating whether this node is enabled. public bool Enabled { get; set; } = true; + /// Gets or sets the timestamp when this node was last seen. public DateTime? LastSeenAt { get; set; } + /// Gets or sets the timestamp when this node was created. public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + /// Gets or sets the username of who created this node. public required string CreatedBy { get; set; } // Navigation + /// Gets or sets the cluster this node belongs to. public ServerCluster? Cluster { get; set; } + /// Gets or sets the credentials associated with this node. public ICollection Credentials { get; set; } = []; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNodeCredential.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNodeCredential.cs index c6824ea7..6a767e9a 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNodeCredential.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNodeCredential.cs @@ -8,22 +8,30 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class ClusterNodeCredential { + /// Gets or sets the credential identifier. public Guid CredentialId { get; set; } + /// Gets or sets the node identifier this credential binds to. public required string NodeId { get; set; } + /// Gets or sets the credential kind (login, certificate, etc.). public required CredentialKind Kind { get; set; } - /// Login name / cert thumbprint / SID / gMSA name. + /// Gets or sets the credential value (login name / cert thumbprint / SID / gMSA name). public required string Value { get; set; } + /// Gets or sets a value indicating whether the credential is enabled. public bool Enabled { get; set; } = true; + /// Gets or sets the date/time when the credential was last rotated. public DateTime? RotatedAt { get; set; } + /// Gets or sets the date/time when the credential was created. public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + /// Gets or sets the user who created the credential. public required string CreatedBy { get; set; } + /// Gets or sets the related cluster node. public ClusterNode? Node { get; set; } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigAuditLog.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigAuditLog.cs index 627d5eeb..386a34ca 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigAuditLog.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigAuditLog.cs @@ -6,21 +6,28 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class ConfigAuditLog { + /// Gets or sets the unique audit log identifier. public long AuditId { get; set; } + /// Gets or sets the timestamp of the audit event. public DateTime Timestamp { get; set; } = DateTime.UtcNow; + /// Gets or sets the principal (user or service) that initiated the event. public required string Principal { get; set; } /// DraftCreated | DraftEdited | Published | RolledBack | NodeApplied | CredentialAdded | CredentialDisabled | ClusterCreated | NodeAdded | ExternalIdReleased | CrossClusterNamespaceAttempt | OpcUaAccessDenied | … public required string EventType { get; set; } + /// Gets or sets the cluster identifier associated with the event, if applicable. public string? ClusterId { get; set; } + /// Gets or sets the node identifier associated with the event, if applicable. public string? NodeId { get; set; } + /// Gets or sets the generation identifier associated with the event, if applicable. public long? GenerationId { get; set; } + /// Gets or sets additional event details in JSON format. public string? DetailsJson { get; set; } /// diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigEdit.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigEdit.cs index 237fcb1c..4a73f338 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigEdit.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigEdit.cs @@ -7,21 +7,27 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class ConfigEdit { + /// Gets the unique identifier for this edit. public Guid EditId { get; init; } = Guid.NewGuid(); + /// Gets the type of entity that was edited. public required string EntityType { get; init; } + /// Gets the identifier of the entity that was edited. public Guid EntityId { get; init; } - /// JSON payload of the column-name → new-value pairs touched by this edit. + /// Gets the JSON payload of the column-name → new-value pairs touched by this edit. public required string FieldsJson { get; init; } - /// Optional correlation across edits inside a single admin operation. + /// Gets the optional correlation identifier across edits inside a single admin operation. public Guid? ExecutionId { get; init; } + /// Gets the username of the user who performed the edit. public required string EditedBy { get; init; } + /// Gets the UTC timestamp when the edit was performed. public DateTime EditedAtUtc { get; init; } = DateTime.UtcNow; + /// Gets the node identifier of the admin instance that performed the edit. public required string SourceNode { get; init; } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Deployment.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Deployment.cs index 8a4afacc..19d83728 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Deployment.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Deployment.cs @@ -10,21 +10,30 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class Deployment { + /// Gets or sets the unique deployment identifier. public Guid DeploymentId { get; init; } = Guid.NewGuid(); + /// Gets or sets the revision hash of the deployment artifact. public required string RevisionHash { get; init; } + /// Gets or sets the deployment status. public DeploymentStatus Status { get; set; } = DeploymentStatus.Dispatching; + /// Gets or sets the name of the user who created the deployment. public required string CreatedBy { get; init; } + /// Gets or sets the UTC timestamp when the deployment was created. public DateTime CreatedAtUtc { get; init; } = DateTime.UtcNow; + /// Gets or sets the serialized artifact blob containing the configuration. public byte[] ArtifactBlob { get; init; } = Array.Empty(); + /// Gets or sets the row version for optimistic concurrency control. public byte[] RowVersion { get; set; } = Array.Empty(); + /// Gets or sets the failure reason if the deployment failed. public string? FailureReason { get; set; } + /// Gets or sets the UTC timestamp when the deployment was sealed. public DateTime? SealedAtUtc { get; set; } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Device.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Device.cs index 736cef38..0fca1d16 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Device.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Device.cs @@ -3,15 +3,27 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// Per-device row for multi-device drivers (Modbus, AB CIP). Optional for single-device drivers. public sealed class Device { + /// + /// Gets or sets the unique database row identifier for the device. + /// public Guid DeviceRowId { get; set; } + /// + /// Gets or sets the device identifier. + /// public required string DeviceId { get; set; } /// Logical FK to . public required string DriverInstanceId { get; set; } + /// + /// Gets or sets the device name. + /// public required string Name { get; set; } + /// + /// Gets or sets a value indicating whether the device is enabled. + /// public bool Enabled { get; set; } = true; /// Schemaless per-driver-type device config (host, port, unit ID, slot, etc.). diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverHostStatus.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverHostStatus.cs index 440d1cee..7b1eb167 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverHostStatus.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverHostStatus.cs @@ -39,6 +39,7 @@ public sealed class DriverHostStatus /// public required string HostName { get; set; } + /// Gets or sets the current connectivity state of the host. public DriverHostState State { get; set; } = DriverHostState.Unknown; /// Timestamp of the last state transition (not of the most recent heartbeat). diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstance.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstance.cs index 39276223..09c40868 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstance.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstance.cs @@ -3,10 +3,13 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// One driver instance in a cluster's generation. JSON config is schemaless per-driver-type. public sealed class DriverInstance { + /// Gets or sets the row ID for this driver instance. public Guid DriverInstanceRowId { get; set; } + /// Gets or sets the unique driver instance identifier. public required string DriverInstanceId { get; set; } + /// Gets or sets the cluster ID this driver instance belongs to. public required string ClusterId { get; set; } /// @@ -15,11 +18,13 @@ public sealed class DriverInstance /// public required string NamespaceId { get; set; } + /// Gets or sets the friendly name of this driver instance. public required string Name { get; set; } /// Galaxy | ModbusTcp | AbCip | AbLegacy | S7 | TwinCat | Focas | OpcUaClient public required string DriverType { get; set; } + /// Gets or sets a value indicating whether this driver instance is enabled. public bool Enabled { get; set; } = true; /// Schemaless per-driver-type JSON config. Validated against registered JSON schema at draft-publish time (decision #91). @@ -46,5 +51,6 @@ public sealed class DriverInstance /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. public byte[] RowVersion { get; set; } = Array.Empty(); + /// Gets or sets the related server cluster for navigation. public ServerCluster? Cluster { get; set; } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstanceResilienceStatus.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstanceResilienceStatus.cs index 445b84b2..b057222a 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstanceResilienceStatus.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstanceResilienceStatus.cs @@ -15,7 +15,9 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class DriverInstanceResilienceStatus { + /// Gets or sets the driver instance identifier. public required string DriverInstanceId { get; set; } + /// Gets or sets the host name. public required string HostName { get; set; } /// Most recent time the circuit breaker for this (instance, host) opened; null if never. diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Equipment.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Equipment.cs index d4cd5e6d..dd1e8c79 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Equipment.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Equipment.cs @@ -7,6 +7,7 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class Equipment { + /// Gets or sets the row identifier for this equipment. public Guid EquipmentRowId { get; set; } /// @@ -43,19 +44,29 @@ public sealed class Equipment // OPC UA Companion Spec OPC 40010 Machinery Identification fields (decision #139). // All nullable so equipment can be added before identity is fully captured. + /// Gets or sets the manufacturer name for this equipment. public string? Manufacturer { get; set; } + /// Gets or sets the model number or designation for this equipment. public string? Model { get; set; } + /// Gets or sets the serial number for this equipment. public string? SerialNumber { get; set; } + /// Gets or sets the hardware revision level for this equipment. public string? HardwareRevision { get; set; } + /// Gets or sets the software revision level for this equipment. public string? SoftwareRevision { get; set; } + /// Gets or sets the year of construction for this equipment. public short? YearOfConstruction { get; set; } + /// Gets or sets the asset location information for this equipment. public string? AssetLocation { get; set; } + /// Gets or sets the manufacturer URI for this equipment. public string? ManufacturerUri { get; set; } + /// Gets or sets the device manual URI for this equipment. public string? DeviceManualUri { get; set; } /// Nullable hook for future schemas-repo template ID (decision #112). public string? EquipmentClassRef { get; set; } + /// Gets or sets whether this equipment is enabled. public bool Enabled { get; set; } = true; /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/EquipmentImportBatch.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/EquipmentImportBatch.cs index c3b65f8c..bd37b7d2 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/EquipmentImportBatch.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/EquipmentImportBatch.cs @@ -17,15 +17,31 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class EquipmentImportBatch { + /// Gets or sets the unique identifier for this batch. public Guid Id { get; set; } + + /// Gets or sets the cluster identifier. public required string ClusterId { get; set; } + + /// Gets or sets the user name who created this batch. public required string CreatedBy { get; set; } + + /// Gets or sets the UTC timestamp when this batch was created. public DateTime CreatedAtUtc { get; set; } + + /// Gets or sets the total number of rows staged in this batch. public int RowsStaged { get; set; } + + /// Gets or sets the number of rows accepted in this batch. public int RowsAccepted { get; set; } + + /// Gets or sets the number of rows rejected in this batch. public int RowsRejected { get; set; } + + /// Gets or sets the UTC timestamp when this batch was finalised, or null if still in staging. public DateTime? FinalisedAtUtc { get; set; } + /// Gets or sets the collection of staged rows in this batch. public ICollection Rows { get; set; } = []; } @@ -37,32 +53,74 @@ public sealed class EquipmentImportBatch /// public sealed class EquipmentImportRow { + /// Gets or sets the unique identifier for this row. public Guid Id { get; set; } + + /// Gets or sets the parent batch identifier. public Guid BatchId { get; set; } + + /// Gets or sets the line number in the source file. public int LineNumberInFile { get; set; } + + /// Gets or sets a value indicating whether this row was accepted. public bool IsAccepted { get; set; } + + /// Gets or sets the reason this row was rejected, if applicable. public string? RejectReason { get; set; } // Required (decision #117) + /// Gets or sets the Z tag identifier. public required string ZTag { get; set; } + + /// Gets or sets the machine code. public required string MachineCode { get; set; } + + /// Gets or sets the SAP identifier. public required string SAPID { get; set; } + + /// Gets or sets the equipment identifier. public required string EquipmentId { get; set; } + + /// Gets or sets the equipment UUID. public required string EquipmentUuid { get; set; } + + /// Gets or sets the equipment name. public required string Name { get; set; } + + /// Gets or sets the UNS area name. public required string UnsAreaName { get; set; } + + /// Gets or sets the UNS line name. public required string UnsLineName { get; set; } // Optional (decision #139 — OPC 40010 Identification) + /// Gets or sets the manufacturer name. public string? Manufacturer { get; set; } + + /// Gets or sets the equipment model. public string? Model { get; set; } + + /// Gets or sets the serial number. public string? SerialNumber { get; set; } + + /// Gets or sets the hardware revision. public string? HardwareRevision { get; set; } + + /// Gets or sets the software revision. public string? SoftwareRevision { get; set; } + + /// Gets or sets the year of construction. public string? YearOfConstruction { get; set; } + + /// Gets or sets the asset location. public string? AssetLocation { get; set; } + + /// Gets or sets the manufacturer URI. public string? ManufacturerUri { get; set; } + + /// Gets or sets the device manual URI. public string? DeviceManualUri { get; set; } + /// Gets or sets the parent batch. public EquipmentImportBatch? Batch { get; set; } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ExternalIdReservation.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ExternalIdReservation.cs index cd4c7897..934e9135 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ExternalIdReservation.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ExternalIdReservation.cs @@ -9,10 +9,13 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class ExternalIdReservation { + /// Gets or sets the unique reservation identifier. public Guid ReservationId { get; set; } + /// Gets or sets the kind of reservation (ZTag or SAPID). public required ReservationKind Kind { get; set; } + /// Gets or sets the reserved external ID value. public required string Value { get; set; } /// The equipment that owns this reservation. Stays bound even when equipment is disabled. @@ -21,16 +24,21 @@ public sealed class ExternalIdReservation /// First cluster to publish this reservation. public required string ClusterId { get; set; } + /// Gets or sets the timestamp when the reservation was first published. public DateTime FirstPublishedAt { get; set; } = DateTime.UtcNow; + /// Gets or sets the identifier of the user or system that first published the reservation. public required string FirstPublishedBy { get; set; } + /// Gets or sets the timestamp of the most recent publication. public DateTime LastPublishedAt { get; set; } = DateTime.UtcNow; /// Non-null when explicitly released by FleetAdmin (audit-logged, requires reason). public DateTime? ReleasedAt { get; set; } + /// Gets or sets the identifier of the user or system that released the reservation. public string? ReleasedBy { get; set; } + /// Gets or sets the reason for releasing the reservation. public string? ReleaseReason { get; set; } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Namespace.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Namespace.cs index c22b7895..55f53433 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Namespace.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Namespace.cs @@ -8,24 +8,30 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class Namespace { + /// Gets or sets the row identifier for this namespace. public Guid NamespaceRowId { get; set; } /// Stable logical ID, e.g. "LINE3-OPCUA-equipment". Globally unique in v2. public required string NamespaceId { get; set; } + /// Gets or sets the cluster identifier. public required string ClusterId { get; set; } + /// Gets or sets the namespace kind. public required NamespaceKind Kind { get; set; } /// E.g. "urn:zb:warsaw-west:equipment". Unique fleet-wide per generation. public required string NamespaceUri { get; set; } + /// Gets or sets a value indicating whether the namespace is enabled. public bool Enabled { get; set; } = true; + /// Gets or sets optional notes about the namespace. public string? Notes { get; set; } /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. public byte[] RowVersion { get; set; } = Array.Empty(); + /// Gets or sets the associated server cluster. public ServerCluster? Cluster { get; set; } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeAcl.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeAcl.cs index a69287be..537dfa4b 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeAcl.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeAcl.cs @@ -8,14 +8,19 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class NodeAcl { + /// Gets or sets the database row ID for this ACL entry. public Guid NodeAclRowId { get; set; } + /// Gets or sets the logical ID of this ACL entry. public required string NodeAclId { get; set; } + /// Gets or sets the cluster ID for this ACL entry. public required string ClusterId { get; set; } + /// Gets or sets the LDAP group for this ACL entry. public required string LdapGroup { get; set; } + /// Gets or sets the scope kind for this ACL entry. public required NodeAclScopeKind ScopeKind { get; set; } /// NULL when = ; otherwise the scoped entity's logical ID. @@ -24,6 +29,7 @@ public sealed class NodeAcl /// Bitmask of . Stored as int in SQL. public required NodePermissions PermissionFlags { get; set; } + /// Gets or sets optional notes for this ACL entry. public string? Notes { get; set; } /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeDeploymentState.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeDeploymentState.cs index 0a53094e..95375733 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeDeploymentState.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeDeploymentState.cs @@ -10,20 +10,29 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class NodeDeploymentState { + /// Gets or sets the cluster node identifier. public required string NodeId { get; init; } + /// Gets or sets the deployment identifier. public Guid DeploymentId { get; init; } + /// Gets or sets the deployment status on this node. public NodeDeploymentStatus Status { get; set; } = NodeDeploymentStatus.Applying; + /// Gets or sets the UTC timestamp when the deployment application started. public DateTime StartedAtUtc { get; set; } = DateTime.UtcNow; + /// Gets or sets the UTC timestamp when the deployment was successfully applied, or null if not yet applied. public DateTime? AppliedAtUtc { get; set; } + /// Gets or sets the failure reason if the deployment failed, or null if successful. public string? FailureReason { get; set; } + /// Gets or sets the row version for optimistic concurrency control. public byte[] RowVersion { get; set; } = Array.Empty(); + /// Gets or sets the cluster node entity reference. public ClusterNode? Node { get; set; } + /// Gets or sets the deployment entity reference. public Deployment? Deployment { get; set; } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/PollGroup.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/PollGroup.cs index 5d6c99b5..4220c3f8 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/PollGroup.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/PollGroup.cs @@ -3,14 +3,19 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// Driver-scoped polling group. Tags reference it via . public sealed class PollGroup { + /// Gets or sets the database row identifier for the polling group. public Guid PollGroupRowId { get; set; } + /// Gets or sets the unique identifier for the polling group. public required string PollGroupId { get; set; } + /// Gets or sets the driver instance that owns this polling group. public required string DriverInstanceId { get; set; } + /// Gets or sets the display name of the polling group. public required string Name { get; set; } + /// Gets or sets the poll interval in milliseconds. public int IntervalMs { get; set; } /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Script.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Script.cs index 056340eb..17fa3ad9 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Script.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Script.cs @@ -16,6 +16,7 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class Script { + /// Gets or sets the script row identifier. public Guid ScriptRowId { get; set; } /// Stable logical id. Globally unique in v2. diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarm.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarm.cs index cb5d1710..b53aab4d 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarm.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarm.cs @@ -16,6 +16,7 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class ScriptedAlarm { + /// Gets or sets the database row identifier for this scripted alarm. public Guid ScriptedAlarmRowId { get; set; } /// Stable logical id — drives AlarmConditionType.ConditionName. Globally unique in v2. @@ -52,6 +53,7 @@ public sealed class ScriptedAlarm /// public bool Retain { get; set; } = true; + /// Gets or sets a value indicating whether this alarm is enabled. public bool Enabled { get; set; } = true; /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarmState.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarmState.cs index d0d78373..c199ac63 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarmState.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarmState.cs @@ -45,13 +45,16 @@ public sealed class ScriptedAlarmState /// Operator-supplied ack comment. Null if no comment or never acked. public string? LastAckComment { get; set; } + /// Gets or sets the UTC timestamp of the last acknowledgment. public DateTime? LastAckUtc { get; set; } /// User who last confirmed. public string? LastConfirmUser { get; set; } + /// Gets or sets the operator-supplied confirm comment. Null if no comment or never confirmed. public string? LastConfirmComment { get; set; } + /// Gets or sets the UTC timestamp of the last confirmation. public DateTime? LastConfirmUtc { get; set; } /// JSON array of operator comments, append-only (GxP audit). diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ServerCluster.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ServerCluster.cs index 159bb79b..c05e5b36 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ServerCluster.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ServerCluster.cs @@ -11,6 +11,7 @@ public sealed class ServerCluster /// Stable logical ID, e.g. "LINE3-OPCUA". public required string ClusterId { get; set; } + /// Gets or sets the display name for the server cluster. public required string Name { get; set; } /// UNS level 1. Canonical org value: "zb" per decision #140. @@ -19,23 +20,33 @@ public sealed class ServerCluster /// UNS level 2, e.g. "warsaw-west". public required string Site { get; set; } + /// Gets or sets the number of nodes in the cluster. public byte NodeCount { get; set; } + /// Gets or sets the redundancy mode for the cluster. public required RedundancyMode RedundancyMode { get; set; } + /// Gets or sets a value indicating whether the cluster is enabled. public bool Enabled { get; set; } = true; + /// Gets or sets optional notes about the cluster. public string? Notes { get; set; } + /// Gets or sets the UTC timestamp when the cluster was created. public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + /// Gets or sets the user who created the cluster. public required string CreatedBy { get; set; } + /// Gets or sets the UTC timestamp when the cluster was last modified. public DateTime? ModifiedAt { get; set; } + /// Gets or sets the user who last modified the cluster. public string? ModifiedBy { get; set; } // Navigation + /// Gets or sets the collection of cluster nodes. public ICollection Nodes { get; set; } = []; + /// Gets or sets the collection of namespaces in the cluster. public ICollection Namespaces { get; set; } = []; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Tag.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Tag.cs index ec2f8225..889e9d7f 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Tag.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Tag.cs @@ -9,12 +9,24 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class Tag { + /// + /// Gets or sets the unique database row identifier for the tag. + /// public Guid TagRowId { get; set; } + /// + /// Gets or sets the tag identifier. + /// public required string TagId { get; set; } + /// + /// Gets or sets the driver instance identifier for this tag. + /// public required string DriverInstanceId { get; set; } + /// + /// Gets or sets the device identifier. + /// public string? DeviceId { get; set; } /// @@ -23,6 +35,9 @@ public sealed class Tag /// public string? EquipmentId { get; set; } + /// + /// Gets or sets the tag name. + /// public required string Name { get; set; } /// Only used when is NULL (SystemPlatform namespace). @@ -31,11 +46,17 @@ public sealed class Tag /// OPC UA built-in type name (Boolean / Int32 / Float / etc.). public required string DataType { get; set; } + /// + /// Gets or sets the access level for this tag. + /// public required TagAccessLevel AccessLevel { get; set; } /// Per decisions #44–45 — opt-in for write retry eligibility. public bool WriteIdempotent { get; set; } + /// + /// Gets or sets the poll group identifier for batching read/write operations. + /// public string? PollGroupId { get; set; } /// Register address / scaling / poll group / byte-order / etc. — schemaless per driver type. diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsArea.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsArea.cs index 36fad95d..889da2d9 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsArea.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsArea.cs @@ -3,19 +3,24 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// UNS level-3 segment. Generation-versioned per decision #115. public sealed class UnsArea { + /// Gets or sets the unique row identifier. public Guid UnsAreaRowId { get; set; } + /// Gets or sets the UNS area identifier. public required string UnsAreaId { get; set; } + /// Gets or sets the cluster identifier. public required string ClusterId { get; set; } /// UNS level 3 segment: matches ^[a-z0-9-]{1,32}$ OR equals literal _default. public required string Name { get; set; } + /// Gets or sets optional notes for the area. public string? Notes { get; set; } /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. public byte[] RowVersion { get; set; } = Array.Empty(); + /// Gets or sets the associated server cluster. public ServerCluster? Cluster { get; set; } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsLine.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsLine.cs index d95e7d16..ee990fbf 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsLine.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsLine.cs @@ -3,8 +3,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// UNS level-4 segment. Generation-versioned per decision #115. public sealed class UnsLine { + /// Gets or sets the unique row identifier for this UNS line. public Guid UnsLineRowId { get; set; } + /// Gets or sets the unique identifier for this UNS line. public required string UnsLineId { get; set; } /// Logical FK to . @@ -13,6 +15,7 @@ public sealed class UnsLine /// UNS level 4 segment: matches ^[a-z0-9-]{1,32}$ OR equals literal _default. public required string Name { get; set; } + /// Gets or sets optional notes describing this UNS line. public string? Notes { get; set; } /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/VirtualTag.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/VirtualTag.cs index bf160cc2..5957dba9 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/VirtualTag.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/VirtualTag.cs @@ -20,9 +20,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// public sealed class VirtualTag { + /// Gets or sets the database row ID (primary key). public Guid VirtualTagRowId { get; set; } - /// Stable logical id. Globally unique in v2. + /// Gets or sets the stable logical identifier, globally unique in v2. public required string VirtualTagId { get; set; } /// Logical FK to — owner of this virtual tag. @@ -43,9 +44,10 @@ public sealed class VirtualTag /// Timer re-evaluation cadence in milliseconds. null = no timer. public int? TimerIntervalMs { get; set; } - /// Per plan decision #10 — checkbox to route this tag's values through IHistoryWriter. + /// Gets or sets a value indicating whether this tag's values should be historized. public bool Historize { get; set; } + /// Gets or sets a value indicating whether this virtual tag is enabled. public bool Enabled { get; set; } = true; /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSealedCache.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSealedCache.cs index 78408c97..a64ddf3a 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSealedCache.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSealedCache.cs @@ -31,6 +31,8 @@ public sealed class GenerationSealedCache /// Root directory for all clusters' sealed caches. public string CacheRoot => _cacheRoot; + /// Initializes a new instance of the GenerationSealedCache class. + /// The root directory for the cache. public GenerationSealedCache(string cacheRoot) { ArgumentException.ThrowIfNullOrWhiteSpace(cacheRoot); @@ -43,6 +45,9 @@ public sealed class GenerationSealedCache /// mark the file read-only, then atomically publish the CURRENT pointer. Existing /// sealed files for prior generations are preserved (prune separately). /// + /// The generation snapshot to seal. + /// The cancellation token. + /// A task representing the asynchronous operation. public async Task SealAsync(GenerationSnapshot snapshot, CancellationToken ct = default) { ArgumentNullException.ThrowIfNull(snapshot); @@ -88,6 +93,9 @@ public sealed class GenerationSealedCache /// (first-boot-no-snapshot case) or when the sealed file is corrupt. Never silently /// falls back to a prior generation. /// + /// The cluster ID to read the snapshot for. + /// The cancellation token. + /// A task representing the asynchronous operation containing the generation snapshot. public Task ReadCurrentAsync(string clusterId, CancellationToken ct = default) { ArgumentException.ThrowIfNullOrWhiteSpace(clusterId); @@ -135,6 +143,8 @@ public sealed class GenerationSealedCache } /// Return the generation id the CURRENT pointer points at, or null if no pointer exists. + /// The cluster ID to get the current generation ID for. + /// The generation ID, or null if no pointer exists. public long? TryGetCurrentGenerationId(string clusterId) { ArgumentException.ThrowIfNullOrWhiteSpace(clusterId); @@ -165,6 +175,11 @@ public sealed class GenerationSealedCache /// Sealed cache is unreachable — caller must fail closed. public sealed class GenerationCacheUnavailableException : Exception { + /// Initializes a new instance of the GenerationCacheUnavailableException class. + /// The error message. public GenerationCacheUnavailableException(string message) : base(message) { } + /// Initializes a new instance of the GenerationCacheUnavailableException class with an inner exception. + /// The error message. + /// The inner exception. public GenerationCacheUnavailableException(string message, Exception inner) : base(message, inner) { } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSnapshot.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSnapshot.cs index 9d67ce4f..b883719d 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSnapshot.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSnapshot.cs @@ -7,9 +7,14 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.LocalCache; /// public sealed class GenerationSnapshot { + /// Gets or sets the auto-generated LiteDB ID. public int Id { get; set; } // LiteDB auto-ID + /// Gets or sets the cluster identifier. public required string ClusterId { get; set; } + /// Gets or sets the generation identifier. public required long GenerationId { get; set; } + /// Gets or sets the time this snapshot was cached. public required DateTime CachedAt { get; set; } + /// Gets or sets the JSON-serialized payload content. public required string PayloadJson { get; set; } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ILocalConfigCache.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ILocalConfigCache.cs index a4cca538..fc92d9ec 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ILocalConfigCache.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ILocalConfigCache.cs @@ -13,7 +13,18 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.LocalCache; /// public interface ILocalConfigCache { + /// Retrieves the most recent generation snapshot for the specified cluster. + /// The cluster identifier. + /// The cancellation token. + /// The most recent generation snapshot, or null if none exists. Task GetMostRecentAsync(string clusterId, CancellationToken ct = default); + /// Stores a generation snapshot in the local cache. + /// The generation snapshot to store. + /// The cancellation token. Task PutAsync(GenerationSnapshot snapshot, CancellationToken ct = default); + /// Removes old generations, keeping only the most recent N. + /// The cluster identifier. + /// The number of latest generations to keep. + /// The cancellation token. Task PruneOldGenerationsAsync(string clusterId, int keepLatest = 10, CancellationToken ct = default); } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/LiteDbConfigCache.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/LiteDbConfigCache.cs index 8c04b2d5..39e5dfb4 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/LiteDbConfigCache.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/LiteDbConfigCache.cs @@ -20,6 +20,8 @@ public sealed class LiteDbConfigCache : ILocalConfigCache, IDisposable // page-level write, not the find-then-insert window. private readonly SemaphoreSlim _writeGate = new(initialCount: 1, maxCount: 1); + /// Initializes a new instance of the class. + /// Path to the LiteDB database file. public LiteDbConfigCache(string dbPath) { // LiteDB can be tolerant of header-only corruption at construction time (it may overwrite @@ -43,6 +45,9 @@ public sealed class LiteDbConfigCache : ILocalConfigCache, IDisposable } } + /// Gets the most recent snapshot for the specified cluster. + /// The cluster ID. + /// Cancellation token. public Task GetMostRecentAsync(string clusterId, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); @@ -53,6 +58,9 @@ public sealed class LiteDbConfigCache : ILocalConfigCache, IDisposable return Task.FromResult(snapshot); } + /// Stores a snapshot in the cache. + /// The snapshot to store. + /// Cancellation token. public async Task PutAsync(GenerationSnapshot snapshot, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); @@ -81,6 +89,10 @@ public sealed class LiteDbConfigCache : ILocalConfigCache, IDisposable } } + /// Removes old generation snapshots, keeping only the latest ones. + /// The cluster ID. + /// Number of latest generations to keep. + /// Cancellation token. public Task PruneOldGenerationsAsync(string clusterId, int keepLatest = 10, CancellationToken ct = default) { ct.ThrowIfCancellationRequested(); @@ -97,6 +109,7 @@ public sealed class LiteDbConfigCache : ILocalConfigCache, IDisposable return Task.CompletedTask; } + /// Releases all resources used by the cache. public void Dispose() { _writeGate.Dispose(); diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ResilientConfigReader.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ResilientConfigReader.cs index d628565d..d6c72bf1 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ResilientConfigReader.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ResilientConfigReader.cs @@ -27,6 +27,12 @@ public sealed class ResilientConfigReader private readonly ResiliencePipeline _pipeline; private readonly ILogger _logger; + /// Initializes a resilient config reader with the given cache and options. + /// The sealed cache for fallback. + /// The stale config flag to manage. + /// The logger instance. + /// The timeout for central fetch (default 2s). + /// The number of retries (default 3). public ResilientConfigReader( GenerationSealedCache cache, StaleConfigFlag staleFlag, @@ -71,6 +77,9 @@ public sealed class ResilientConfigReader @"(?ix)\b(Password|Pwd|User\s*Id|Uid|AccessToken|Authorization|Api[-_]?Key)\s*=\s*[^;,)\s]*", RegexOptions.Compiled); + /// Redacts sensitive credential information from a message. + /// The message to scrub. + /// The message with redacted credentials. internal static string ScrubSecrets(string? message) { if (string.IsNullOrEmpty(message)) return message ?? string.Empty; @@ -80,10 +89,15 @@ public sealed class ResilientConfigReader } /// - /// Execute through the resilience pipeline. On full failure - /// (post-retry), reads the sealed cache for and passes the - /// snapshot to to extract the requested shape. + /// Executes a central fetch through the resilience pipeline. On full failure + /// (post-retry), reads the sealed cache and extracts the requested shape. /// + /// The type of configuration to read. + /// The cluster ID to fetch for. + /// Function to fetch from central DB. + /// Function to extract the config from a snapshot. + /// Cancellation token. + /// The configuration of type T. public async ValueTask ReadAsync( string clusterId, Func> centralFetch, diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs index 06ef21f7..97747fe1 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs @@ -12,39 +12,69 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration; public sealed class OtOpcUaConfigDbContext(DbContextOptions options) : DbContext(options), IDataProtectionKeyContext { + /// Gets the DbSet of server clusters. public DbSet ServerClusters => Set(); + /// Gets the DbSet of cluster nodes. public DbSet ClusterNodes => Set(); + /// Gets the DbSet of cluster node credentials. public DbSet ClusterNodeCredentials => Set(); + /// Gets the DbSet of namespaces. public DbSet Namespaces => Set(); + /// Gets the DbSet of UNS areas. public DbSet UnsAreas => Set(); + /// Gets the DbSet of UNS lines. public DbSet UnsLines => Set(); + /// Gets the DbSet of driver instances. public DbSet DriverInstances => Set(); + /// Gets the DbSet of devices. public DbSet Devices => Set(); + /// Gets the DbSet of equipment. public DbSet Equipment => Set(); + /// Gets the DbSet of tags. public DbSet Tags => Set(); + /// Gets the DbSet of poll groups. public DbSet PollGroups => Set(); + /// Gets the DbSet of node ACLs. public DbSet NodeAcls => Set(); + /// Gets the DbSet of configuration audit logs. public DbSet ConfigAuditLogs => Set(); + /// Gets the DbSet of external ID reservations. public DbSet ExternalIdReservations => Set(); + /// Gets the DbSet of driver host statuses. public DbSet DriverHostStatuses => Set(); + /// Gets the DbSet of driver instance resilience statuses. public DbSet DriverInstanceResilienceStatuses => Set(); + /// Gets the DbSet of LDAP group role mappings. public DbSet LdapGroupRoleMappings => Set(); + /// Gets the DbSet of equipment import batches. public DbSet EquipmentImportBatches => Set(); + /// Gets the DbSet of equipment import rows. public DbSet EquipmentImportRows => Set(); + /// Gets the DbSet of scripts. public DbSet