Files
Marc Schier 15d0ce7bd5 Implement OPC UA Part 10 Programs (#4789)
# Description

Implement OPC UA Part 10 Programs across `Opc.Ua.Core`/`Core.Types`,
`Opc.Ua.Server`, and `Opc.Ua.Client`, reusing the existing
state-machine, source-generation, node-management, auditing, and
streaming-subscription infrastructure.

- Add asynchronous provider-backed execution, standard controls,
internal/autonomous transitions, generation checks, and nested-state
activation/resumption.
- Add checked creation/adoption, vendor Create adapters, deletion,
recycling and instance limits, auto-delete, DI, and direct-construction
paths.
- Maintain ProgramDiagnostic2 and retained final results; publish
captured intermediate results and concrete transition/audit events with
access controls.
- Add generated SDK models/proxies, typed client discovery and reads,
event streams, and subscribe-before-call readiness handling.
- Add unit, connected client/server, generated Annex A-style model, and
NativeAOT coverage. Document usage and migration in `docs/Programs.md`
and related guides.

### Compatibility and design decisions

The linked Part 10 document is v1.05.00; namespace-zero definitions
remain aligned with 1.05.07. Documentation distinguishes normative
requirements from conflicting specification text and SDK conventions.

- Correct state numbers to Halted=11, Ready=12, Running=13,
Suspended=14. Generated subtypes retain inherited namespace-zero
state/transition identifiers.
- Managed Reset is Halted-to-Ready only. Preserve the existing low-level
Reset-from-Suspended behavior for compatibility.
- Preserve UInt32 limit types; use `UInt32.MaxValue` as a documented SDK
unlimited convention. RecycleCount overflow reports BadOutOfRange
without stopping unlimited execution.
- In-memory default with injectable providers. Durable recovery,
distributed execution/failover, and a production Annex A download engine
are excluded.

## Checklist

_Put an `x` in the boxes that apply. You can complete these step by step
after opening the PR._

- [ ] I have signed the
[CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf)
and read the
[CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md)
doc.
- [ ] I have added tests that prove my fix is effective or that my
feature works and increased code coverage.
- [x] I have added all necessary documentation.
- [x] I have verified that my changes do not introduce (new) build or
analyzer warnings.
- [ ] I ran **all** tests locally using the **UA.slnx** solution against
at least .net **framework** and .net **10**, and all passed.
- [ ] I fixed **all** failing and flaky tests in the CI pipelines and
**all** CodeQL warnings.
- [ ] I have addressed **all** PR feedback received.

Tests and focused coverage evidence are above; the combined
tests/coverage checkbox remains open because a whole-repository coverage
increase has not been established. CLA status, CI/CodeQL results,
tracking-issue approval, and PR feedback are not asserted.
2026-10-15 09:19:25 +02:00

133 lines
7.4 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2005-2026 The OPC Foundation, Inc. OPC Foundation MIT License 1.00. -->
<opc:ModelDesign xmlns:opc="http://opcfoundation.org/UA/ModelDesign.xsd"
xmlns:ua="http://opcfoundation.org/UA/"
xmlns:programs="http://opcfoundation.org/UA/SDK/Programs/"
xmlns="urn:opcfoundation:tests:programs"
TargetNamespace="urn:opcfoundation:tests:programs"
TargetXmlNamespace="urn:opcfoundation:tests:programs:types"
TargetVersion="1.0.0" TargetPublicationDate="2026-10-14T00:00:00Z">
<opc:Namespaces>
<opc:Namespace Name="DomainDownloadModel" Prefix="Opc.Ua.TestModels.DomainDownload"
XmlNamespace="urn:opcfoundation:tests:programs:types" XmlPrefix="Download">urn:opcfoundation:tests:programs</opc:Namespace>
<opc:Namespace Name="OpcUaPrograms" Prefix="Opc.Ua.Programs"
XmlNamespace="http://opcfoundation.org/UA/SDK/Programs/Types.xsd"
XmlPrefix="Programs">http://opcfoundation.org/UA/SDK/Programs/</opc:Namespace>
<opc:Namespace Name="OpcUa" Prefix="Opc.Ua"
XmlNamespace="http://opcfoundation.org/UA/2008/02/Types.xsd"
XmlPrefix="OpcUa">http://opcfoundation.org/UA/</opc:Namespace>
</opc:Namespaces>
<opc:ObjectType SymbolicName="DomainDownloadType" BaseType="programs:ManagedProgramType">
<opc:Children>
<opc:Method SymbolicName="ua:Start" ModellingRule="Mandatory">
<opc:InputArguments>
<opc:Argument Name="DomainName" DataType="ua:String" />
<opc:Argument Name="DomainSource" DataType="ua:String" />
<opc:Argument Name="DomainDestination" DataType="ua:String" />
</opc:InputArguments>
</opc:Method>
<opc:Method SymbolicName="ua:Suspend" ModellingRule="Mandatory" />
<opc:Method SymbolicName="ua:Resume" ModellingRule="Mandatory" />
<opc:Method SymbolicName="ua:Halt" ModellingRule="Mandatory" />
<opc:Variable SymbolicName="ua:ProgramDiagnostic" TypeDefinition="ua:ProgramDiagnostic2Type"
ModellingRule="Mandatory" />
<opc:Object SymbolicName="TransferStateMachine" TypeDefinition="TransferStateMachineType"
ModellingRule="Mandatory" />
<opc:Object SymbolicName="ua:Running" TypeDefinition="ua:StateType" ModellingRule="None">
<opc:References>
<opc:Reference>
<opc:ReferenceType>ua:HasSubStateMachine</opc:ReferenceType>
<opc:TargetId>DomainDownloadType_TransferStateMachine</opc:TargetId>
</opc:Reference>
</opc:References>
</opc:Object>
<opc:Object SymbolicName="ua:FinalResultData" TypeDefinition="ua:BaseObjectType"
ModellingRule="Mandatory">
<opc:Children>
<opc:Variable SymbolicName="BytesTransferred" DataType="ua:UInt32" ModellingRule="Mandatory" />
<opc:Variable SymbolicName="Completed" DataType="ua:Boolean" ModellingRule="Mandatory" />
<opc:Variable SymbolicName="ErrorCode" DataType="ua:StatusCode" ModellingRule="Mandatory" />
</opc:Children>
</opc:Object>
</opc:Children>
</opc:ObjectType>
<opc:ObjectType SymbolicName="NamedProgramType" BaseType="programs:ManagedProgramType">
<opc:Children>
<opc:Method SymbolicName="Create" ModellingRule="None">
<opc:InputArguments>
<opc:Argument Name="Name" DataType="ua:String" />
</opc:InputArguments>
<opc:OutputArguments>
<opc:Argument Name="InvocationId" DataType="ua:NodeId" />
<opc:Argument Name="Label" DataType="ua:String" />
</opc:OutputArguments>
</opc:Method>
</opc:Children>
</opc:ObjectType>
<opc:ObjectType SymbolicName="TransferStateMachineType" BaseType="ua:FiniteStateMachineType">
<opc:Children>
<opc:Variable SymbolicName="ua:LastTransition" TypeDefinition="ua:FiniteTransitionVariableType"
ModellingRule="Mandatory">
<opc:Children>
<opc:Property SymbolicName="ua:Number" DataType="ua:UInt32" ModellingRule="Mandatory" />
<opc:Property SymbolicName="ua:TransitionTime" DataType="ua:UtcTime" ModellingRule="Mandatory" />
</opc:Children>
</opc:Variable>
<opc:Object SymbolicName="Opening" TypeDefinition="ua:InitialStateType" ModellingRule="None">
<opc:Children>
<opc:Property SymbolicName="ua:StateNumber" DataType="ua:UInt32">
<opc:DefaultValue><UInt32 xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">1</UInt32></opc:DefaultValue>
</opc:Property>
</opc:Children>
</opc:Object>
<opc:Object SymbolicName="Sending" TypeDefinition="ua:StateType" ModellingRule="None">
<opc:Children>
<opc:Property SymbolicName="ua:StateNumber" DataType="ua:UInt32">
<opc:DefaultValue><UInt32 xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">2</UInt32></opc:DefaultValue>
</opc:Property>
</opc:Children>
</opc:Object>
<opc:Object SymbolicName="Closing" TypeDefinition="ua:StateType" ModellingRule="None">
<opc:Children>
<opc:Property SymbolicName="ua:StateNumber" DataType="ua:UInt32">
<opc:DefaultValue><UInt32 xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">3</UInt32></opc:DefaultValue>
</opc:Property>
</opc:Children>
</opc:Object>
<opc:Object SymbolicName="OpeningToSending" TypeDefinition="ua:TransitionType" ModellingRule="None">
<opc:Children>
<opc:Property SymbolicName="ua:TransitionNumber" DataType="ua:UInt32">
<opc:DefaultValue><UInt32 xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">10</UInt32></opc:DefaultValue>
</opc:Property>
</opc:Children>
<opc:References>
<opc:Reference><opc:ReferenceType>ua:FromState</opc:ReferenceType><opc:TargetId>TransferStateMachineType_Opening</opc:TargetId></opc:Reference>
<opc:Reference><opc:ReferenceType>ua:ToState</opc:ReferenceType><opc:TargetId>TransferStateMachineType_Sending</opc:TargetId></opc:Reference>
</opc:References>
</opc:Object>
<opc:Object SymbolicName="SendingToSending" TypeDefinition="ua:TransitionType" ModellingRule="None">
<opc:Children>
<opc:Property SymbolicName="ua:TransitionNumber" DataType="ua:UInt32">
<opc:DefaultValue><UInt32 xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">11</UInt32></opc:DefaultValue>
</opc:Property>
</opc:Children>
<opc:References>
<opc:Reference><opc:ReferenceType>ua:FromState</opc:ReferenceType><opc:TargetId>TransferStateMachineType_Sending</opc:TargetId></opc:Reference>
<opc:Reference><opc:ReferenceType>ua:ToState</opc:ReferenceType><opc:TargetId>TransferStateMachineType_Sending</opc:TargetId></opc:Reference>
</opc:References>
</opc:Object>
<opc:Object SymbolicName="SendingToClosing" TypeDefinition="ua:TransitionType" ModellingRule="None">
<opc:Children>
<opc:Property SymbolicName="ua:TransitionNumber" DataType="ua:UInt32">
<opc:DefaultValue><UInt32 xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">12</UInt32></opc:DefaultValue>
</opc:Property>
</opc:Children>
<opc:References>
<opc:Reference><opc:ReferenceType>ua:FromState</opc:ReferenceType><opc:TargetId>TransferStateMachineType_Sending</opc:TargetId></opc:Reference>
<opc:Reference><opc:ReferenceType>ua:ToState</opc:ReferenceType><opc:TargetId>TransferStateMachineType_Closing</opc:TargetId></opc:Reference>
</opc:References>
</opc:Object>
</opc:Children>
</opc:ObjectType>
</opc:ModelDesign>